我创建了一个mvc模型类,其中一个属性是'MyObject'类型。它上面还有一个System.ComponentModel.DataAnnotations.StringLength属性。
MyObject作为隐式转换运算符,因此它基本上可以用作字符串:
public static implicit operator string(MyObject o){...}
public static implicit operator MyObject(string sValue){...}
出于某种奇怪的原因,这是一个asp mvc问题吗?我问,因为我知道在大多数情况下隐式转换工作正常,我可以例如将该属性分配给字符串值,它可以正常工作。
编辑 - 好的,我知道错误发生的原因:
这是因为StringLength.IsValid()方法将一个对象作为参数,因此转换实际上是从一个对象转到另一个字符串,而不是从MyObject转到字符串,这就解释了为什么我的隐式转换操作符没有被调用。但是如何解决这个问题?
这一切都正常,直到我在我的模型中的属性上放置System.ComponentModel.DataAnnotations.StringLength属性,然后当视图从提交按钮发出帖子时,我得到了例外:
[InvalidCastException:无法投射 对象类型 'StrataSpot.Shared.Models.Email'来 输入'System.String'。] System.ComponentModel.DataAnnotations.StringLengthAttribute.IsValid(对象 价值)+34
System.Web.Mvc.d__1.MoveNext() +56 System.Web.Mvc.DefaultModelBinder.OnPropertyValidated(ControllerContext controllerContext,ModelBindingContext bindingContext,PropertyDescriptor propertyDescriptor,Object value)+203 System.Web.Mvc.DefaultModelBinder.BindProperty(ControllerContext controllerContext,ModelBindingContext bindingContext,PropertyDescriptor propertyDescriptor)+413
System.Web.Mvc.DefaultModelBinder.BindProperties(ControllerContext controllerContext,ModelBindingContext bindingContext)+90
System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext,ModelBindingContext bindingContext,Object model)+383
System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext,ModelBindingContext bindingContext)+1048
System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext)+280
System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext,ParameterDescriptor parameterDescriptor)+257
System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext,ActionDescriptor actionDescriptor)+109
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext,String actionName) +314 System.Web.Mvc.Controller.ExecuteCore() +105 System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)+39
System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(的RequestContext requestContext)+7
System.Web.Mvc&LT;&GT; c__DisplayClass8.b__4() +34 System.Web.Mvc.Async。&lt;&gt; c__DisplayClass1.b__0() +21 System.Web.Mvc.Async。&lt;&gt; c__DisplayClass81.<BeginSynchronous>b__7(IAsyncResult _) +12 System.Web.Mvc.Async.WrappedAsyncResult
1.End() +59 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult) asyncResult)+44
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult的 结果)+7
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8678910 System.Web.HttpApplication.ExecuteStep(IExecutionStep 步,布尔&amp; completedSynchronously) 155
答案 0 :(得分:5)
不能将[StringLength]用于String以外的类型的属性。如果要复制功能,可以继承StringLengthAttribute:
public class MyCoolAttribute : StringLengthAttribute {
// constructor here
public override bool IsValid(object value) {
return base.IsValid((string)(value as MyObject));
}
}
然后在你的财产上拍[MyCool]而不是[StringLength]。在这方面使用演员可能不是世界上最干净的东西;你可能应该使用ToString()或类似的东西。但这个想法是一样的。
或者,如果您不想继承StringLengthAttribute,则可以代之以委托私有StringLengthAttribute实例的IsValid()方法。