没有公共属性的类型上的自定义 MVC 模型绑定
本文关键字:自定义 MVC 模型 绑定 类型 属性 | 更新日期: 2023-09-27 18:37:17
我已经在我的项目中创建了强类型的ID类,因为目前与可互换的字符串ID存在混淆,这导致了容易错过的错误。
我已将操作方法中的所有string id
参数更改为新的强类型,以实现 MVC 模型绑定器现在无法将字符串绑定到新类型(尽管此类型存在隐式字符串转换运算符)。
例如
public ActionResult Index(JobId jobId)
{
//...
}
我已经阅读了有关创建自定义模型绑定器的信息,但是当我们知道查询参数/表单值的名称时,所有教程都是关于绑定POCO类的。
我只是希望能够告诉框架"如果参数是强类型 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);
}
}
我刚刚想出了一种方法来使用自定义模型绑定器来做到这一点。无论需要绑定的参数名称如何,这种方式都将起作用:
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());