Hi,
I’m having trouble trying to pass a complex JSON object to an MVC 4 controller action. As the JSON content is variable, I don’t want MVC to map individual properties/elements of the JSON to parameters in the action method’s parameter list. I just want to
get the data as a single JSON string parameter in the controller action.
Here’s the signature of my action method:
[HttpPost] [ValidateInput(false)] public string ConvertLogInfoToXml(string jsonOfLog)
And here’s my attempt to post some JSON data, from my browser:
data = {prop: 1, myArray: [1, "two", 3]}; //'data' is much more complicated in my real application json = {jsonOfLog: data}; $.ajax({ type: 'POST', url: "Home/ConvertLogInfoToXml", data: JSON.stringify(json), success: function (returnPayload) { console && console.log ("request succeeded"); }, error: function (xhr, ajaxOptions, thrownError) { console && console.log ("request failed"); }, dataType: "xml", contentType: "application/json", processData: false, async: false });
When I hit my breakpoint at the beginning of the ConvertLogInfoToXML method, jsonOfLog is null.
If I change what ‘json’ variable is set to in the JavaScript to have the jsonOfLog property be a simple string, e.g. :
json = { jsonOfLog: "simple string" };
then when my breakpoint at the beginning of the ConvertLogInfoToXML method is hit, jsonOfLog is the value of the string (e.g. “simple string”).
I tried changing the type of the jsonOfLog parameter in the action method to be of type object:
[HttpPost] [ValidateInput(false)] public string ConvertLogInfoToXml(object jsonOfLog)
Now, with the original JavaScript code (where I’m passing a more complex ‘data’ object), jsonOfLog gets the value of {object}. But the debugger doesn’t show any more details in a watch window, and I don’t know what methods I can use to operate on this variable.
How do I pass JSON data to a MVC controller, where the data passed is a stringified complex object?
Thanks,
Notre
Create a class that have a prop as property get/set. See how I pass on click "Save" name and department id in http://msprogrammer.serviciipeweb.ro/2011/12/05/jquery-ajax-request-and-mvcdetailed/
For array you must follow this
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
Hi Ignatandrei,
Thank you very much for your reply and your links.
I’m not sure if my original question was clear (I’m afraid it may not be). My constraint is that I don’t know what kind of JSON is being passed from the browser. It
will be complex; it will have nested properties and contain array(s). But I won’t know in the receiving controller action what exactly I’m going to get, so I don’t want to create a model. I stringify it on the browser; I just want to get that stringified
version on the server side as a single parameter and use JsonConvert to convert the arbitrary JSON to XML:
XmlDocument xmlDocument = (XmlDocument)JsonConvert.DeserializeXmlNode(jsonOfLog, "root");
I don’t want the binder (or whatever) to attempt to convert the JSON to a set of parameters/objects in the action method.
Thanks,
Notre
Notre_Poubelle
My constraint is that I don’t know what kind of JSON is being passed from the browser.
That is the same as saying that you have a class, you do not know what properties it have. What yuo want to do with it?
Notre_Poubelle
It will be complex; it will have nested properties and contain array(s).
For sure the arrays will not satisfy MVC requirements of server binding.
Notre_Poubelle
I just want to get that stringified version on the server side as a single parameter and use JsonConvert to convert the arbitrary JSON to XML:
Why you do not do that on client with javascript and send to the server just a string?
ignatandrei
Notre_Poubelle
My constraint is that I don’t know what kind of JSON is being passed from the browser.
That is the same as saying that you have a class, you do not know what properties it have. What yuo want to do with it?
Ultimately, I just want to get a string that represents JSON down to the server, and do further processing (convert the JSON string to XML, there).
ignatandrei
Notre_Poubelle
I just want to get that stringified version on the server side as a single parameter and use JsonConvert to convert the arbitrary JSON to XML:
Why you do not do that on client with javascript and send to the server just a string?
You mean, why not just send the stringified version of the JSON to the server? That is what I’m trying to do. I messed with the contentType, changing it from "application/json" to "application/x-www-form-urlencoded". Then I modified the "data" property
of the jQuery.Ajax object to be like this:
data: "jsonOfLog= " + JSON.stringify(json)
This worked at first (and I was happy). However, when I have more data to send, the data is truncated (I think on the server) when using "application/x-www-form-urlencoded". I can look at my browser request (in IE9) network tool, and everything seems to
be there, but on the server side the receiving string is truncated. I think using the "application/x-www-form-urlencoded" content type is designed to not transfer as much data.
Thanks,
Notre
Notre_Poubelle
I just want to get a string that represents JSON down to the server, and do further processing (convert the JSON string to XML, there).
THis is rather strange. Why you do not convert to xml from the javascript?
Notre_Poubelle
, why not just send the stringified version of the JSON to the server? That is what I’m trying to do.
then stringify all properties
Example:
data = {prop: 1, myArray: [1, "two", 3]};
stingify first myArray, then stringify data.
See https://github.com/Canop/JSON.prune
The problem is, that I don’t know what the various properties are of the JSON statically, so I can’t stringify individual properties. The only thing I know is the root property, which I use to wrap whatever the contained JSON is.
I’ve not found any way to make this work with ASP.NET MVC, except using application/x-www-form-urlencoded. But this ran into the problem where if there was content of any significant length, it was truncated when content was received in the ASP.NET MVC
controller action.
I ended up switching my controller action to web api. With this approach, I could pass an arbitrary stringified object, and use a content type of application/json. Doing so I didn’t run into the length issue and everything worked as desired.
Could you please post your final solution?
I’m afraid I’ve moved on to a different company and don’t have access to the source code any longer. When I switched to WebAPI, there was nothing special about it. Everything just worked as expected. An ex-colleague did find a way to get this to work
with ASP.NET MVC but I fear I don’t remember the details (nor do I have the source code any longer). Sorry
I spoke with my ex-colleague and here’s what the code looked like on the browser side:
$.ajax({ type: 'POST', url: "path/endpoint", data: JSON.stringify({ myPropName: arrayList }), ... dataType: "text", contentType: "application/json; charset=utf-8", processData: false });
The controller method’s signature was:
[HttpPost] public JsonNetResult endpoint(string myPropName)
Hopefully this helps!
I came here looking for a solution to a similar problem.
Basically, I need to post JSON data to a MVC controller and then process as a string data, without need to specify a model (say I’m lazy and don’t want to specify a class with lot of properties to binding).
So I found a solution based on this answer http://stackoverflow.com/a/19292019/654634 and decide to post here also.
The idea is to get data directly from HttpContext.Request, here’s the controller’s code:
[HttpPost] public virtual ActionResult saveEvaluacion() { var resolveRequest = HttpContext.Request; resolveRequest.InputStream.Seek(0, SeekOrigin.Begin); string jsonString = new StreamReader(resolveRequest.InputStream).ReadToEnd(); if (jsonString != null) { //Deserialize JSON data to a dynamic type dynamic eval = JsonConvert.DeserializeObject(jsonString); int obrerokey = eval.id; int aspectoId = eval.evaluaciones[0].aspectoId; int aspectoCalif = eval.evaluaciones[0].aspectoCalif; } ... }
HTH.
Roberto.