json - 在 ASP.NET MVC 3 中将 JSON 反序列化为没有默认构造函数的对象

标签 json asp.net-mvc-3 deserialization

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

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

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
}

一个示例 Controller 操作可能是:
[HttpPost]
public ActionResult ShowSomething(EmailAddress emailAddress)
{
    return View(emailAddress)
}

进来的 JSON 是:
{"Address":"joe@bloggs.com","Name":"Joe Bloggs"}

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

尽管对任何好的建议持开放态度,但不干扰对象本身的解决方案将是可取的(即单独的反序列化器类,而不是向属性添加属性等)。

我在这里发现了一个类似的问题(没有答案):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?



是的,您可以编写自定义模型绑定(bind)器:
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 中注册:
ModelBinders.Binders.Add(typeof(EmailAddress), new EmailAddressModelBinder());

最后剩下的就是调用 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');
    }
});

关于json - 在 ASP.NET MVC 3 中将 JSON 反序列化为没有默认构造函数的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7360239/

相关文章:

asp.net - 使用 JQuery 渲染部分 View 时遇到问题

java - 通过反序列化代码更改数据

javascript - 对多个组合框使用相同的 ID?

javascript - JSON 解析与否?

json - Angular environment.ts 问题 JSON。然而 environment.prod.ts

javascript - "gameActivity" key 在开始时更改但应该停止

asp.net-mvc-3 - 通过 ASP.NET 同步上下文安全地执行任务,无需 AsyncManager.Sync

c# - 远程属性验证未在 Asp.Net MVC 中触发

java - (Jackson 1.9.2) 让@JsonIgnore 工作 : deserialization with mixin annotations and polymorphic types

c# - 反序列化其他列表中的列表时,Newtonsoft 反序列化重复元素