从内容类型为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) { }