从内容类型为application / json的请求中检索值

我有以下脚本将数据发送到MVC中的控制器:

$.ajax({ url: '/products/create', type: 'post', contentType: 'application/json; charset=utf-8', data: JSON.stringify({ 'name':'widget', 'foo':'bar' }) }); 

我的控制器看起来像这样:

 [HttpPost] public ActionResult Create(Product product) { return Json(new {success = true}); } public class Product { public string name { get; set; } } 

有没有办法在没有控制器动作的情况下获得“foo”变量

  • 修改模型
  • 修改动作的签名

如果是常规表单提交,我可以访问Request.Form [“foo”],但是这个值为null,因为它是通过application / json提交的。

我希望能够从动作filter访问此值,这就是我不想修改签名/模型的原因。

我想今天几乎完全一样,发现这个问题没有答案。 我也用Mark的类似解决方案解决了它。

这对我来说非常适合我在asp.net MVC 4.也许可以帮助别人阅读这个问题,即使它是一个旧问题。

  [HttpPost] public ActionResult Create() { string jsonPostData; using (var stream = Request.InputStream) { stream.Position = 0; using (var reader = new System.IO.StreamReader(stream)) { jsonPostData = reader.ReadToEnd(); } } var foo = Newtonsoft.Json.JsonConvert.DeserializeObject>(jsonPostData)["foo"]; return Json(new { success = true }); } 

重要的部分是重置流的位置,因为它已经被某些MVC内部代码或其他内容读取。

我希望能够从动作filter访问此值,这就是我不想修改签名/模型的原因。

在不更改方法的签名的情况下访问Actionfilter中的值会很棘手。 从这篇文章中可以更好地理解这个原因。

此代码可以在授权filter中使用,也可以在模型绑定之前运行的代码中使用。

 public class CustomFilter : FilterAttribute, IAuthorizationFilter { public void OnAuthorization(AuthorizationContext filterContext) { var request = filterContext.RequestContext.HttpContext.Request; var body = request.InputStream; var encoding = request.ContentEncoding; var reader = new StreamReader(body, encoding); var json = reader.ReadToEnd(); var ser = new JavaScriptSerializer(); // you can read the json data from here var jsonDictionary = ser.Deserialize>(json); // i'm resetting the position back to 0, else the value of product in the action // method will be null. request.InputStream.Position = 0; } } 

即使这个’foo’没有绑定,它也会在你的动作filter中通过:

 filterContext.HttpContext.Current.Request.Params 

如果看到参数,请查看这些集合。

所以是的,只需创建您的动作filter,不要更改它将起作用的签名。

以防万一调试您的filter以确定值的位置。

最后,您需要在global.asax中注册json的值提供程序:

 protected void Application_Start() { RegisterRoutes(RouteTable.Routes); ValueProviderFactories.Factories.Add(new JsonValueProviderFactory()); } 

您的参数也是错误的,它需要更像:

 $.ajax({ url: '/products/create', type: 'post', contentType: 'application/json; charset=utf-8', data: JSON.stringify({ name:'widget', foo:'bar' }) }); 

没有报价。

编辑(更准确地说):

您的filter将包含这些方法

 public void OnActionExecuting(ActionExecutingContext filterContext) { } public void OnActionExecuted(ActionExecutedContext filterContext) { }