3

我创建了一个 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, 对象模型) +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.<>c__DisplayClass8.b__4() +34 System.Web.Mvc.Async.<>c__DisplayClass1.b__0() + 21 System.Web.Mvc.Async.<>c__DisplayClass8 1.<BeginSynchronous>b__7(IAsyncResult _) +12 System.Web.Mvc.Async.WrappedAsyncResult1.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 step, Boolean& completedSynchronously) +155

4

1 回答 1

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() 方法。

于 2010-01-04T06:21:49.930 回答