DataContract模型在ASP.NET MVC操作方法参数绑定到JSON [英] DataContract model binding to JSON in ASP.NET MVC Action Method Arguments

查看:183
本文介绍了DataContract模型在ASP.NET MVC操作方法参数绑定到JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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.net属性映射到模型中的不同对象的属性(而不是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.net 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆