2015-03-06 1 views
0

Que doit recevoir le contrôleur lorsque j'envoie une vue contenant plusieurs vues partielles avec différents modèles? J'ai une vue qui affiche des vues partielles multiples/dynamiques (ces vues sont sélectionnées en fonction du paquet que l'utilisateur a précédemment sélectionné), toutes ces vues partielles ont des modèles différents et je dois les soumettre dans un grand "parent" " forme. Ma principale préoccupation est ce que le contrôleur devrait recevoir? et comment gérer toutes les informations à l'intérieur du formulaire, puisque j'ai des modèles multiples et variables (en fonction de ce que l'utilisateur choisit) qui sont envoyés à partir du formulaire.Que doit recevoir le contrôleur lorsque j'envoie une vue contenant plusieurs vues partielles avec différents modèles?

Ceci est ma vue parente, qui affiche toutes les vues partielles, selon le package choisi par l'utilisateur (par exemple, la vue parente peut afficher de 1 à 7 formulaires, tous ayant des modèles différents). La chaîne IEnumerable contient une liste de chaînes que je vais utiliser pour cracher un dictionnaire avec des vues et des modèles pour les rendre plus tard dans cette vue.

@using UI.Shared.Utils 
@model IEnumerable<string> 
@{ 
    var forms = CustomFormUtil.GetCustomMetaPartial(Model);  
}      
@using (Html.BeginForm(MVC.Service.NewOrderRequest.Index(**I am confused what to pass here**), FormMethod.Post)) 
{ 
    foreach (var form in forms) 
    { 
    { Html.RenderPartial(form.View, form.Model); } 
    } 
    <p style="clear: both"> 
    <input id="submitNOR" type="submit" value="Submit" style="float: right" /> 
    </p> 
} 

Alors disons que l'utilisateur remplit 4 une vue partielle, cela signifie que je dois envoyer 4 modèles différents au contrôleur afin que je puisse utiliser les données saisies par l'utilisateur.

Ceci est mon contrôleur:

[HttpPost] 
[SaveModelState] 
public virtual RedirectToRouteResult Index(**What should I receive**) 
{ 
    if (!ModelState.IsValid) 
    { 
    ModelState.AddModelError("error", "Please fill out the required fields"); 
    return RedirectToAction(MVC.Service.NewOrderRequestForms.Index()); 
    } 
    ... 
} 

Ma principale préoccupation est ce que le contrôleur devrait recevoir? Je l'ai essayé ce qui suit:

[HttpPost] 
[SaveModelState] 
public virtual RedirectToRouteResult Index(IEnumerable<ICustomModel> models) 

mais après quelques recherches ce n'est pas possible aussi que j'ai essayé de transmettre tous les modèles possibles au contrôleur

[HttpPost] 
[SaveModelState] 
public virtual RedirectToRouteResult Index(Model1 model1, ..., ModelN modeln) 

Cela ne fonctionnait pas, et mon dernier tentative était de créer un modèle maître qui contient tous les modèles possibles et le transmettre au contrôleur, ceci est mon modèle maître

namespace UI.Next.Areas.Service.Models 
{ 
    public class TdlMasterModel : ICustomMetaModel 
    { 
    public TdlMasterModel() 
    { 
    } 
    public TdlMasterModel(Guid? accountId) 
    { 
     AccountId = accountId; 
    } 
    public Guid? AccountId { get; set; } 
    public Model1 model1{ get; set; } 
    ... 
    public ModelN modeln{ get; set; } 
    } 
} 

Controller:

[HttpPost] 
[SaveModelState] 
public virtual RedirectToRouteResult Index(MasterModel masterModel) 

Jusqu'à présent, rien des solutions proposées n'avait fonctionné. Y at-il une solution directe pour cela ou je vais devoir créer un ModelBinder pour gérer cela.

+0

Q1 - Rien ne doit être 'BeginForm' si l'EEG et Les méthodes POST sont les mêmes (ie 'Index()' - il peut être juste '@using (Html.BeginForm()) {' –

+0

Q2.- Le modèle de vue 'maître' est la bonne approche. instance du modèle de vue dans la méthode GET et le passer à la vue qui aura '@model TdlMasterModel' –

+0

Merci d'avoir répondu, je suis confus au sujet de Q2, pourriez-vous donner un exemple s'il vous plaît? une propriété "nom", ou quelque chose de similaire, de les différencier dans le contrôleur? Je demande cela parce que certains des Les champs de propriété dans les modèles partagent le même champ de nom et je suis préoccupé par la façon de les différencier lors de l'effacement des données du MasterModel –

Répondre

1

Utilisez un modèle de vue contenant les modèles pour chaque forme que vous voulez rendre

Voir modèle

public class MasterVM 
{ 
    public Model1 Model1 { get; set; } 
    public Model2 Model2 { get; set; } 
    .... 
} 

Contrôleur

public ActionResult Index() 
{ 
    MasterVM model = new MasterVM(); 
    // Set the values of only those models you want to display forms for 
    model.Model2 = new Model2(); 
    return View(model); 
} 

[HttpPost] 
public ActionResult Index(MasterVM model) 
{ 
    if(!ModelState.IsValid) 
    { 
    return View(); 
    } 
    if (model.Model1 != null) 
    { 
    // save Model1 
    } 
    else if (model.Model2 != null) 
    { 
    // save Model2 
    } 
    .... 
    // redirect somewhere 
} 

partielle _Model1.cshtml

@model Model1 

@Html.LabelFor(m => m.SomeProperty) 
@Html.TextBoxFor(m => m.SomeProperty) 
@Html.ValidationMessageFor(m => m.SomeProperty) 

@Html.LabelFor(m => m.AnotherProperty) 
@Html.TextBoxFor(m => m.AnotherProperty) 
@Html.ValidationMessageFor(m => m.AnotherProperty) 

.... 

Voir

@model MasterVM 
@using Html.BeginForm()) 
{ 
    if(Model.Model1 != null) 
    { 
    @Html.Partial("_Model1", Model.Model1, new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "Model1" }}) 
    } 
    if(Model.Model2 != null) 
    { 
    @Html.Partial("_Model2", Model.Model2, new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "Model2" }}) 
    } 
    .... 
    <input type="submit" /> 
} 

Notez le 3ème paramètre de @Html.Partial.Cela va ajouter un préfixe aux noms de contrôle, donc si Model1 contient la propriété string Name, le contrôle sera généré <input name="Model1.Name" ...> vous permettant de republier et se lient à MasterVM

+0

Merci, je suis en train d'essayer maintenant =) –

+0

Merci, cela a fonctionné parfaitement =), merci beaucoup, j'avais des problèmes parce que Je ne liai pas le nom correctement "input name =" Model1.Name ", merci encore. –