MVC - Http Post JSON - Serialization Dependency
I am using开发者_运维百科 ASP MVC with JQuery and posting json data to my controller.
var jsonPostData = {
control: "PersonControl",
data: {
name: "Craig",
age: 25
}
};
I am using the following to perform my serialization.
public override void OnActionExecuting(ActionExecutingContext FilterContext)
{
var contentType = FilterContext.HttpContext.Request.ContentType
?? string.Empty;
if (contentType.Contains("application/json"))
{
object JsonObject = new DataContractJsonSerializer(RootType)
.ReadObject(FilterContext.HttpContext.Request.InputStream);
FilterContext.ActionParameters[Param] = JsonObject;
}
}
Which serializes to the following model:
[DataContract]
public class ControlModel
{
[DataMember(Name = "control", IsRequired = true)]
public string Control { get; set; }
[DataMember(Name = "data"]
public object Data { get; set; }
}
This is working fine.
The problem I am trying to resolve is that the type for data is dependent upon what is passed for the control value.
I use reflection to create a control instance from the control value. I would like to be able to then call into this control instance to get a dynamic type back to then use to serialize "Data" separately.
CustomControl.GetDataType()
here would return typeof(PersonModel)
object JsonObject = new DataContractJsonSerializer(CustomControl.GetDataType())
.ReadObject(FilterContext.HttpContext.Request.InputStream);
[DataContract] //this is what data could be serialized too
public class PersonModel
{
[DataMember(Name="name", IsRequired=true)]
public string Name { get; set; }
[DataMember(Name="age", IsRequired=true)]
public string Age { get; set; }
}
So essentially I am trying to find if I can parse my JSON in two different partial chunks.
Ideas? Suggestions?
As per the suggestion from thaBadDawg, I ended up going with the JSON.Net route, which allows me to parse the JSON items individually, allowing me to first pull out the control, and then later in my control implementation pull out the needed custom data items.
Here is my example above rewritten (and simplified for the example) to use this:
public override void OnActionExecuting(ActionExecutingContext FilterContext)
{
if ((FilterContext.HttpContext.Request.ContentType ?? string.Empty).Contains("application/json"))
{
var bytes = new byte[FilterContext.HttpContext.Request.InputStream.Length];
FilterContext.HttpContext.Request.InputStream.Read(bytes, 0, bytes.Length);
FilterContext.HttpContext.Request.InputStream.Position = 0;
JObject JsonObject = JObject.Parse(Encoding.UTF8.GetString(bytes));
FilterContext.ActionParameters["Control"] = (string) JsonObject["control"];
FilterContext.ActionParameters["Action"] = (string)JsonObject["action"];
}
}
Off the top of my head I would suggest going the Json.Net route using it as a Linq to JSON parser and skip the deserialization of the top level (just query it for it's value) and then have it decide what type to deserialize the nested object into. My experience with the DataContractJsonSerializer leads me to believe that you will be unable to find a simple solution going that route.
There's a pretty good example of using Linq to JSON here : http://james.newtonking.com/projects/json/help/LINQtoJSON.html
精彩评论