无效的强制转换异常,即使我定义了隐式强制转换运算符(在asp mvc app中)

时间:2010-01-04 00:51:22

标签: asp.net-mvc asp.net-mvc-2 implicit-cast implicit-conversion

我创建了一个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__DisplayClass8 1.<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

1 个答案:

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