Ale*_*use 5 c# asp.net-mvc asp.net-mvc-4
在我们的 MVC 2 应用程序中,我们实现了一个 JSON 模型绑定器,如下所示:
public virtual object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
string input;
using (var reader = new StreamReader(controllerContext.HttpContext.Request.InputStream))
{
input = reader.ReadToEnd();
}
return JsonConvert.DeserializeObject(
input,
bindingContext.ModelType);
}
Run Code Online (Sandbox Code Playgroud)
更新到 MVC 4 后,我注意到我们为传入的 JSON 帖子获取了空传入模型。当挖掘时,很明显上游有什么东西正在推进溪流。这很容易修复,就像这样
public virtual object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
string input;
//something upstream after MVC 4 upgrade is advancing the stream to end before we can read it
controllerContext.HttpContext.Request.InputStream.Position = 0;
using (var reader = new StreamReader(controllerContext.HttpContext.Request.InputStream))
{
input = reader.ReadToEnd();
}
return JsonConvert.DeserializeObject(
input,
bindingContext.ModelType);
}
Run Code Online (Sandbox Code Playgroud)
但我想知道发生了什么使改变成为必要?之前的实现只是巧合吗?
不,之前的实施并非巧合。
ASP.NET MVC 3引入了内置的 JSON 绑定支持,使操作方法能够接收 JSON 编码的数据并将其模型绑定到操作方法参数。
JsonValueProviderFactory于 及以后默认注册ASP.NET MVC 3。值提供程序JSON在模型绑定之前运行,并将请求数据序列化到字典中。然后将字典数据传递到model binder.
让我们看看如何工作。这里是ASP.NET MVC 开源代码JsonValueProviderFactory.csJsonValueProviderFactory中提供的源代码的链接JsonValueProviderFactory
GetDeserializedObject中定义的方法,如果设置为则JsonValueProviderFactory.cs读取,因此它将留在流的末尾。所以这里先调用再调用。由于
已经读取了一次流并将其推进到流的末尾,因此我们需要再次重置streamContent-Typeapplication/jsonRequest.InputStreamGetDeserializedObjectBindModelGetDeserializedObjectRequest.InputStreamRequest.InputStreamBindModel
private static object GetDeserializedObject(ControllerContext controllerContext)
{
if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
{
// not JSON request
return null;
}
StreamReader reader = new StreamReader(controllerContext.HttpContext.Request.InputStream);
string bodyText = reader.ReadToEnd();
if (String.IsNullOrEmpty(bodyText))
{
// no JSON data
return null;
}
JavaScriptSerializer serializer = new JavaScriptSerializer();
object jsonData = serializer.DeserializeObject(bodyText);
return jsonData;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2482 次 |
| 最近记录: |