bind attributo include ed esclude proprietà con oggetti nidificati di tipo complesso
-
29-10-2019 - |
Domanda
Ok, questo è strano.Non riesco a utilizzare le proprietà BindAttribute
e Include
di Exclude
con oggetti nidificati di tipo complesso su ASP.NET MVC.
Ecco cosa ho fatto:
<”Modello:
public class FooViewModel {
public Enquiry Enquiry { get; set; }
}
public class Enquiry {
public int EnquiryId { get; set; }
public string Latitude { get; set; }
}
Azione HTTP POST:
[ActionName("Foo"), HttpPost]
public ActionResult Foo_post(
[Bind(Include = "Enquiry.EnquiryId")]
FooViewModel foo) {
return View(foo);
}
<”Visualizza:
@using (Html.BeginForm()) {
@Html.TextBoxFor(m => m.Enquiry.EnquiryId)
@Html.TextBoxFor(m => m.Enquiry.Latitude)
<input type="submit" value="push" />
}
Non funziona affatto.Posso farlo funzionare solo se definisco il BindAttribute
per la classe Enquiry
come indicato qui:
Come si usa [Bind(Include="")] attributo su oggetti nidificati complessi?
Soluzione
Sì, puoi farlo funzionare così:
[Bind(Include = "EnquiryId")]
public class Enquiry
{
public int EnquiryId { get; set; }
public string Latitude { get; set; }
}
e la tua azione:
[ActionName("Foo"), HttpPost]
public ActionResult Foo_post(FooViewModel foo)
{
return View(foo);
}
Questo includerà solo il EnquiryId
nell'associazione e lascerà il Latitude
nullo.
Detto questo, l'utilizzo dell'attributo Bind non è qualcosa che ti consiglierei.Il mio consiglio è di utilizzare i modelli di visualizzazione.All'interno di questi modelli di visualizzazione includi solo le proprietà che hanno senso per questa particolare visualizzazione.
Quindi riadatta semplicemente i tuoi modelli di visualizzazione:
public class FooViewModel
{
public EnquiryViewModel Enquiry { get; set; }
}
public class EnquiryViewModel
{
public int EnquiryId { get; set; }
}
Ecco fatto.Non devi più preoccuparti dell'associazione.
Altri suggerimenti
IMHO esiste un modo migliore per farlo.
Essenzialmente se hai più modelli nel modello di visualizzazione, la firma del controller del post conterrebbe gli stessi modelli, al contrario del modello di visualizzazione.
Cioè
public class FooViewModel {
public Bar BarV { get; set; }
public Enquiry EnquiryV { get; set; }
public int ThisNumber { get; set; }
}
public class Bar {
public int BarId { get; set; }
}
public class Enquiry {
public int EnquiryId { get; set; }
public string Latitude { get; set; }
}
E l'azione post nel controller sarebbe simile a questa.
[ActionName("Foo"), HttpPost]
public ActionResult Foo_post(
[Bind(Include = "EnquiryId")]
Enquiry EnquiryV,
[Bind(Include = "BarId"])]
Bar BarV,
int ThisNumber
{
return View(new FooViewModel { Bar = BarV, Enquiry = EnquiryV, ThisNumber = ThisNumber });
}
Il tutto mentre la visualizzazione è ancora così
@using (Html.BeginForm()) {
@Html.TextBoxFor(m => m.EnquiryV.EnquiryId)
@Html.TextBoxFor(m => m.EnquiryV.Latitude)
@Html.TextBoxFor(m => m.BarV.BarId)
@Html.TextBoxFor(m => m.ThisNumber)
<input type="submit" value="push" />
}
Tieni presente che questo modulo invierà ancora Latitude (nel modo in cui l'avevi impostato), tuttavia poiché non è incluso nella stringa Bind Include per Inquiry sull'azione del post, l'azione non accetterà il nuovo valore nella risultante inchiesta. Suggerirei di rendere la latitudine disabilitata o non un elemento del modulo per evitare ulteriori dati di pubblicazione.
In qualsiasi altro scenario puoi usare bind benissimo, ma per qualche motivo non piace la notazione del punto per i modelli complessi.
Come nota a margine, non metterei l'attributo bind direttamente sulla classe in quanto può causare altri problemi come la replica del codice e non tiene conto di determinati scenari in cui potresti voler avere un binding diverso.
(Ho modificato i nomi delle variabili per maggiore chiarezza. Sono anche consapevole che la tua domanda è piuttosto datata, tuttavia nella ricerca della risposta da solo questo è il primo SO in cui mi sono imbattuto prima di provare le mie soluzioni e arrivare a quella che ho pubblicato . Spero che possa aiutare altre persone che cercano una soluzione allo stesso problema.)