web-dev-qa-db-fra.com

Message de validation "Le champ Id est requis" sur Créer; L'identifiant n'est pas défini sur [Obligatoire]

Cela se produit lorsque j'essaie de créer l'entité à l'aide d'une action Créer un style dans Asp.Net MVC 2.

Le POCO a les propriétés suivantes:

public int Id {get;set;}

[Required]
public string Message {get; set}

Lors de la création de l'entité, l'ID est défini automatiquement, il n'est donc pas nécessaire pour l'action Créer.

Le ModelState dit que "Le champ Id est obligatoire", mais je ne l'ai pas défini comme tel. Y at-il quelque chose d'automatique qui se passe ici?

EDIT - Reason Revealed

Brad Wilson, par l’intermédiaire de Paul Speranza, a répondu à la question, dans l’un des commentaires ci-dessous, où il dit (acclamait Paul): 

Vous fournissez une valeur pour ID, tu ne savais pas que tu étais . C'est dans les données de route de la valeur par défaut route ("{contrôleur}/{action}/{id}"), et sa valeur par défaut est vide chaîne, qui n'est pas valide pour un int . Utilisez l'attribut [Bind] sur votre paramètre d'action à exclure ID. Ma La route par défaut était: new {controller = "Client", action = "Modifier", id = "" } // Paramètres par défaut

EDIT - Technique de mise à jour de modèle

En fait, j'ai changé la façon dont je l'ai fait à nouveau en utilisant TryUpdateModel et le tableau de paramètres d'exclusion associé à cela. 

    [HttpPost]
    public ActionResult Add(Venue collection)
    {
        Venue venue = new Venue();
        if (TryUpdateModel(venue, null, null, new[] { "Id" }))
        {
            _service.Add(venue);
            return RedirectToAction("Index", "Manage");
        }
        return View(collection);
    }
68
Dann

Vous pouvez ajouter l'attribut:

 [Bind(Exclude = "Id")] 

sur le paramètre dans la méthode plutôt que sur la classe, de cette façon sur create, vous pouvez l'exclure et sur edit, il sera toujours obligatoire:

public ActionResult Create([Bind(Exclude = "Id")] User u)
{
    // will exclude for create
}

public ActionResult Edit(User u)
{
    // will require for edit
}
85
Rosstified

J'ai rencontré ce problème avec un formulaire dans lequel j'ajoutais des "objets" à une liste de manière dynamique. Par conséquent, nos utilisateurs ont pu ajouter, supprimer ou mettre à jour. Tout a bien fonctionné, sauf dans les cas où de nouveaux éléments ont été créés. Pour cette raison, dans mon cas, exclure la propriété Id n'était pas une option . La solution consistait à rendre l'ID Nullable :

public int? Id { get; set; }

De cette façon, les éléments existants auront une valeur et les nouveaux auront la valeur null. Bon produit.

18
Ulises

Excellente question et réponses, sauvé ma ... derrière. J'ai besoin d'ajouter quelque chose, cependant:

Au lieu de 

[Bind(Exclude = "Id")]

Je pense qu'il vaut mieux utiliser

[Bind(Include = "Prop1, Prop2, Prop3, etc")]

.. où Prop1, Prop2 et Prop3 sont les propriétés THE THE ONLY que vous souhaitez lier au niveau action.

Puisqu'il s'agit d'une liste blanche par opposition à une liste noire. La liste blanche est meilleure, plus sûre. De cette façon, vous résolvez aussi le risque de poster et de poster. Voir Le message de Brad Wilson .

11
Andrei Rînea
[Bind(Exclude = "Id")]
public class Hebe
{
      public int Id {get;set;}

      [Required]
      public string Message {get; set}
}

En passant, il ne lie pas la propriété Id de votre modèle lors de la création.

7
Barbaros Alp

L'identifiant doit être envoyé à partir du client sous la forme 0 . Le modèle n'a pas de problème avec Id = 0, il s'agit du paramètre par défaut de int . Le problème est qu'il ne voit pas la valeur provenant du client. ou il vient avec espace ou null . J'ai une entrée cachée qui représente l'Id (ou dans l'objet complexe NestedPropertyId/NestedProperty.Id) alors je m'assure qu'il commence par une valeur de zéro.

<input type="hidden" id="id" value="0" />
<input type="hidden" id="eventId" value="0"/>
<input type="hidden" id="contactId" value="0"/>

De même, lorsque je crée le formulaire pour ajouter une nouvelle entité du côté client, je m'assure d'initialiser le masqué avec zéro.

J'espère que cela aide quelqu'un.

Efy

6
user1911353

Vérifiez à votre vue. Supprimer si vous avez un champ hiddenfieldfor id. Ceci est utilisé uniquement pour l'édition. @ Html.HiddenFor (Model => Model.Id)

2
Than Aramburo

J'ai le même problème, en utilisant RC2 avec un POCO. Si vous nommez un identifiant de propriété mais ne lui attribuez pas d'attributs de validation, IsValid indique qu'il est obligatoire. Si je nomme une propriété autre chose que Id, cela ne se produit pas. Pourquoi devrais-je exclure Id?

Merci

2
Paul Speranza

ajouter ? à int 

[Key]
[HiddenInput(DisplayValue = false)]
public int? ID { get; set; }
2
andreydruz

Je viens de créer un nouveau projet MVC2 et d’ajouter un simple POCO ainsi qu’un contrôleur et une vue. D'après ce que j'ai compris, vous utilisez la liaison de modèle pour créer l'objet, c'est-à-dire

using System.ComponentModel.DataAnnotations;
public class SimpleObject
{
    public int Id {get;set;}
    [Required]
    public string Message { get; set; }
}

dans le contrôleur nous avons

[HttpPost]
public ActionResult Create(SimpleObject created)
{
    /// do something
}

et dans la vue, il n'y a pas d'éditeur pour le champ ID?

Cela ne devrait pas se retrouver dans des messages d'erreur. Au lieu de cela, l'ID est censé être défini sur la valeur par défaut (int), qui est 0. Cela fonctionne pour moi. Quelle version de MVC2 utilisez-vous (la RC, je suppose)?

Ne vous méprenez pas: il est important d'empêcher l'Id d'être lié par les classeurs de modèles, car cela permettrait à un attaquant de falsifier l'identifiant de l'objet. Néanmoins, le classeur de modèle par défaut ne doit pas afficher le comportement que vous décrivez.

1
mnemosyn

Dans mon cas, le problème venait du fait qu’ID était de type string. Le passage à int (non nullable) l’a corrigé. Le type string est le résultat de l'ingénierie inverse d'une base de données mal conçue. 

1
PBG

J'ai également rencontré le même problème avec vous et maintenant, j'ai déjà résolu ce problème . Tel que

[HttpGet]
public ActionResult Add()
{
    //Your code here
    return View(new Venue);
}

J'espère que cela vous sera utile.

0
user3717418

Les réponses ci-dessus sont correctes. Quelle que soit la façon dont chacun suit un scénario différent. Ma solution est la suivante pour le même problème . Si votre ID est une clé primaire, vous devez l’initialiser. nouvel objet devant elle. Il définira 0 sur votre ID au lieu de null.

0
Geeti

J'ai eu le même problème, sauf que j'avais trois champs de nombre entier sur mon modèle. J'ai réussi à contourner le problème en définissant toutes les propriétés de mon entier requises par erreur en nullable.

0
kmehta

Vous pouvez désactiver cette validation implicite en définissant l'option AddImplicitRequiredAttributeForValueTypes sur DataAnnotationsModelValidatorProvider en ajoutant ce qui suit à votre Application_Start:

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

Lectures supplémentaires:

0
KyleMit

J'ai eu le même problème et j'ai réussi à le résoudre en passant simplement une instance vide du modèle de vue à la vue pendant l'appel GET de ma méthode Create.

//GET: DocumentTypes/{Controller}/Create
    public ActionResult Create()
    {
        return View(new DocumentTypeViewModel());
    }

    //POST: DocumentTypes/{Controller}/Create
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(DocumentTypeViewModel viewModel)
    {
        if(ModelState.IsValid) {

            var result = AddDocumentType(viewModel);
            if(!result.HasValidationErrors) {
                return RedirectToAction("Index");
            }

            ModelState.Update(result);

        }

        return View(viewModel);
    }

Et puis à mon avis, je m'assure d'avoir

@Html.HiddenFor(m => m.ID)

De cette façon, je n'ai pas à spécifier explicitement les attributs Bind

0
jspaey