42

In doing an auto-refresh using the following code, I assumed that when I do a post, the model will automatically sent to the controller:

$.ajax({
    url: '<%=Url.Action("ModelPage")%>',
    type: "POST",
    //data:  ??????
    success: function(result) {
        $("div#updatePane").html(result);
    },

    complete: function() {
    $('form').onsubmit({ preventDefault: function() { } });

    }
});

Every time there is a post, I need to increment the value attribute in the model:

public ActionResult Modelpage(MyModel model)
    {                   
        model.value = model.value + 1;

        return PartialView("ModelPartialView", this.ViewData);
    }

But the model is not passed to the controller when the page is posted with jQuery AJAX request. How can I send the model in the AJAX request?

tereško
  • 58,060
  • 25
  • 98
  • 150
ravikiran
  • 1,327
  • 5
  • 14
  • 18

7 Answers7

49

The simple answer (in MVC 3 onwards, maybe even 2) is you don't have to do anything special.

As long as your JSON parameters match the model, MVC is smart enough to construct a new object from the parameters you give it. The parameters that aren't there are just defaulted.

For example, the Javascript:

var values = 
{
    "Name": "Chris",
    "Color": "Green"
}

$.post("@Url.Action("Update")",values,function(data)
{
    // do stuff;
});

The model:

public class UserModel
{
     public string Name { get;set; }
     public string Color { get;set; }
     public IEnumerable<string> Contacts { get;set; }
}

The controller:

public ActionResult Update(UserModel model)
{
     // do something with the model

     return Json(new { success = true });
}
Chris S
  • 64,770
  • 52
  • 221
  • 239
  • will this work with scenario, where model contains custom objects for partial views? like inside values array there is property `"Customer" :{ "Name":"N" , ...}"` – Javidan Nov 16 '15 at 08:59
  • How would you reference Contacts, such as Contact.Name, Contact.Phone, etc within the ajax success? – JoshYates1980 May 23 '17 at 18:30
25

If you need to send the FULL model to the controller, you first need the model to be available to your javascript code.

In our app, we do this with an extension method:

public static class JsonExtensions
{
    public static string ToJson(this Object obj)
    {
        return new JavaScriptSerializer().Serialize(obj);
    }
}

On the view, we use it to render the model:

<script type="javascript">
  var model = <%= Model.ToJson() %>
</script>

You can then pass the model variable into your $.ajax call.

Laviak
  • 406
  • 1
  • 5
  • 8
  • 2
    This is nice, but is quite useless, if you change the model on the page the model is rendered and if you modify it on the page (i think is normal on a web page) you pass an empty model to the post action. – theLaw Jun 19 '14 at 07:00
  • 1
    @Laviak This method seems to be good, but returns empty model in this scenario: I submit the form with filled model and in case there is an error the form returns from controller. In this case the model is not empty, but when using this method an empty model sent to the controller. How to fix it? – Jack Jun 17 '15 at 10:26
  • @theLaw Any idea to fix this problem? – Jack Jun 17 '15 at 10:26
4

I have an MVC page that submits JSON of selected values from a group of radio buttons.

I use:

var dataArray = $.makeArray($("input[type=radio]").serializeArray());

To make an array of their names and values. Then I convert it to JSON with:

var json = $.toJSON(dataArray)

and then post it with jQuery's ajax() to the MVC controller

$.ajax({
url: "/Rounding.aspx/Round/" + $("#OfferId").val(),
type: 'POST',
dataType: 'html',
data: json, 
contentType: 'application/json; charset=utf-8',
beforeSend: doSubmitBeforeSend,
complete: doSubmitComplete,
success: doSubmitSuccess});

Which sends the data across as native JSON data.

You can then capture the response stream and de-serialize it into the native C#/VB.net object and manipulate it in your controller.

To automate this process in a lovely, low maintenance way, I advise reading this entry that spells out most of native, automatic JSON de-serialization quite well.

Match your JSON object to match your model and the linked process below should automatically deserialize the data into your controller. It's works wonderfully for me.

Article on MVC JSON deserialization

dano
  • 5,640
  • 5
  • 27
  • 27
3

This can be done by building a javascript object to match your mvc model. The names of the javascript properties have to match exactly to the mvc model or else the autobind won't happen on the post. Once you have your model on the server side you can then manipulate it and store the data to the database.

I am achieving this either by a double click event on a grid row or click event on a button of some sort.

@model TestProject.Models.TestModel

<script>

function testButton_Click(){
  var javaModel ={
  ModelId: '@Model.TestId',
  CreatedDate: '@Model.CreatedDate.ToShortDateString()',
  TestDescription: '@Model.TestDescription',
  //Here I am using a Kendo editor and I want to bind the text value to my javascript
  //object. This may be different for you depending on what controls you use.
  TestStatus: ($('#StatusTextBox'))[0].value, 
  TestType: '@Model.TestType'
  }

  //Now I did for some reason have some trouble passing the ENUM id of a Kendo ComboBox 
    //selected value. This puzzled me due to the conversion to Json object in the Ajax call. 
  //By parsing the Type to an int this worked.

  javaModel.TestType = parseInt(javaModel.TestType);

  $.ajax({
      //This is where you want to post to.
      url:'@Url.Action("TestModelUpdate","TestController")', 
      async:true,
      type:"POST",
      contentType: 'application/json',
      dataType:"json",
      data: JSON.stringify(javaModel)
  });
}
</script>


//This is your controller action on the server, and it will autobind your values 
//to the newTestModel on post.

[HttpPost]
public ActionResult TestModelUpdate(TestModel newTestModel)
{
 TestModel.UpdateTestModel(newTestModel);
 return //do some return action;
}
B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862
logan gilley
  • 191
  • 2
  • 5
2

I think you need to explicitly pass the data attribute. One way to do this is to use the data = $('#your-form-id').serialize();

This post may be helpful. Post with jquery and ajax

Have a look at the doc here.. Ajax serialize

Community
  • 1
  • 1
rajesh pillai
  • 8,102
  • 7
  • 43
  • 60
  • i want to pass the model not just the form data – ravikiran Oct 05 '09 at 08:46
  • 2
    When you use form.serialize() on an action which accepts a appropriate model, the mapping is automatically done. So, in your case when you make this request the "MyModel" instance will be populated with the form values. – rajesh pillai Oct 05 '09 at 12:33
1

you can create a variable and send to ajax.

var m = { "Value": @Model.Value }

$.ajax({
    url: '<%=Url.Action("ModelPage")%>',
    type: "POST",
    data:  m,
    success: function(result) {
        $("div#updatePane").html(result);
    },

    complete: function() {
    $('form').onsubmit({ preventDefault: function() { } });

    }
});

All of model's field must bo ceated in m.

Majid Hosseini
  • 1,098
  • 10
  • 17
0

In ajax call mention-

data:MakeModel(),

use the below function to bind data to model

function MakeModel() {

    var MyModel = {};

    MyModel.value = $('#input element id').val() or your value;

    return JSON.stringify(MyModel);
}

Attach [HttpPost] attribute to your controller action

on POST this data will get available

Harry
  • 87,580
  • 25
  • 202
  • 214