web-dev-qa-db-fra.com

Publier un formulaire avec plusieurs vues partielles

J'essaie actuellement de publier un formulaire composé de deux vues fortement typées. Cette question est similaire mais n'a pas de réponse:

MVC 3 Razor Form Post avec plusieurs vues partielles fortement typées non contraignantes

Lorsque je soumets un formulaire, le modèle soumis au contrôleur est toujours nul. J'ai passé quelques heures à essayer de le faire fonctionner. Cela semble être simple. Est-ce que j'ai râté quelque chose? Je n'ai pas besoin de faire ajax, il suffit de pouvoir poster sur le contrôleur et de rendre une nouvelle page.

Merci

Voici mon code d'affichage:

<div>
    @using (Html.BeginForm("TransactionReport", "Reports", FormMethod.Post, new {id="report_request"}))
    {
        ViewContext.FormContext.ValidationSummaryId = "valSumId";
        @Html.ValidationSummary(false, "Please fix these error(s) and try again.", new Dictionary<string, object> { { "id", "valSumId" } });
        @Html.Partial("_ReportOptions", Model.ReportOptions);
        @Html.Partial("_TransactionSearchFields", new ViewDataDictionary(viewData) { Model = Model.SearchCriteria });
    }

Voici le code dans le contrôleur:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult TransactionReport(TransactionReportRequest reportRequest)
{
    var reportInfo = new List<TransactionReportItem>();

    if (ModelState.IsValid)
    {
        var reportData = _reportDataService.GetReportData(Search.MapToDomainSearchCriteria(reportRequest.SearchCriteria));
        if (reportData!=null)
        {
            reportInfo = reportData.ToList();
        }
        return View(reportInfo);
    }
    return View(reportInfo);
}

Les vues partielles elles-mêmes ne sont pas pertinentes car elles ne font qu'offrir et afficher leurs modèles.

33
dalcantara

Les partiels ne sont pas la voie à suivre ici. Vous recherchez des EditorTemplates, ceux-ci sont faits pour ce que vous voulez. Dans ce cas, vos propriétés seront bien liées à votre modèle (que vous soumettrez).

Votre vue principale aura ce formulaire (notez que vous n'avez qu'à utiliser EditorFor au lieu de Partial; dans ce cas, vous devrez probablement mettre ce paramètre viewData dans le ViewBag):

@using (Html.BeginForm("TransactionReport", "Reports", FormMethod.Post, new {id="report_request"}))
{
    ViewContext.FormContext.ValidationSummaryId = "valSumId";
    @Html.ValidationSummary(false, "Please fix these error(s) and try again.", new Dictionary<string, object> { { "id", "valSumId" } });
    @Html.EditorFor(model => model.ReportOptions);
    @Html.EditorFor(model = Model.SearchCriteria });
}

Il ne vous reste plus qu'à faire glisser vos partiels vers le dossier ~/Shared/EditorTemplates/ et renommez-les pour qu'ils correspondent au nom du modèle pour lequel ils sont les modèles d'éditeur.

Dans le ~/Shared/EditorTemplates/ dossier, créez une nouvelle "vue", par exemple "SearchCriteria.cshtml". A l'intérieur, mettez comme "modèle" le type de classe pour lequel vous souhaitez créer un modèle d'éditeur. Exemple (l'exemple de classe a les propriétés Name et OtherCriteria):

@model MyNamespace.SearchCriteria
<ul>
    <!-- Note that I also use EditorFor for the properties; this way you can "nest" editor templates or create custom editor templates for system types (like DateTime or String or ...). -->
    <li>@Html.LabelFor(m => m.Name): @Html.EditorFor(m => m.Name)</li>
    <li>@Html.LabelFor(m => OtherCriteria): @Html.EditorFor(m => m.OtherCriteria</li>
</ul>

Quelques bonnes lectures à leur sujet:

53
Styxxy

Vous devez ajouter un préfixe aux champs de PartialView. Cela permettra aux données de liaison correctement.

Donc au lieu:

@Html.Partial("_ReportOptions", Model.ReportOptions);

Utilisation:

@Html.Partial("_ReportOptions", Model.ReportOptions, new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "ReportOptions" }})
13

Je suis d'accord avec @Styxxy et @Tony, les modèles d'éditeur sont la meilleure solution. Cependant, votre problème est que vous alimentez un sous-modèle dans les vues partielles. Ainsi, lorsque la vue partielle s'affiche, elle ne sait pas qu'elle fait partie d'un modèle plus grand et ne génère pas les attributs de nom corrects.

Si vous insistez pour utiliser des partiels plutôt que des modèles d'éditeur, je suggère de ne passer que le modèle aux partiels, puis de faire faire à chaque partiel Model.Wwhat.Foo et cela générera les attributs de nom corrects pour la liaison.

10
Erik Funkenbusch

Essayez d'utiliser EditorTemplates au lieu de Partials http://coding-in.net/asp-net-mvc-3-how-to-use-editortemplates/ .

4
magritte
@Html.Partial("_ReportOptions", Model.Contact, new ViewDataDictionary()
           {
               TemplateInfo = new TemplateInfo()
                   {
                       HtmlFieldPrefix = "Contact"
                   }
           })

)


@Html.Partial("_TransactionSearchFields", Model.SearchCriteria, new  
 ViewDataDictionary()
           {
               TemplateInfo = new TemplateInfo()
                   {
                       HtmlFieldPrefix = "SearchCriteria"
                   }
           })
2
Kesikan K