MVC - Http Post JSON - 序列化依赖
我正在使用 ASP MVC 和 JQuery 并将 json 数据发布到我的控制器。
var jsonPostData = {
control: "PersonControl",
data: {
name: "Craig",
age: 25
}
};
我正在使用以下内容来执行序列化。
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;
}
}
其序列化为以下模型:
[DataContract]
public class ControlModel
{
[DataMember(Name = "control", IsRequired = true)]
public string Control { get; set; }
[DataMember(Name = "data"]
public object Data { get; set; }
}
这工作正常。
我试图解决的问题是数据的类型取决于控制值传递的内容。
我使用反射从控件值创建控件实例。我希望能够调用此控件实例以获取动态类型,然后用于单独序列化“数据”。
CustomControl.GetDataType()
这里会返回 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; }
}
所以本质上我试图找出是否可以在两个不同的部分块中解析我的 JSON。
有想法吗?建议?
根据 thaBadDawg 的建议,我最终选择了 JSON.Net 路线,它允许我解析单独的 JSON 项,允许我首先拉出控件,然后在我的控件实现中拉出所需的自定义数据项。
这是我上面的示例,重写(并简化了示例)以使用它:
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"];
}
}
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"];
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我突然想到,我建议使用 Json.Net 路线,将其用作 Linq to JSON 解析器,并跳过顶层的反序列化(只需查询它的值),然后让它决定反序列化嵌套的类型对象进入.我使用 DataContractJsonSerializer 的经验使我相信您将无法找到一条简单的解决方案。
这里有一个使用 Linq to JSON 的很好的例子: http://james.newtonking .com/projects/json/help/LINQtoJSON.html
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