在ASP.NET MVC 3中将JSON反序列化为没有默认构造函数的对象 [英] Deserializing JSON to object with no default constructor in ASP.NET MVC 3

查看:130
本文介绍了在ASP.NET MVC 3中将JSON反序列化为没有默认构造函数的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于JSON反序列化的问题很多,但其中很多似乎是针对MVC 1或MVC 2的.我似乎还没有找到专门针对MVC 3的令人满意的答案.

There are quite a few questions around JSON deserialization but a lot of them seem to be for MVC 1 or MVC 2. I don't seem to have found a satisfactory answer to this specifically for MVC 3.

我有一个具有不变属性且没有默认构造函数的对象,我想在ASP.NET MVC 3应用程序中反序列化该对象.这是一个简化的版本:

I have an object with immutable properties and no default constructor, which I want to deserialize to in an ASP.NET MVC 3 application. Here is a simplified version:

public class EmailAddress
{
    public EmailAddress(string nameAndEmailAddress)
    {
        Name = parseNameFromNameAndAddress(nameAndEmailAddress);
        Address = parseAddressFromNameAndAddress(nameAndEmailAddress);
    }

    public EmailAddress(string name, string address)
    {
        Guard.Against<FormatException>(!isNameValid(name), "Value is invalid for EmailAddress.Name: [{0}]", name);
        Guard.Against<FormatException>(!isAddressValid(address), "Value is invalid for EmailAddress.Address: [{0}]", address);
        Name = name;
        Address = address;
    }

    public string Address { get; private set; }
    public string Name { get; private set; }

    // Other stuff
}

示例控制器动作可能是:

An example controller action might be:

[HttpPost]
public ActionResult ShowSomething(EmailAddress emailAddress)
{
    return View(emailAddress)
}

传入的JSON是:

{"Address":"joe@bloggs.com","Name":"Joe Bloggs"}

在MVC3中反序列化的最佳方法是什么?有什么方法可以实现可处理此问题的自定义模型绑定程序或反序列化器类?

What is the best way to get this to deserialize in MVC3? Is there some way of implementing a custom model binder or deserializer class that can handle this?

最好采用不干扰对象本身的解决方案(例如,使用单独的反序列化器类,而不是在属性中添加属性等),尽管有很多好的建议.

A solution that doesn't interfere with the object itself would be preferable (ie. a separate deserializer class, rather than adding attributes to properties, etc), although open to any good suggestions.

我在这里找到了类似的问题(没有答案):我可以使用JavascriptSerializer反序列化为不可变的对象吗?

I found a similar question (with no answer) here: Can I deserialize to an immutable object using JavascriptSerializer?

推荐答案

是否有某种方法可以实现自定义模型联编程序或 能解决这个问题的反序列化器类?

Is there some way of implementing a custom model binder or deserializer class that can handle this?

是的,您可以编写自定义模型联编程序:

Yes, you could write a custom model binder:

public class EmailAddressModelBinder : DefaultModelBinder
{
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
    {
        var addressKey = "Address";
        var nameKey = "Name";
        if (!string.IsNullOrEmpty(bindingContext.ModelName))
        {
            addressKey = bindingContext.ModelName + "." + addressKey;
            nameKey = bindingContext.ModelName + "." + nameKey;
        }

        var addressValue = bindingContext.ValueProvider.GetValue(addressKey);
        var nameValue = bindingContext.ValueProvider.GetValue(nameKey);
        if (addressValue == null || nameValue == null)
        {
            throw new Exception("You must supply an address and name");
        }
        return new EmailAddress(nameValue.AttemptedValue, addressValue.AttemptedValue);
    }
}

将在Application_Start中注册:

which will be registered in Application_Start:

ModelBinders.Binders.Add(typeof(EmailAddress), new EmailAddressModelBinder());

最后剩下的就是调用该动作:

and finally all that's left is to invoke the action:

$.ajax({
    url: '@Url.Action("ShowSomething")',
    type: 'POST',
    data: JSON.stringify({ "Address": "joe@bloggs.com", "Name": "Joe Bloggs" }),
    contentType: 'application/json',
    succes: function (result) {
        alert('success');
    }
});

这篇关于在ASP.NET MVC 3中将JSON反序列化为没有默认构造函数的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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