3

J'ai une classe de modèle mvc créée et l'une des propriétés est de type 'MyObject'. Il possède également un attribut System.ComponentModel.DataAnnotations.StringLength.Exception de transtypage invaid, même si j'ai un opérateur de distribution implicite défini (dans l'application asp mvc)

MyObject que les opérateurs de la distribution implicite de sorte qu'il peut être utilisé essentiellement comme une chaîne:

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

Est-ce un problème de asp mvc pour une raison étrange? Je demande parce que je sais que dans la plupart des cas la distribution implicite fonctionne bien, je peux par exemple assigner cette propriété à une valeur de chaîne et cela fonctionne très bien.

Edition - Ok, je sais pourquoi l'erreur est INTERVENUES:
C'est parce que la méthode StringLength.IsValid() prend un objet en tant que paramètre, de sorte que la distribution va en fait d'un objet à chaîne, pas de MyObject chaîne, ce qui explique pourquoi mon opérateur de distribution implicite n'est pas appelé. Mais comment travailler autour de cela?

Tout cela a bien fonctionné jusqu'à ce que je mets l'attribut System.ComponentModel.DataAnnotations.StringLength sur la propriété dans mon modèle, puis lorsque la vue fait un poste d'un bouton d'envoi, je suis arrivé à l'exception:

[InvalidCastException: incapable de lancer objet de type 'StrataSpot.Shared.Models.Email' à type 'System.String'.]
System.ComponentModel.DataAnnotations.StringLengthAttribute.IsValid (Object valeur ) 34
System.Web.Mvc.d__1.MoveNext() 56 System.Web.Mvc.DefaultModelBinder.OnPropertyValidated (ControllerContext ControllerContext, ModelBindingContext BindingContext, PropertyDescriptor PropertyDescriptor, la valeur de l'objet) 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, le modèle de l'objet) 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.GetParameterVal ues (ControllerContext ControllerContext, ActionDescriptor ActionDescriptor) 109
System.Web.Mvc.ControllerActionInvoker.InvokeAction (ControllerContext ControllerContext, String actionName) 314 System.Web.Mvc.Controller.ExecuteCore() 105 système. Web.Mvc.ControllerBase.Exécuter (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.WrappedAsyncResult 1.End() 59 System.Web.Mvc.MvcHandler.EndProcessRequest (IAsyncResult asyncResult) 44
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest (suite IAsyncResult ) 7
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 8678910 System.Web.HttpApplication.ExecuteStep (IExecutionStep étape, Boolean & completedSynchronously) +155

Répondre

5

Vous ne peut pas utiliser [StringLengt h] pour une propriété d'un type autre que String. Si vous souhaitez dupliquer la fonctionnalité, vous pouvez sous-classe StringLengthAttribute:

public class MyCoolAttribute : StringLengthAttribute { 
    // constructor here 

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

gifle alors [MyCool] au lieu de [StringLength] sur votre propriété. L'utilisation d'un opérateur de casting à cet égard n'est probablement pas la chose la plus propre au monde; vous devriez probablement utiliser ToString() ou quelque chose de similaire à la place. Mais l'idée est la même.

Alternativement, si vous ne voulez pas sous-classer StringLengthAttribute, vous pouvez simplement déléguer à la méthode IsValid() d'une instance privée de StringLengthAttribute à la place.