Invaid cast exception, even when I have an implicit cast operator defined (in asp mvc app)
I have an mvc model class created and one of the properties is of type 'MyObject'. It also has a System.ComponentModel.DataAnnotations.StringLength attribute on it.
MyObject as implicit cast operators so it can essentially be used as a string:
public static implicit operator string(MyObject o){...}
public static implicit operator MyObject(string sValue){...}
Is this an asp mvc issue for some strange reason? I ask because I know in most cases the implicit cast works fine, I can for example assign that property to a string value and it works just fine.
Edit - Ok, I know why the error is occuring:
It's because the StringLength.IsValid() method takes an object as a parameter, so the cast is actually going from object to string, not f开发者_运维百科rom MyObject to string, so that explains why my implicit cast operator is not being called. But how to work around this?This all worked fine until I put the System.ComponentModel.DataAnnotations.StringLength attribute on the property in my model, then when the view does a post from a submit button, I got the exception:
[InvalidCastException: Unable to cast object of type 'StrataSpot.Shared.Models.Email' to type 'System.String'.]
System.ComponentModel.DataAnnotations.StringLengthAttribute.IsValid(Object value) +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.<>c__DisplayClass8.b__4() +34 System.Web.Mvc.Async.<>c__DisplayClass1.b__0() +21 System.Web.Mvc.Async.<>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 result) +7 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8678910 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
You can't use [StringLength] for a property of a type other than String. If you want to duplicate the functionality, you can subclass StringLengthAttribute:
public class MyCoolAttribute : StringLengthAttribute {
// constructor here
public override bool IsValid(object value) {
return base.IsValid((string)(value as MyObject));
}
}
Then slap [MyCool] instead of [StringLength] on your property. Using a cast operator in this regard probably isn't the cleanest thing in the world; you should probably use ToString() or something similar instead. But the idea is the same.
Alternatively, if you don't want to subclass StringLengthAttribute, you can just delegate to a private StringLengthAttribute instance's IsValid() method instead.
精彩评论