0

I'm calling an MVC controller method and passing it an Entity object. Among other properties, Entity also has a Contacts property. With this approach, the controller gets the entity, and the right number of contacts within the entities, but all of the contacts' properties are null.

This is the original approach:

$.post('/Home/Save', $.param(entity), SaveComplete);

With the strongly-typed controller:

public ActionResult Save(Entity entity)

This causes each Entity.Contact to have null properties:

enter image description here

And Fiddler shows that the contacts are passed to the server.

To get the controller to recognize the Contacts property of Entity, I have to do this:

JavaScript:

$.post('/Home/Save', { entityAsJson: JSON.stringify(entity) }, SaveComplete);

Controller method:

public ActionResult Save(string entityAsJson)
{
    try
    {        
        Entity entity = JsonConvert.DeserializeObject<Entity>(entityAsJson);
        // more code here
    }
}

That's unfortunate, because now my controller takes a string instead of a strongly-typed entity. Is there a way to get the first option to work, or do I need to stringify the JSON?

Bob Horn
  • 33,387
  • 34
  • 113
  • 219
  • check [here](http://stackoverflow.com/questions/5980389/proper-way-to-use-ajax-post-in-jquery-to-pass-model-from-strongly-typed-mvc3-vie) . The most upvoted ansver... – AliRıza Adıyahşi Mar 02 '13 at 20:23
  • @AliRızaAdıyahşi Which one of the three options, in that answer, are you suggesting? The original question doesn't show a collection within an object; only primitive properties on the main object. – Bob Horn Mar 02 '13 at 20:29
  • You should not need the `JsonConvert.DeserializeObject`. Try simply doing json-serialization on the client, and leave the server as it was (IE: accepting an "Entity" object). Asp.NET MVC has it's own jsonvalueprovider. If that does not solve the problem, I remember reading sometime that there were some hoops you had to jump through to get MVC(3 I think) to play nice with arrays passed from the client. – Alxandr Mar 02 '13 at 20:29
  • I use `data: $('#form').serialize(),` to post model – AliRıza Adıyahşi Mar 02 '13 at 20:32
  • Aha: Found it: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx. It's a bit dated, but I'm guessing if you conform to the specified format it should work :) – Alxandr Mar 02 '13 at 20:34

2 Answers2

4

In order to use strongly typed parameters in your controller actions and send data with ajax which gets bound correctly (including collection properties) you need to do the following things:

  • use the $.ajax instead of $.post because $.post does not allow to configure the contentType option
  • you need to send JSON. So you need to JSON.stringfy your data
  • set the contentType to "application/json" because this tells ASP.NET MVC to use the correct model binder for JSON

So the following code should work with your original controller action:

$.ajax({ 
    url: '/Home/Save', 
    type: 'POST', 
    data: JSON.stringify(entity), 
    contentType: "application/json",
    success: SaveComplete 
});
Bob Horn
  • 33,387
  • 34
  • 113
  • 219
nemesv
  • 138,284
  • 16
  • 416
  • 359
  • 1
    @DaveA yeah, I know... I have answered this type of question multiple times but so far I was not able to find a good cannonical question/answer pair (not even inside the ones I've answered). So if you know a good one I will be happy to close this as a duplicate. – nemesv Mar 02 '13 at 21:20
  • @nemesv Dave is talking about his answer here: http://stackoverflow.com/a/15170512/279516. I didn't know it then, but his answer would have solved my original problem (that post - parameter's values are null), and my new problem (this post - collection's parameters *within* a parameter are null), although I wouldn't have known why. Your answer has a good explanation with it. – Bob Horn Mar 02 '13 at 22:22
  • I'd say your implementation is better than mine. My jquery is still growing. For example, I like how you are passing a delegate to success method and having the data **implicitly** passed whereas I passed it **explicitly** and thereby less elegantly @nemesv – Dave Alperovich Mar 06 '13 at 03:38
0

In your case i don't know why are u making javascript post. If it's strongly type binding then just do the following:

(1) Wrap your controls, submit button under using block (Form).
(2) Call your action which should have your class name as an parameter.

e.g:


    Public Action Result (YourClassName model)
    {
          Your sample Code
    }

in model you will get whatever u have filled on your view...

Sham
  • 691
  • 2
  • 13
  • 26