ek_*_*_ny 10 asp.net-mvc json custom-model-binder data-annotations
我开始玩knockout.js并且这样做我使用了FromJsonAttribute(由Steve Sanderson创建).我遇到了自定义属性未执行模型验证的问题.我把一个简单的例子放在一起 - 我知道它看起来像很多代码 - 但基本问题是如何强制在自定义模型绑定器中验证模型.
using System.ComponentModel.DataAnnotations;
namespace BindingExamples.Models
{
public class Widget
{
[Required]
public string Name { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的控制器:
using System;
using System.Web.Mvc;
using BindingExamples.Models;
namespace BindingExamples.Controllers
{
public class WidgetController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(Widget w)
{
if(this.ModelState.IsValid)
{
TempData["message"] = String.Format("Thanks for inserting {0}", w.Name);
return RedirectToAction("Confirmation");
}
return View(w);
}
[HttpPost]
public ActionResult PostJson([koListEditor.FromJson] Widget w)
{
//the ModelState.IsValid even though the widget has an empty Name
if (this.ModelState.IsValid)
{
TempData["message"] = String.Format("Thanks for inserting {0}", w.Name);
return RedirectToAction("Confirmation");
}
return View(w);
}
public ActionResult Confirmation()
{
return View();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是该模型在我的PostJson方法中始终有效.为了完整性,这里是FromJson属性的Sanderson代码:
using System.Web.Mvc;
using System.Web.Script.Serialization;
namespace koListEditor
{
public class FromJsonAttribute : CustomModelBinderAttribute
{
private readonly static JavaScriptSerializer serializer = new JavaScriptSerializer();
public override IModelBinder GetBinder()
{
return new JsonModelBinder();
}
private class JsonModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var stringified = controllerContext.HttpContext.Request[bindingContext.ModelName];
if (string.IsNullOrEmpty(stringified))
return null;
var model = serializer.Deserialize(stringified, bindingContext.ModelType);
return model;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
dkn*_*ack 13
该FromJsonAttribute只结合模型和呢,像你说的,没有验证.
您可以向其添加验证FromJsonAttribute,以便根据其DataAnnotations属性验证模型.
这可以使用TypeDescriptor该类完成.
TypeDescriptor提供有关组件特征的信息,例如其属性,属性和事件.
看看我的解决方案.我测试了它.
private class JsonModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var stringified = controllerContext.HttpContext.Request[bindingContext.ModelName];
if (string.IsNullOrEmpty(stringified))
return null;
var model = serializer.Deserialize(stringified, bindingContext.ModelType);
// DataAnnotation Validation
var validationResult = from prop in TypeDescriptor.GetProperties(model).Cast<PropertyDescriptor>()
from attribute in prop.Attributes.OfType<ValidationAttribute>()
where !attribute.IsValid(prop.GetValue(model))
select new { Propertie = prop.Name, ErrorMessage = attribute.FormatErrorMessage(string.Empty) };
// Add the ValidationResult's to the ModelState
foreach (var validationResultItem in validationResult)
bindingContext.ModelState.AddModelError(validationResultItem.Propertie, validationResultItem.ErrorMessage);
return model;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3448 次 |
| 最近记录: |