Question

Edit: prime Ajouté parce que je suis à la recherche d'une solution MVC3 (le cas échéant) autre que ceci:

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;


J'ai lu que la propriété sur mon modèle « Adresse » 'CityStateZip'.

Il est juste un moyen pratique d'obtenir ville, état, code postal d'une adresse américaine. Il lève une exception si le pays n'est pas Etats-Unis (l'appelant est censé vérifier d'abord).

    public string CityStateZip
    {
        get
        {
            if (IsUSA == false)
            {
                throw new ApplicationException("CityStateZip not valid for international addresses!");
            }

            return (City + ", " + StateCd + " " + ZipOrPostal).Trim().Trim(new char[] {','});
        }
    }

Cela fait partie de mon modèle il se lie. Avant ASP.NET MVC2 RC2 ce domaine n'a jamais causé un problème lors de la liaison de données. Je ne ai jamais vraiment pensé à ce sujet -. Après tout, ce n'est en lecture seule

Maintenant, si avec la version RC2 Janvier 2010, il me donne une erreur lors de la liaison de données -. Becasue le liant modèle par défaut semble vouloir vérifier cette valeur (même si elle est en lecture seule)

Il est la ligne « base.OnModelUpdated » qui provoque cette erreur à déclencher.

public class AddressModelBinder : DefaultModelBinder
{
    protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        base.OnModelUpdated(controllerContext, bindingContext);

Les changements de dernière minutes au ModelBinder évidemment provoqué ce changement de comportement - mais je ne suis pas tout à fait sûr encore ce que les repurcussions de celui-ci sont - ou si c'est un bug? Je passe ce message à l'équipe MVC, mais curieux de savoir si quelqu'un a d'autre des suggestions en attendant que je peux empêcher cette propriété de se lier.

Cet article mérite d'être lu sur les changements - mais ne mentionne pas les propriétés en lecture seule du tout (pas que j'attendre à). La question (si elle existe) peut être plus large que cette situation - je ne suis pas sûr de tout repurcussions - le cas échéant

validation des entrées vs validation de modèle dans ASP.NET MVC


Comme l'a demandé @haacked voici le stacktrace:

Je reçois en ajoutant simplement la ligne suivante à tout modèle et faire un poste à la méthode d'action correspondante. Dans ce cas, je l'ai ajouté à mon modèle le plus simple possible.

 public string Foo { get { throw new Exception("bar"); } }
  

[TargetInvocationException: accesseur de propriété 'Foo' sur l'objet 'Rolling_Razor_MVC.Models.ContactUsModel' a jeté l'exception suivante: 'bar']      System.ComponentModel.ReflectPropertyDescriptor.GetValue (composant Object) 390      System.Web.Mvc. <> C__DisplayClassb. B__a de () +18      System.Web.Mvc.ModelMetadata.get_Model () 22      System.Web.Mvc.ModelMetadata.get_RealModelType () 29      System.Web.Mvc. d__0.MoveNext () +38      System.Linq. d__14`2.MoveNext () + 273      System.Web.Mvc. d__5.MoveNext () +644      System.Web.Mvc.DefaultModelBinder.OnModelUpdated (ControllerContext ControllerContext, ModelBindingContext BindingContext) 92      System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel (ControllerContext ControllerContext, ModelBindingContext BindingContext, modèle d'objet) 60      System.Web.Mvc.DefaultModelBinder.BindComplexModel (ControllerContext ControllerContext, ModelBindingContext BindingContext) 1048      System.Web.Mvc.DefaultModelBinder.BindModel (ControllerContext ControllerContext, ModelBindingContext BindingContext) 280      System.Web.Mvc.Controller.TryUpdateModel (modèle TModel, préfixe String, String [] includeProperties, String [] excludeProperties, IValueProvider valueProvider) +449      System.Web.Mvc.Controller.TryUpdateModel (modèle TModel) 73

Était-ce utile?

La solution

Je crois que je rencontre un problème similaire. J'ai posté les détails:

http://forums.asp.net/t/1523362.aspx


modifier : Réponse de l'équipe MVC (ci-dessus URL):

Nous avons étudié cela et avons conclu que le système de validation se comporte comme prévu. Depuis la validation du modèle consiste à tenter d'exécuter la validation sur toutes les propriétés, et puisque les propriétés de type valeur non nullables ont un attribut implicite [Obligatoire], nous validons cette propriété et appelant sa getter dans le processus. Nous comprenons que ce changement est la rupture de V1 du produit, mais il est nécessaire de rendre le nouveau système de validation du modèle fonctionne correctement.

Vous avez quelques options pour contourner ce. Chacun de ces facteurs devrait fonctionner:

  • Modifier la propriété Date à une méthode au lieu d'une propriété; Ainsi, il sera ignoré par le framework MVC.
  • Modifier le type de propriété à DateTime? au lieu de DateTime. Cela supprime l'implicite [Obligatoire] de cette propriété.
  • Effacer le drapeau de DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes statique. Cela supprime l'implicite [Obligatoire] à partir de toutes les propriétés de type valeur non nulle à l'échelle application. Nous envisageons d'ajouter dans V3 du produit un attribut qui signalera à nous « ne se lient pas, ne pas valider, juste prétendre que cette propriété n'existe pas. »

Merci encore pour le rapport!

Autres conseils

ayant toujours le même problème avec MVC3.

Je pense que la meilleure façon est juste pour cela dans global.asax (de la réponse de SevenCentral):

 DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

Ceci désactivera pour tous

Cela ressemble à tout le monde comme un bug pour moi. Je ne comprends pas bien pourquoi le ModelBinder doit vérifier ma lecture de propriétés seulement (il peut y avoir des aspects techniques, mais je ne comprends pas vraiment, et je ne suis pas prêt à passer le temps à essayer de).

J'ajouté ce qui suit fournisseur du modèle de métadonnées pour ma solution pour contourner le problème

protected override CachedDataAnnotationsModelMetadata CreateMetadataPrototype(IEnumerable<Attribute> attributes, Type containerType, Type modelType, string propertyName)
{
    var metadata = base.CreateMetadataPrototype(attributes, containerType, modelType, propertyName);

    if (metadata.IsReadOnly)
    {
        metadata.IsRequired = false;
    }

    return metadata;
}

protected override CachedDataAnnotationsModelMetadata CreateMetadataFromPrototype(CachedDataAnnotationsModelMetadata prototype, Func<object> modelAccessor)
{
    var metadata = base.CreateMetadataFromPrototype(prototype, modelAccessor);

    if (prototype.IsReadOnly)
    {
        metadata.IsRequired = false;
    }

    return metadata;
}

Vous devrez également ajouter ce qui suit à Global.asax.cs

protected void Application_Start()
{
    ModelMetadataProviders.Current = new RESModelMetadataProvider();
    ModelBinders.Binders.Add(typeof(SmartDate), new SmartDateModelBinder());

    ...
}

Bien sûr, je suppose que je pourrais convertir CityStateZip à GetCityStateZip() mais je ne peux pas le lierai dans quelque chose comme silverlight tout aussi facilement. Cela pourrait fonctionner pour une solution temporaire pour tous ceux qui connaissent bien ce problème.

J'ai le même problème EXACT !!

Pour plus d'informations au sujet de mon problème, vous pouvez visiter ASP.NET MVC 2.0 Modèle inutilisé propriété être appelé lors de la publication d'un produit sur le serveur?

ce que cela signifie que nous devons programmer nos propriétés avec l'hypothèse selon laquelle ils seront appelés de façon inattendue (avant que les propriétés dont il dépend sont mis en place / etc initialisées) ... si oui, cela représente un changement dans nos pratiques de programmation et je voudrais savoir comment procéder.

En attendant, je suis juste un simple « si » vérifier que le problème débarrasse.

J'avais un problème similaire, un terrain que je ne pensais pas être validé recevait une erreur lorsque le formulaire affiché au contrôleur. Après quelques recherches sur Google, je suis tombé sur http://codeblog.shawson.co.uk/mvc-strongly-typed-view-returns-a-null-model-on-post-back/ où il a été souligné que les conflits de nom pourrait causer des problèmes.

Bien que je ne pensais pas que ma classe variable de post-retour étaient en conflit les noms de propriétés, de renommer la propriété recevoir l'erreur a résolu mon problème.

Le même problème existe toujours dans MVC 5.2.3, et il est même pas le code de validation qui cause le problème. Le DefaultModelBinder appelle les apporteurs en dehors de son code de validation, même si elles sont en lecture seule propriétés et même si aucune donnée de demande est transmise au contrôleur correspondant à ces propriétés.

Voir une explication plus détaillée et ma solution complète ici: https://stackoverflow.com/a/54431404/10987278.

Je ne sais pas si cette solution peut être refactorisé de travailler avec MVC 3, mais nous espérons qu'il peut aider les autres qui souffrent encore de la même question dans la version ultérieure de MVC qui a trébuché à travers cette question comme je l'ai fait.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top