Classeur d’object complexe et de modèle ASP.NET MVC

J’ai une structure d’object de modèle avec une classe Foo qui contient un Bar avec une valeur de chaîne.

 public class Foo { public Bar Bar; } public class Bar { public ssortingng Value { get; set; } } 

Et un modèle de vue qui utilise cette structure comme celle-ci

 public class HomeModel { public Foo Foo; } 

J’ai alors un formulaire en vue qui dans Razor ressemble à ceci.

  
@using (Html.BeginForm("Save", "Home", FormMethod.Post)) {
@Html.TextBoxFor(m => m.Foo.Bar.Value)
}

En html ça devient.

 

Enfin le contrôleur pour gérer les post-loos comme ceci

 [HttpPost] public ActionResult Save(Foo foo) { // Magic happends here return RedirectToAction("Index"); } 

Mon problème est que Bar dans Foo est null une fois que l’action de Save contrôleur a été effectuée ( Foo est créé mais avec un champ Bar null ).

Je pensais que le classeur de modèle dans MVC serait capable de créer les objects Foo et Bar et de définir la propriété Value tant qu’elle ressemble à ce qui est décrit ci-dessus. Qu’est-ce que je rate?

Je sais aussi que mon modèle de vue est un peu trop compliqué et pourrait être plus simple, mais je voudrais vraiment m’aider si je pouvais utiliser la structure d’object plus profonde. Les exemples ci-dessus utilisent ASP.NET 5.

Tout d’abord, DefaultModelBinder ne sera pas DefaultModelBinder à des champs, vous devez donc utiliser des propriétés.

 public class HomeModel { public Foo Foo { get; set; } } 

Deuxièmement, les assistants génèrent des contrôles basés sur HomeModel mais vous HomeModel à nouveau sur Foo . Soit changer la méthode POST pour

 [HttpPost] public ActionResult Save(HomeModel model) 

ou utilisez l’ BindAtsortingbute pour spécifier le Prefix (qui BindAtsortingbute essentiellement la valeur du préfixe des valeurs publiées – afin que Foo.Bar.Value devienne Bar.Value aux fins de la liaison).

 [HttpPost] public ActionResult Save([Bind(Prefix="Foo")]Foo model) 

Notez également que vous ne devez pas nommer le paramètre de méthode avec le même nom que l’une de vos propriétés, sinon la liaison échouera et votre modèle sera null.

Je viens de découvrir une autre raison qui peut arriver, c’est-à-dire si votre propriété s’appelle Settings ! Considérez le modèle de vue suivant:

 public class SomeVM { public SomeSettings DSettings { get; set; } // named this way it will work public SomeSettings Settings { get; set; } // property named 'Settings' won't bind! public bool ResetToDefault { get; set; } } 

En code, si vous vous liez à la propriété Settings , la liaison échouera (pas seulement sur post mais même lors de la génération du formulaire). Si vous renommez Settings en DSettings (etc.), cela fonctionne à nouveau soudainement.

J’ai eu le même problème et après avoir suivi les étapes de @Stephen Muecke, j’ai réalisé que le problème était dû au fait que mes entrées étaient désactivées (je les désactivais avec JQuery sur le document prêt), comme vous pouvez le voir ici: Comment envoyer des entrées désactivées dans ASP.NET MVC? . À la fin, j’ai utilisé l’atsortingbut désactivé en lecture seule au lieu de l’atsortingbut désactivé et toutes les valeurs ont été envoyées avec succès au contrôleur.

J’ai eu le même problème, mais une fois que j’ai créé un HIDDEN FIELD pour la clé étrangère … tout a bien fonctionné …

EXEMPLE DE FORME:

 @using (Html.BeginForm("save", "meter", FormMethod.Post)) { @Html.AntiForgeryToken() @Html.ValidationSummary(true) @Html.HiddenFor(model => Model.Entity.Id) @Html.HiddenFor(model => Model.Entity.DifferentialMeter.MeterId) @Html.HiddenFor(model => Model.Entity.LinearMeter.MeterId) @Html.HiddenFor(model => Model.Entity.GatheringMeter.MeterId) ... all your awesome controls go here ... } 

EXEMPLE D’ACTION:

 // POST: /Meter/Save [HttpPost] public ActionResult Save(Meter entity) { ... world-saving & amazing logic goes here ... } 

JOLIES IMAGES:
entrez la description de l'image ici