Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does model maintains its structure when data is received in controller?

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 type ContactUsDataModel in the view I am getting it as null if I refer directly, but ContactUsModel which is inside HomeViewModel gets filled. Doesn't type of model matter here. Is the hierarchy its referred is necessary while fetching in controller?

like image 634
Guruprasad J Rao Avatar asked Oct 18 '15 18:10

Guruprasad J Rao


People also ask

How does the controller interact with the model and view?

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.

What is the difference between a model and a controller?

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.

What is the role of the controller?

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.

What does the model do?

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.


3 Answers

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

like image 185
haim770 Avatar answered Nov 07 '22 04:11

haim770


Your view posts the Type you have referenced in the view - @model ProjectName.Models.HomeViewModel - CUDModel is simply a property of HomeViewModel.

like image 43
viperguynaz Avatar answered Nov 07 '22 04:11

viperguynaz


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.

like image 29
BenM Avatar answered Nov 07 '22 05:11

BenM