Domanda

Ho un modello mvc classe creata e una delle proprietà è di tipo 'MyObject'.Essa ha anche un Sistema.ComponentModel.DataAnnotations.StringLength attributo.

MyObject come cast implicito operatori, in modo che essenzialmente può essere usato come una stringa:

public static implicit operator string(MyObject o){...}
public static implicit operator MyObject(string sValue){...}

È questo un asp mvc problema per qualche strano motivo?Lo chiedo perchè so che nella maggior parte dei casi il cast implicito funziona bene, posso per esempio assegnare la proprietà per un valore di stringa e funziona bene.

Edit - Ok, lo so perché l'errore è in corso:
Perché il StringLength.Metodo IsValid() accetta un oggetto come parametro, in modo che il cast è in realtà andando da oggetto stringa, non da MyObject di stringa, in modo che spiega perché il mio cast implicito operatore non viene chiamato.Ma come ovviare a questo?

Tutto questo ha funzionato bene fino a quando ho messo il Sistema.ComponentModel.DataAnnotations.StringLength attributo di proprietà nel mio modello, poi quando la vista fa un post di un pulsante di invio, ho avuto l'eccezione:

[InvalidCastException:Impossibile eseguire il cast di oggetto di tipo 'StrataSpot.Comune.Modelli.E-mail' a tipo 'System.String'.]
Sistema.ComponentModel.DataAnnotations.StringLengthAttribute.IsValid(Oggetto valore) +34
Sistema.Web.Mvc.d__1.MoveNext() +56 del Sistema.Web.Mvc.DefaultModelBinder.OnPropertyValidated(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, Object value) +203 Sistema.Web.Mvc.DefaultModelBinder.BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) +413
Sistema.Web.Mvc.DefaultModelBinder.BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) +90
Sistema.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Object model) +383
Sistema.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +1048
Sistema.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +280
Sistema.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +257
Sistema.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +109
Sistema.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +314 Sistema.Web.Mvc.Controller.ExecuteCore() +105 del Sistema.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +39
Sistema.Web.Mvc.ControllerBase.Sistema.Web.Mvc.IController.Execute(RequestContext requestContext) +7
Sistema.Web.Mvc.<>c__DisplayClass8.b__4() +34 del Sistema.Web.Mvc.Async.<>c__DisplayClass1.b__0() +21 Sistema.Web.Mvc.Async.<>c__DisplayClass81.<BeginSynchronous>b__7(IAsyncResult _) +12 System.Web.Mvc.Async.WrappedAsyncResult1.Fine() +59 del Sistema.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +44
Sistema.Web.Mvc.MvcHandler.Sistema.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult il risultato) +7
Sistema.Web.CallHandlerExecutionStep.Sistema.Web.HttpApplication.IExecutionStep.Execute() +8678910 Sistema.Web.HttpApplication.ExecuteStep(IExecutionStep passo, Boolean& completedSynchronously) +155

È stato utile?

Soluzione

Non è possibile utilizzare [StringLength] per una proprietà di un tipo diverso da una Stringa.Se si desidera duplicare le funzionalità, è possibile creare una sottoclasse StringLengthAttribute:

public class MyCoolAttribute : StringLengthAttribute {
  // constructor here

  public override bool IsValid(object value) {
    return base.IsValid((string)(value as MyObject));
  }
}

Quindi schiaffo [MyCool] invece di [StringLength] sulla vostra proprietà.Utilizzando un operatore di cast, a questo proposito, probabilmente non è la cosa più pulita del mondo;probabilmente si dovrebbe utilizzare il metodo ToString() o qualcosa di simile.Ma l'idea è la stessa.

In alternativa, se non si desidera creare una sottoclasse StringLengthAttribute, è possibile delegare al privato StringLengthAttribute istanza del metodo IsValid (), invece.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top