Usando o Razor para criar um formulário para hierarquia de modelos de domínio
-
21-12-2019 - |
Pergunta
Digamos que eu tenha as seguintes classes (você também poderia considerar se minhas classes em termos dessa parte da relação estão corretas):
public class EFDbContext : DbContext
{
public DbSet<Project> Projects { get; set; }
public DbSet<Address> Addresses { get; set; } // *
public DbSet<Country> Countries { get; set; } // *
// Custom model builder bindings for * coz of the plural issue with EF
}
public class Project
{
public int ProjectID { get; set; }
public string Name { get ; set; }
public int AddressID { get; set; } // Database relation column
public Address Address { get ; set; }
}
public class Address
{
public int AddressID { get; set; }
public string Address1 { get ; set; }
public string Address2 { get ; set; }
public int CountryID { get; set; } // Database relation column
public Country Country { get ; set; }
}
public class Country
{
public int CountryID { get; set; }
public string Name { get; set; }
}
Como eu faria para fazer a Navalha para isso ...
Minha página "Criar Projeto" precisará de um formulário parecido com este...mas isso não está correto, certo?
@model Project
<div class="form-group">
@Html.LabelFor(model => model.Name, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Address, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Address)
</div>
</div>
Então acabei criando um Shared/EditorTemplates/Address.cshtml
que então construiu o formulário de endereço:
@model Address
<div class="form-group">
@Html.LabelFor(model => model.Address1, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Address1)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Address2, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Address2)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Country, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Country)
</div>
</div>
E finalmente o Country...O que precisa de digitação antecipada (portanto, algumas classes personalizadas adicionadas ao editorfor
o que você não pode fazer, então eu fiz textbox
) - Shared/EditorTemplates/Country.cshtml
@model Country
<div class="form-group">
@Html.LabelFor(model => model.Name, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.TextBox("", Model.Name.ToString(), new { @class = "countries typeahead" })
</div>
</div>
Isso parece correto?Acho isso muito opressor e confuso (aliás, tentei isso e não está funcionando...mas se eu souber que é o caminho correto, posso seguir nessa direção)!
Solução
Você está no caminho certo.Apenas tome cuidado ao colocar seus EditorTemplates na estrutura do projeto e como você se refere a eles.A convenção MVC nem sempre funciona da maneira que você espera, por exemplo.usando modelos de editor para um único modelo quando o modelo está agrupado em uma lista.
Uma sugestão que tenho seria usar um "modelo de visualização" completamente separado para o modelo passado para suas visualizações de barbear.Você pode mapear entre seu modelo de visualização e seu modelo de estrutura de entidade (também conhecido como modelo de dados) usando algo como automapper.Por que?Com o tempo, você descobrirá que eles exigirão coisas diferentes, por exemplo.atributos mvc nas propriedades do modelo.