关于 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/