我有以下脚本将数据发送到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提交的。
我希望能够从动作过滤器访问此值,这就是我不想修改签名/模型的原因。
答案 0 :(得分:4)
我想今天几乎完全一样,发现这个问题没有答案。我也用与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<IDictionary<string, object>>(jsonPostData)["foo"];
return Json(new { success = true });
}
重要的部分是重置流的位置,因为它已被某些MVC内部代码或其他内容读取。
答案 1 :(得分:1)
我希望能够从动作过滤器中访问此值 这就是为什么我不想修改签名/模型。
在不更改方法签名的情况下访问Action过滤器中的值会很棘手。从post开始,可以更好地理解原因。
此代码适用于授权过滤器或模型绑定之前运行的代码。
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<Dictionary<string, string>>(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;
}
}
答案 2 :(得分:-2)
即使这个'foo'没有绑定,它也会在你的动作过滤器中通过:
filterContext.HttpContext.Current.Request.Params
如果看到参数,请查看这些集合。
所以是的,只需创建您的动作过滤器,不要更改它将起作用的签名。
以防万一调试过滤器以确定值的位置。
最后,您需要在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'
})
});
没有引用。
编辑(更准确地说):
您的过滤器将包含这些方法
public void OnActionExecuting(ActionExecutingContext filterContext)
{
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
}