Dies geschieht, wenn ich versuche, die Entität mithilfe einer Aktion zum Erstellen eines Stils in Asp.Net MVC 2 zu erstellen.
Der POCO hat folgende Eigenschaften:
public int Id {get;set;}
[Required]
public string Message {get; set}
Beim Erstellen der Entität wird die ID automatisch festgelegt, sodass sie für die Aktion "Erstellen" nicht erforderlich ist.
Der ModelState sagt, dass "Das ID-Feld erforderlich ist", aber ich habe das nicht so eingestellt. Ist hier etwas Automatisches los?
EDIT - Grund enthüllt
Der Grund für das Problem wird von Brad Wilson über Paul Speranza in einem der folgenden Kommentare beantwortet, in denen er sagt (Prost Paul):
Sie geben einen Wert für ID an, Sie wussten nur nicht, dass Sie es sind. Es befindet sich in den Routendaten der Standardroute ("{controller} / {action} / {id}") und der Standardwert ist die leere Zeichenfolge, die für ein int nicht gültig ist. Verwenden Sie das Attribut [Bind] für Ihren Aktionsparameter, um die ID auszuschließen. Meine Standardroute war: new {controller = "Customer", action = "Edit", id = ""} // Standardwerte für Parameter
BEARBEITEN - Modelltechnik aktualisieren
Ich habe die Art und Weise, wie ich dies erneut tat, tatsächlich geändert, indem ich TryUpdateModel und das damit verbundene Array mit den Ausschlussparametern verwendet habe.
[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);
}
Antworten:
Sie können das Attribut hinzufügen:
[Bind(Exclude = "Id")]
Wenn Sie den Parameter in method anstelle der Klasse verwenden, können Sie ihn beim Erstellen ausschließen, und beim Bearbeiten ist er weiterhin obligatorisch:
public ActionResult Create([Bind(Exclude = "Id")] User u) { // will exclude for create } public ActionResult Edit(User u) { // will require for edit }
quelle
Ajax.BeginForm()
Daten gepostet . Wie gehe ich beim Speichern / Aktualisieren mit einer einzigen Schaltfläche mit zwei verschiedenen Aktionsmethoden um?Ich bin auf dieses Problem mit einem Formular gestoßen, in dem ich einer Liste dynamisch "Objekte" hinzugefügt habe. Daher konnten unsere Benutzer hinzufügen, entfernen oder aktualisieren. Es hat alles gut funktioniert, bis auf die Fälle, in denen neue Elemente erstellt wurden. Aus diesem Grund war in meinem Fall das Ausschließen der Id-Eigenschaft keine Option . Die Lösung bestand darin, die ID auf Null zu setzen :
public int? Id { get; set; }
Auf diese Weise haben vorhandene Elemente einen Wert und neue Elemente haben stattdessen null. Gutes Zeug.
quelle
Tolle Fragen und Antworten, rettete meinen ... Hintern. Ich muss jedoch etwas hinzufügen:
Anstatt
[Bind(Exclude = "Id")]
Ich denke, es ist besser zu verwenden
[Bind(Include = "Prop1, Prop2, Prop3, etc")]
.. wobei Prop1, Prop2 und Prop3 DIE EINZIGEN Eigenschaften sind, die Sie auf Aktionsebene binden möchten.
Da dies eine weiße Auflistung im Gegensatz zu einer schwarzen Auflistung ist. White-Listing ist besser und sicherer. Auf diese Weise lösen Sie auch das Risiko von Über- und Unterbuchungen. Siehe Brad Wilsons Beitrag .
quelle
[Bind(Exclude = "Id")] public class Hebe { public int Id {get;set;} [Required] public string Message {get; set} }
Übrigens bindet es die ID-Eigenschaft für Ihr Modell beim Erstellen nicht
quelle
Ajax.BeginForm()
Daten gepostet . Wie gehe ich beim Speichern / Aktualisieren mit einer einzigen Schaltfläche mit zwei verschiedenen Aktionsmethoden um?Die ID sollte vom Client als 0 gesendet werden. Das Modell hat kein Problem mit Id = 0, dies ist die Standardeinstellung von int. Das Problem ist, dass er den vom Client kommenden Wert nicht sieht oder er mit Leerzeichen oder Null kommt. Ich habe eine Eingabe ausgeblendet, die die ID darstellt (oder in einem komplexen Objekt NestedPropertyId / NestedProperty.Id), daher stelle ich sicher, dass sie mit dem Wert Null beginnt.
<input type="hidden" id="id" value="0" /> <input type="hidden" id="eventId" value="0"/> <input type="hidden" id="contactId" value="0"/>
Auch wenn das Formular so eingestellt wird, dass auf der Clientseite eine neue Entität hinzugefügt wird, muss das versteckte Objekt mit Null initialisiert werden.
Hoffe das hilft jemandem.
Efy
quelle
Ich habe das gleiche Problem mit RC2 mit einem POCO. Wenn Sie eine Eigenschafts-ID benennen, aber keine Validierungsattribute darauf setzen, IsValid jedoch angibt, dass dies erforderlich ist. Wenn ich einer Eigenschaft etwas anderes als ID nenne, geschieht dies nicht. Warum sollte ich die ID ausschließen müssen?
Vielen Dank
quelle
hinzufügen ? zu int
[Key] [HiddenInput(DisplayValue = false)] public int? ID { get; set; }
quelle
Überprüfen Sie Ihre Ansicht. Entfernen Sie, wenn Sie ein Feld für ID versteckt haben. Dies wird nur zum Bearbeiten verwendet. @ Html.HiddenFor (Model => Model.Id)
quelle
Ich habe gerade ein neues MVC2-Projekt erstellt und einen einfachen POCO sowie einen Controller und eine Ansicht hinzugefügt. Soweit ich weiß, verwenden Sie die Modellbindung, um das Objekt zu erstellen
using System.ComponentModel.DataAnnotations; public class SimpleObject { public int Id {get;set;} [Required] public string Message { get; set; } }
im Controller haben wir
[HttpPost] public ActionResult Create(SimpleObject created) { /// do something }
und in der Ansicht gibt es keinen Editor für das ID-Feld?
Dies sollte nicht zu Fehlermeldungen führen. Stattdessen sollte die ID auf den Standardwert (int) gesetzt werden, der 0 ist. Dies funktioniert bei mir. Welche Version von MVC2 verwenden Sie (die RC nehme ich an)?
Verstehen Sie mich nicht falsch: Es ist wichtig zu verhindern, dass die ID an die Modellbinder gebunden wird, da ein Angreifer dadurch die ID des Objekts manipulieren kann. Der Standardmodellordner sollte jedoch nicht das von Ihnen beschriebene Verhalten anzeigen.
quelle
In meinem Fall war das Problem darauf zurückzuführen, dass es sich um eine ID handelte
string
. Der Wechsel zu einemint
(nicht nullbaren) Fehler wurde für mich behoben. Derstring
Typ war das Ergebnis des Reverse Engineering einer schlecht gestalteten Datenbank.quelle
Ich hatte das gleiche Problem, außer dass ich drei ganzzahlige Felder in meinem Modell hatte. Ich habe es geschafft, es zu umgehen, indem ich alle meine ganzzahligen Eigenschaften, die fälschlicherweise benötigt wurden, auf nullbare Ints gesetzt habe.
quelle
Die obigen Antworten sind richtig. Wie jeder einem anderen Szenario folgt. Meine Lösung lautet für dasselbe Problem wie folgt. Wenn Ihre ID ein Primärschlüssel ist, müssen Sie ihn initiieren. Ich meine, wenn Sie das Modell übergeben, um es in der get-Methode anzuzeigen, erstellen Sie einfach ein neues Objekt davor. Es wird 0 auf Ihre ID anstatt auf Null gesetzt.
quelle
Ich hatte das gleiche Problem und konnte es lösen, indem ich während des GET-Aufrufs meiner Create-Methode einfach eine leere Instanz des Ansichtsmodells an die Ansicht übergab.
//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); }
Und dann stelle ich aus meiner Sicht sicher, dass ich habe
@Html.HiddenFor(m => m.ID)
Auf diese Weise muss ich keine Bindungsattribute explizit angeben
quelle
Ich hatte auch das gleiche Problem mit Ihnen und jetzt habe ich dieses Problem bereits gelöst. Mit HttpGet müssen Sie ein Modell zurückgeben, das leer ist. Sowie
[HttpGet] public ActionResult Add() { //Your code here return View(new Venue); }
Ich hoffe es ist nützlich für dich.
quelle
Sie können diese implizite Validierung deaktivieren, indem Sie die
AddImplicitRequiredAttributeForValueTypes
Option auf setzen,DataAnnotationsModelValidatorProvider
indem Sie Folgendes zu Ihrem hinzufügenApplication_Start
:DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
Weiterführende Literatur :
quelle
Bevor Sie ModelState.IsValid überprüfen, entfernen Sie 'Id' aus ModelState.
ModelState.Remove("Id");
quelle