Asp.net 在MVC控制器中将JSON绑定到JToken
有没有办法让MVC控制器将传入的动态JSON绑定到Asp.net 在MVC控制器中将JSON绑定到JToken,asp.net,asp.net-mvc,asp.net-web-api,asp.net-mvc-5,json.net,Asp.net,Asp.net Mvc,Asp.net Web Api,Asp.net Mvc 5,Json.net,有没有办法让MVC控制器将传入的动态JSON绑定到JToken对象 如果我使用API控制器,我可以做到: public class TestController : ApiController { public void Post(JToken json) { } } 发布的json被转换成JToken对象。 但是,如果使用MVC控制器,则会导致服务器错误 public class TestController : Controller { [HttpPost]
JToken
对象
如果我使用API控制器,我可以做到:
public class TestController : ApiController
{
public void Post(JToken json)
{
}
}
发布的json被转换成JToken
对象。
但是,如果使用MVC控制器,则会导致服务器错误
public class TestController : Controller
{
[HttpPost]
public ActionResult TestAction(JToken json)
{
return new HttpStatusCodeResult(HttpStatusCode.OK);
}
}
我意识到还有其他方法可以获取传入数据,但我更愿意在MVC控制器中作为JToken接收数据
我曾尝试使用自定义的ValueProviderFactory
,但我的AJAX调用仍然返回了一个服务器错误:
$.ajax({
url: '/Test/TestAction', //or /api/Test
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({foo:"bar",wibble:"wobble"})
}).done(function (res) {
alert('ok');
}).fail(function (xhr, status, error) {
alert('error')
});
更新:
注意-如上所述,我已将默认的JsonValueProviderFactory
替换为基于Json.NET
的工厂
经过进一步调查,问题似乎出现在
DefaultModelBinder.CreateModel
方法中。当DefaultModelBinder
尝试创建JToken
实例时,它会失败,因为JToken
是一个抽象类。即使我将TestAction
参数更改为JObject
,它仍然会失败,这可能是因为在对象继承权的更深处有JToken
属性。在这种特殊情况下,通过更改传入JSON的默认序列化程序不起作用。这似乎是因为JToken
是一个抽象类,默认的ModelBinder无法创建涉及抽象类的模型实例
解决办法是采取以下行动:
public class JsonNetModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (!IsJSONRequest(controllerContext))
{
return base.BindModel(controllerContext, bindingContext);
}
var request = controllerContext.HttpContext.Request;
request.InputStream.Seek(0, SeekOrigin.Begin);
var jsonStringData = new StreamReader(request.InputStream).ReadToEnd();
return JsonConvert.DeserializeObject(jsonStringData, bindingContext.ModelType);
}
private static bool IsJSONRequest(ControllerContext controllerContext)
{
var contentType = controllerContext.HttpContext.Request.ContentType;
return contentType.Contains("application/json");
}
}
并对操作使用自定义ModelBinder
,如下所示:
public class TestController : Controller
{
[HttpPost]
public ActionResult TestAction([ModelBinder(typeof(JsonNetModelBinder))] JToken json)
{
return new HttpStatusCodeResult(HttpStatusCode.OK);
}
}
你的JToken类有foo和wibble属性吗?@Karthik这是确定的。该类是否包含foo和wibble属性?ASP.Net MVC使用的是
JavaScriptSerializer
而不是Json.Net。要切换,请参阅和。@dbc谢谢,Jason Butera在第二个链接中的回答提供了解决方案,我还需要创建一个基于Json.NET的自定义ModelBinder。你想提供一个答案,我会接受它,还是我应该展示解决方案?