2

I would really appreciate a tip here... I've been looking for a solution for 4 hours now...

I have a function like so:

public virtual JsonResult LoadPreviousProductsJson(SearchResultModel rmodel, SearchCriteriaModel cmodel)

I'm trying to send data to this controller like so:

var jsonData = $('#frmSearchResult').serialize();
var stringToPost = JSON.stringify(jsonData);

var jsonData2 = $('#frmSearchProducts').serialize();
var stringToPost2 = JSON.stringify(jsonData2);


$.post('@Url.Action(MVC.Product.LoadPreviousProductsJson())', { rmodel: stringToPost, cmodel: stringToPost2 })
    .done(function(data) {....

This results that the objects are Null in the controller...

If I only send 1 Json objectI am succesfull:

$.post('@Url.Action(MVC.Product.LoadPreviousProductsJson())', stringToPost)
.done(function(data) {....

but when I try to send them together, it Always fails...


Only somewhat successful thing I can do is sending the 2 objects as string and read them with Newtonsoft, but here I can't convert the strings to the corresponding objects....

model = Newtonsoft.Json.JsonConvert.DeserializeObject<SearchResultModel>(rmodel);
model2 = Newtonsoft.Json.JsonConvert.DeserializeObject<SearchCriteriaModel>(cmodel);

The above code just fails...

Nkosi
  • 235,767
  • 35
  • 427
  • 472
user1841243
  • 1,663
  • 2
  • 19
  • 35

3 Answers3

2

Create a new model to store your payload that is specific to your action

public class SearchViewModel {
    public SearchResultModel rmodel { get; set; }
    public SearchCriteriaModel cmodel  { get; set; }
}

Update action to accept expected payload

public virtual JsonResult LoadPreviousProductsJson(SearchViewModel model) {
    SearchResultModel rmodel = model.rmodel; 
    SearchCriteriaModel cmodel = model.cmodel;

    //... other code
}

create the same mode on client and send one payload.

var jsonData = {};
$('#frmSearchResult').serializeArray()
    .map(function(x){jsonData[x.name] = x.value;});

var jsonData2 = {};
$('#frmSearchProducts').serializeArray()
    .map(function(x){jsonData2[x.name] = x.value;});

var model = { rmodel:jsonData, cmodel:jsonData2 };

var payload = JSON.stringify(model);

$.post('@Url.Action(MVC.Product.LoadPreviousProductsJson())', payload)
    .done(function(data) {....}
Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • SearchCriteriaModel is filled but with default values... and SearchResultModel is null.... when I attempt your code... unfortunately – user1841243 Jul 01 '16 at 11:40
  • @user1841243, The issue is with JQuery `.serialize()`. it produces a url encoded string not json. You will need to construct your model from the form data. – Nkosi Jul 01 '16 at 12:16
1
public class SearchViewModel 
{
    public SearchResultModel SearchResultModel{ get; set; }
    public SearchCriteriaModel SearchCriteriaModel{ get; set; }
}

public virtual JsonResult LoadPreviousProductsJson(string model) 
{    
    var modelClass = JsonConvert.DeserializeObject<SearchViewModel>(model);
    var searchResultModel = modelClass.SearchCriteriaModel;
    var searchCriteriaModel = modelClass.SearchResultModel;
    //... other code
}

var jsonData = $('#frmSearchResult').serialize();

var jsonData2 = $('#frmSearchProducts').serialize();

var model = { SearchResultModel: jsonData, SearchCriteriaModel:jsonData2 };
     var url = "/Area/Controller/Action" + "?model=" + JSON.stringify(model) + "";
            $.ajax({
                url: url,
                dataType: "JSON",
                type: "GET",
                success: function () {
                }
            });

Hope this might be helpful

Krish
  • 376
  • 1
  • 10
  • check your properties. `modelClass.SearchResultMode` that should be `modelClass.rmodel` – Nkosi Jul 01 '16 at 11:13
  • @Nkosi, If that is rmodel then if you are trying to desearlize then you will end up in error. so you object name should be similar to the property in the Model class – Krish Jul 01 '16 at 11:15
  • Look at the names of the properties of your (my) `SearchViewModel` class. so you either have to update your javascript code or your c# code. Guessing you just copied and pasted from my code. No problem but pay attention to the names – Nkosi Jul 01 '16 at 11:18
  • hmmm I have updated the code. Yes I copied the structure but I have faced a similar situation in application – Krish Jul 01 '16 at 11:22
  • Your update is still wrong. would you like me to fix it for you? I wont touch your answer without your permission. I know your intention but your implementation has errors – Nkosi Jul 01 '16 at 11:24
1

First of all, thanks to inkosi and krish for giving tips (thumbs up for both). His answer wasn't exactly what I needed since I still was getting null values.

Here is what finally worked for me.

controller:

        public virtual JsonResult LoadPreviousProductsJson(string rmodel, string cmodel){

            SearchResultModel model = new SearchResultModel();

        SearchCriteriaModel modelSearchCriteria = new SearchCriteriaModel();

        model = Newtonsoft.Json.JsonConvert.DeserializeObject<SearchResultModel>(rmodel);

        modelSearchCriteria = Newtonsoft.Json.JsonConvert.DeserializeObject<SearchCriteriaModel>(cmodel); 
.......
}

Javascript:

        $.fn.serializeObject = function () {
        var o = {};
        var a = this.serializeArray();
        $.each(a, function () {
            if (o[this.name]) {
                if (!o[this.name].push) {
                    o[this.name] = [o[this.name]];
                }
                o[this.name].push(this.value || '');
            } else {
                o[this.name] = this.value || '';
            }
        });





            var jsonDataNewResult = $('#frmSearchResult').serializeObject();

        var stringjsonDataNewResult = JSON.stringify(jsonDataNewResult);


        var jsonDataNewCriteria = $('#frmSearchProducts').serializeObject();

        var stringjsonDataNewCriteria = JSON.stringify(jsonDataNewCriteria);

        $.post('@Url.Action(MVC.Product.LoadPreviousProductsJson())',
            { rmodel: stringjsonDataNewResult, cmodel: stringjsonDataNewCriteria })
            .done(function(data) {

What a day :-( , I must have tried a hundred things... I don't even remember all the things I tried..... happy to get here, now to explain to my boss why something this trivial has taken me so long.... I miss desktop programming !

PS. Thanks to these 2 SO posts:

Convert form data to JavaScript object with jQuery

Consume jQuery.serializeArray in ASP.NET MVC

Community
  • 1
  • 1
user1841243
  • 1,663
  • 2
  • 19
  • 35