To create the controller and the view corresponding to a given ViewModel
ViewModel
namespace WebApplication1.Models
{
public class ExampleViewModel
{
public Produto Produto { get; set; }
public Cliente Cliente { get; set; }
}
public class Produto
{
public int Id { get; set; }
public string Descricao { get; set; }
}
public class Cliente
{
public int Id { get; set; }
public string Nome { get; set; }
}
}
In this ViewModel ( ExampleViewModel
) I have two aggregations of classes Produto
and Cliente
and with them I will create the view Main ( Create
) and their respective views for each existing aggregation.
What would it be like?
public class ExamplesController : Controller
{
[HttpGet()]
public ActionResult Create()
{
return View();
}
[HttpPost()]
public ActionResult Create(ExampleViewModel exampleViewModel)
{
//ROTINAS DE GRAVAÇÃO
return View();
}
}
In controller
it is simple to create a Create with verb GET
and another with verb POST
with a parameter of its ViewModel
( ExampleViewModel
).
Create your view in this format:
View Product: (_Product.cshtml)
@model WebApplication1.Models.ExampleViewModel
<div class="form-horizontal">
<h4>Produto</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Produto.Id, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Produto.Id, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Produto.Id, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Produto.Descricao, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Produto.Descricao, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Produto.Descricao, "", new { @class = "text-danger" })
</div>
</div>
</div>
View Client: (_Customer.cshtml)
@model WebApplication1.Models.ExampleViewModel
<div class="form-horizontal">
<h4>Cliente</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Cliente.Id, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Cliente.Id, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Cliente.Id, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Cliente.Nome, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Cliente.Nome, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Cliente.Nome, "", new { @class = "text-danger" })
</div>
</div>
</div>
Note that these two views that complement your main view have an interesting factor that I put your type in @model
to your ViewModel ExampleViewModel
Why?
In order for% () the information passed in the fields to be loaded into your class in a simple and transparent way, it works correctly, ie, by sending the information to binding
( Create
) it loads the class correctly. Look at the nomenclature of an item:
@Html.EditorFor(model => model.Cliente.Id, new { htmlAttributes = new { @class = "form-control" } })
It has been mounted on top of its aggregation shown therein in do verb POST
, so that it gives the correct model.Cliente.Id
of the information.
View Main: (Create.cshtml)
@model WebApplication1.Models.ExampleViewModel
@{ Layout = null; }
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Create</title>
</head>
<body>
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryval")
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.Partial("_Cliente", Model)
<hr />
@Html.Partial("_Produto", Model)
<div class="form-horizontal">
<h4>ExampleViewModel</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
</body>
</html>
Html generated
<form action="/Examples/Create" method="post"><input name="__RequestVerificationToken" type="hidden" value="Mr207UcvrXamhyWWVqGbKBVZ8wY9ccJoBqcGVCjwg3G_tjHWIymMjfzE5o1XkXaJ8Q0WsL5XWMhq3biQfh7rKmuerIMuMPCgPFEOzA7baNc1" /><div class="form-horizontal">
<h4>Cliente</h4>
<hr />
<div class="form-group">
<label class="control-label col-md-2" for="Cliente_Id">Id</label>
<div class="col-md-10">
<input class="form-control text-box single-line" data-val="true" data-val-number="The field Id must be a number." data-val-required="O campo Id é obrigatório." id="Cliente_Id" name="Cliente.Id" type="number" value="" />
<span class="field-validation-valid text-danger" data-valmsg-for="Cliente.Id" data-valmsg-replace="true"></span>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2" for="Cliente_Nome">Nome</label>
<div class="col-md-10">
<input class="form-control text-box single-line" id="Cliente_Nome" name="Cliente.Nome" type="text" value="" />
<span class="field-validation-valid text-danger" data-valmsg-for="Cliente.Nome" data-valmsg-replace="true"></span>
</div>
</div>
</div> <hr />
<div class="form-horizontal">
<h4>Produto</h4>
<hr />
<div class="form-group">
<label class="control-label col-md-2" for="Produto_Id">Id</label>
<div class="col-md-10">
<input class="form-control text-box single-line" data-val="true" data-val-number="The field Id must be a number." data-val-required="O campo Id é obrigatório." id="Produto_Id" name="Produto.Id" type="number" value="" />
<span class="field-validation-valid text-danger" data-valmsg-for="Produto.Id" data-valmsg-replace="true"></span>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2" for="Produto_Descricao">Descricao</label>
<div class="col-md-10">
<input class="form-control text-box single-line" id="Produto_Descricao" name="Produto.Descricao" type="text" value="" />
<span class="field-validation-valid text-danger" data-valmsg-for="Produto.Descricao" data-valmsg-replace="true"></span>
</div>
</div>
</div> <div class="form-horizontal">
<h4>ExampleViewModel</h4>
<hr />
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
</form>
In this generation it is easy to see why the aggregations of the binding
class are loaded, the fields for example client name in its ExampleViewModel
of type tag input
is named text
. Client is the Cliente.Nome
and the Name its property , this is how MVC can define the information and load in the corresponding classes. p>
If you ride differently it will not work !!!