I am not sure whether I've framed the question properly above in subject but I will try to explain to my best about the question I have.
I have below ContactUsModel
which is a part of HomeViewModel
, better say Nested Model Class in a single model
public class ContactUsDataModel
{
public string ContactName { get; set; }
public string ContactEmail { get; set; }
public string ContactMessage { get; set; }
public string ContactPhone { get; set; }
}
and I am getting this Model
referred in HomeViewModel
as below:
public class HomeViewModel
{
/*My other models goes here*/
public ContactUsDataModel CUDModel { get; set; }
}
Now in Index.cshtml
view I strongly create a form view as below:
@model ProjectName.Models.HomeViewModel
<!--I have other views for other models-->
@using (Html.BeginForm("ContactPost", "Home", FormMethod.Post, new { id = "contactform" }))
{
@Html.TextBoxFor(m => m.CUDModel.ContactName, new { @class="contact col-md-6 col-xs-12", placeholder="Your Name *" })
@Html.TextBoxFor(m => m.CUDModel.ContactEmail, new { @class = "contact noMarr col-md-6 col-xs-12", placeholder = "E-mail address *" })
@Html.TextBoxFor(m => m.CUDModel.ContactPhone, new { @class = "contact col-md-12 col-xs-12", placeholder = "Contact Number (optional)" })
@Html.TextAreaFor(m=>m.CUDModel.ContactMessage, new { @class = "contact col-md-12 col-xs-12", placeholder = "Message *" })
<input type="submit" id="submit" class="contact submit" value="Send message">
}
I do ajax
Post as below:
$('#contactform').on('submit', function (e) {
e.preventDefault();
var formdata = new FormData($('.contact form').get(0));
$.ajax({
url: $("#contactform").attr('action'),
type: 'POST',
data: formdata,
processData: false,
contentType: false,
//success
success: function (result) {
//Code here
},
error: function (xhr,responseText,status) {
//Code here
}
});
});
and in Controller I tried to receive it as below:
public JsonResult ContactPost(ContactUsDataModel model)
{
var name=model.ContactName; //null
/*Fetch the data and save it and return Json*/
//model is always null
}
For some reason the above model is always null
. But this works if I refer the model
as HomeViewModel model
instead of ContactUsDataModel model
in controller parameter like below:
public JsonResult ContactPost(HomeViewModel model)
{
var name=model.CUDModel.ContactName; //gets value
/*Fetch the data and save it and return Json*/
//Model is filled.
}
My question here is even though I fill
model
of typeContactUsDataModel
in the view I am getting it asnull
if I refer directly, butContactUsModel
which is insideHomeViewModel
gets filled. Doesn't type of model matter here. Is the hierarchy its referred is necessary while fetching in controller?
Then, the Controller interacts with the Model to send and receive data. The Controller then interacts with the View to render the data. The View is only concerned about how to present the information and not the final presentation.
Typically, the user interacts with the View, which in turn generates the appropriate request, this request will be handled by a controller. The controller renders the appropriate view with the model data as a response. So, to sum it up: Model is data part. View is User Interface part. Controller is request-response handler.
The controller is the bossy manager. It stands between the model and the view, coordinating the entire show. Whenever the controller receives a request from the user (either directly or via the view), it puts the model to work. And when the model delivers the data requested in the right format, the controller forwards it to the view.
The model's job is to simply manage the data. Whether the data is from a database, API, or a JSON object, the model is responsible for managing it. In the Car Clicker application, the model object contains an array of car objects with all the information (data) needed for the app.
Well, if your generated <input>
name is CUDModel.ContactName
instead of simply ContactName
, the default Model-Binder wouldn't be able to bind it.
Fortunately, you can use the [Bind]
attribute with prefix:
public JsonResult ContactPost([Bind(Prefix="CUDModel")]ContactUsDataModel model)
{
// ...
}
See MSDN
Your view posts the Type you have referenced in the view - @model ProjectName.Models.HomeViewModel
- CUDModel
is simply a property of HomeViewModel.
Using your web browser, inspect each DOM input element "name" property. MVC automatically maps properties from your inputs to the class using the input's "name" property.
To solve this you can create a custom model binder or create the inputs by hand, specifying the name property in such a way that the automatic model binder can match them to properties of your class.
However, there isn't anything wrong with your controller action taking HomeViewModel
as an argument.
More information, found here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With