List of View objects for controller

1

I have two Client and Address entities where the client has multiple addresses. At the time of filling out the form, the user can add two addresses in the same form and at the time of the Submit, would like to receive the data of the client and more than one address filled in the same form.  How can I receive on my Controller the Customer filled in with more than one address with just a Submit?

In my MVC project I'm following the DDD architecture strategy where my Application layer contains my ViewsModel classes with the ClientEnderecoViewModel, ClientViewModel, and EnderecoViewModel classes where I talk to my ClientController Presentation layer.

My ClientEnderecoViewModel has the following prop below

 public Guid ClienteId { get; set; }
 public string Nome { get; set; }
 public string Email { get; set; }
 public string CPF { get; set; }
 public ICollection<EnderecoViewModel> ListEnderecoViewModels { get; set; }

My ClientController

    public ActionResult Create( ClienteEnderecoViewModel clienteEnderecoViewModel)
    {
        if (ModelState.IsValid)
        {

            _clienteAppService.Adicionar(clienteEnderecoViewModel);
            return RedirectToAction("Index");
        }

        return View(clienteEnderecoViewModel);
    } 

My Create.CSHTML

    <h4>Endereco </h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(model => model.Logradouro, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.ListEnderecoViewModels, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Logradouro, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Numero, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Numero, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Numero, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Complemento, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Complemento, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Complemento, "", new { @class = "text-danger" })
        </div>
    </div>
    
asked by anonymous 19.10.2016 / 04:33

1 answer

2

You said you would have two addresses. You could already create the model by adding two empty addresses and delivering it to the View. It is necessary to make a for to generate the EditorFor for each item in the collection. If you need to add more addresses dynamically you have to do with JS to create new form items.

 public class ClienteViewModel {
    public Guid ClienteId { get; set; }
    public string Nome { get; set; }
    public string Email { get; set; }
    public string CPF { get; set; }
    public ICollection<EnderecoViewModel> ListEnderecoViewModels { get; set; }
 }

 public ActionResult Index() {
      var model = new ClienteViewModel(){
            ListEnderecoViewModels = new List<EnderecoViewModel>{
                new EnderecoViewModel(),
                new EnderecoViewModel()
            }
      };
      return View(model);
 }

View

I've done the example of just one Editor. Then you should do it for others.

<div class="form-group">
    @Html.LabelFor(model => model.Nome, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.EditorFor(model => model.Nome, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Nome, "", new { @class = "text-danger" })
    </div>
</div>

@for(int i = 0; i < Model.ListEnderecoViewModels.Count; i++) {
    <div class="form-group">
    @Html.LabelFor(model => model.ListEnderecoViewModels[i].Logradouro, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.EditorFor(model => model.ListEnderecoViewModels[i].Logradouro, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.ListEnderecoViewModels[i].Logradouro, "", new { @class = "text-danger" })
    </div>
</div>
}

Controller

In this way, you can retrieve the client and address data in a single object.

public ActionResult Salvar(ClienteViewModel model){
   // as propriedades do cliente estarão preenchidas bem como os endereços
    foreach(var endereco in model.ListEnderecoViewModels){
      _clienteAppService.Adicionar(endereco);
   }
   .....
}
    
19.10.2016 / 12:41