我在我的项目中创建了强类型ID类,因为目前存在可互换字符串ID的混淆,导致容易错过的错误。
我已将操作方法中的所有string id
参数更改为新的强类型,以实现MVC模型绑定器现在无法将字符串绑定到新类型(尽管此类型存在隐式字符串转换运算符)。
e.g。
public ActionResult Index(JobId jobId)
{
//...
}
我已经阅读了有关创建自定义模型绑定器的内容,但是当我们知道查询参数/表单值的名称时,所有教程都是关于绑定POCO类。
我只是想告诉框架'if参数是强类型id类型,使用这个构造函数实例化',所以无论参数名称是什么,它都会一直有效。
有人能指出我正确的方向吗?
修改
这是强类型ID继承自的基类:
public class StronglyTypedId
{
private readonly string _id;
public StronglyTypedId(string id)
{
_id = id;
}
public static bool operator ==(StronglyTypedId a, StronglyTypedId b)
{
if (ReferenceEquals(a, b))
{
return true;
}
if (((object)a != null) && ((object)b == null) || ((object)a == null))
{
return false;
}
return a._id == b._id;
}
public static bool operator !=(StronglyTypedId a, StronglyTypedId b)
{
return !(a == b);
}
public override string ToString()
{
return _id;
}
public override bool Equals(object obj)
{
if (!(obj is StronglyTypedId))
{
return false;
}
return ((StronglyTypedId)obj)._id == _id;
}
public Guid ToGuid()
{
return Guid.Parse(_id);
}
public bool HasValue()
{
return !string.IsNullOrEmpty(_id);
}
}
答案 0 :(得分:0)
我现在想出了一种使用自定义模型绑定器的方法。无论需要绑定的参数名称是什么,这种方式都可以工作:
public class JobIdModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType == typeof(JobId))
{
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
string id = value.AttemptedValue;
return new JobId(id);
}
else
{
return base.BindModel(controllerContext, bindingContext);
}
}
}
所以它与为特定模型类型实现自定义绑定器几乎相同,除了这有点神奇var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName)
,这意味着无论参数命名如何都可以工作。
然后您只需在Global.cs
中注册活页夹,就像这样:
ModelBinders.Binders.Add(typeof(JobId), new JobIdModelBinder());