MVC3出来这对传入的JSON结合的模式非常方便的与JsonValueProviderFactory(盒)的。不幸的是,我无法弄清楚如何建立示范合同与从传入的JSON不同的名字。例如:
[DataContract(NAME =会议)]公共类FacebookSession{ [数据成员(NAME =ACCESS_TOKEN)] 公共字符串的accessToken {搞定;组; } [数据成员(NAME =过期)] 公众诠释?过期{搞定;组; } [数据成员(名称为秘密)] 公共字符串秘密{搞定;组; } [数据成员(NAME =session_key可以)] 公共字符串Sessionkey {搞定;组; } [数据成员(NAME =SIG)] 公共特征码{搞定;组; } [数据成员(NAME =UID)] 公共字符串userid {搞定;组; }}在JSON对象路过时再presenting Facebook的会议上,性能和秘密绑定到期正确,但其余不要因为属性名称是不是JSON的键名不同
。我期望的datacontract串行会尝试绑定到属性提供的名称,但不会出现这种情况。没有人有任何解决办法的建议?
修改
我怎么会用这种模式的一个例子:
公众的ActionResult日志(INT?CUSTID,FacebookSession响应) { ViewBag.Id = response.UserId; 返回查看(); }解决方案
最后我用gt124的链接的模型绑定例如的一起一个更好的模型绑定以写我自己的模型绑定逻辑。它结束了看起来像这样:
public接口IFilteredModelBinder:IModelBinder { 布尔IsMatch(类型modelType); }公共类SmartModelBinder:DefaultModelBinder{ 私人只读IFilteredModelBinder [] _filteredModelBinders; 公共SmartModelBinder(IFilteredModelBinder [] filteredModelBinders) { _filteredModelBinders = filteredModelBinders; } 公众覆盖对象BindModel(ControllerContext controllerContext,ModelBindingContext的BindingContext) { 的foreach(在_filteredModelBinders VAR filteredModelBinder) { 如果(filteredModelBinder.IsMatch(bindingContext.ModelType)) { 返回filteredModelBinder.BindModel(controllerContext,BindingContext中); } } 返回base.BindModel(controllerContext,BindingContext中); }}公共类NewtonsoftJsonModelBinder:IFilteredModelBinder{ 公共对象BindModel(ControllerContext controllerContext,ModelBindingContext的BindingContext) { 如果(!controllerContext.HttpContext.Request.ContentType.StartsWith(应用/ JSON,StringComparison.OrdinalIgnoreCase)) { //不是JSON请求 返回null; } VAR请求= controllerContext.HttpContext.Request; request.InputStream.Position = 0; VAR incomingData =新的StreamReader(request.InputStream).ReadToEnd(); 如果(String.IsNullOrEmpty(incomingData)) { //没有JSON数据 返回null; } RET对象= JsonConvert.DeserializeObject(incomingData,bindingContext.ModelType); 返回RET; } 公共BOOL IsMatch(类型modelType) { VAR RET =(typeof运算(JsonModel).IsAssignableFrom(modelType)); 返回RET; }}然后我用JSON属性映射到模型中的不同对象的属性(而不是DataContracts)。这些模型都是从一个空基类继承JsonModel
MVC3 comes out of the box with JsonValueProviderFactory() which is very handy for binding incoming JSON to a model. Unfortunately, I can't figure out how to setup model contracts with names that differ from the incoming JSON. For example:
[DataContract(Name = "session")] public class FacebookSession { [DataMember(Name = "access_token")] public string AccessToken { get; set; } [DataMember(Name = "expires")] public int? Expires { get; set; } [DataMember(Name = "secret")] public string Secret { get; set; } [DataMember(Name = "session_key")] public string Sessionkey { get; set; } [DataMember(Name = "sig")] public string Signature { get; set; } [DataMember(Name = "uid")] public string UserId { get; set; } }when passing in a json object representing the facebook session, the properties secret and expires bind properly, but the rest do not because the property name is different than the json key name. I would expect that the datacontract serializer would try and bind to the name provided in the attribute, but that doesn't appear to be the case. Does anyone have any workaround suggestions?
Edit
An example of how I would use this model:
public ActionResult Log(int? custId, FacebookSession response) { ViewBag.Id = response.UserId; return View(); }解决方案
I ended up using gt124's link model binder example along with a better model binder to write my own model binding logic. It ended up looking like this:
public interface IFilteredModelBinder : IModelBinder { bool IsMatch(Type modelType); } public class SmartModelBinder : DefaultModelBinder { private readonly IFilteredModelBinder[] _filteredModelBinders; public SmartModelBinder(IFilteredModelBinder[] filteredModelBinders) { _filteredModelBinders = filteredModelBinders; } public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { foreach (var filteredModelBinder in _filteredModelBinders) { if (filteredModelBinder.IsMatch(bindingContext.ModelType)) { return filteredModelBinder.BindModel(controllerContext, bindingContext); } } return base.BindModel(controllerContext, bindingContext); } } public class NewtonsoftJsonModelBinder : IFilteredModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase)) { // not JSON request return null; } var request = controllerContext.HttpContext.Request; request.InputStream.Position = 0; var incomingData = new StreamReader(request.InputStream).ReadToEnd(); if (String.IsNullOrEmpty(incomingData)) { // no JSON data return null; } object ret = JsonConvert.DeserializeObject(incomingData, bindingContext.ModelType); return ret; } public bool IsMatch(Type modelType) { var ret = (typeof(JsonModel).IsAssignableFrom(modelType)); return ret; } }I then used JSON attributes to map to the different object properties (instead of DataContracts) on the models. The models all inherited from an empty base class JsonModel.
更多推荐
DataContract模型在ASP.NET MVC操作方法参数绑定到JSON
发布评论