Bind Select List with ViewBag in PartialView - ASP.NET Core MVC - asp.net-core-mvc

I have two models Employee and Department, i am trying to bind a Select List with Department model in Employee Create PartialView using ViewBag:
public class Employee
{
[Key]
public int EmployeeId { get; set; }
public string EmployeeName { get; set; }
public string Email{ get; set; }
[ForeignKey("DepartmentId")]
public int DepartmentId { get; set; }
public virtual Department Department { get; set; }
}
public class Department
{
[Key]
public int DepartmentId { get; set; }
[Required]
public string DepartmentName { get; set; }
public virtual ICollection<Employee> Employees { get; set; }
}
EmployeeController:
public IActionResult Create()
{
List<Department> departments = _dbcontext.Department.ToList();
ViewBag.ListDepartments = new SelectList(departments, "DepartmentId", "DepartmentName");
Employee employee = new Employee();
return PartialView("_AddEmployeePartialView",employee);
}
_AddEmployeePartialView.cshtml:
#model WebApplication1.Models.Employee
<div class="modal fade" role="dialog" tabindex="-1" id="addEmployee" aria-labelledby="addEmployeeLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addEmployeeLabel">Employees</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form asp-action="Create" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
...
<div class="form-group">
<label asp-for="DepartmentId" class="control-label">DepartmentId</label>
<select asp-for="DepartmentId" class="form-control" asp-items="ViewBag.ListDepartments" ></select>
</div>
...
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Save</button>
</div>
</form>
</div>
</div>
</div>
</div>
But i got an empty Dropdownlist. How to resolve this? is the problem in the modal popup??

I found my mistake. In the Controler the ViewBage should be in Index Action not in Create action:
public IActionResult Index()
{
List<Department> departments = _dbcontext.Department.ToList();
ViewBag.ListDepartments = new SelectList(departments, "DepartmentId", "DepartmentName");
Employee employee = _dbContext.Employee.ToList();
return View(employee);
}

Related

Model Validation Not Working on Multiple Models in Single View | in Asp.Net Core MVC

I need to do validation in the view where I sent 2 different models. I implemented this to be able to use 2 different models in a single view.
Dish.cs
public class Dish
{
public int DishId { get; set; }
[Required(ErrorMessage = "req")]
public Category Category { get; set; }
[Required(ErrorMessage = "req")]
public string DishName { get; set; }
[Required(ErrorMessage = "req")]
public string Description { get; set; }
}
Category.cs
public class Category
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
}
DishCategoriesModel.cs
public class DishCategoriesModel
{
public Dish Dish { get; set; }
public List<Category> Categories { get; set; }
}
Add.cshtml
#model DishCategoriesModel
#{
ViewData["Title"] = "Add";
}
<div class="row">
<div class="col-md-4">
<form asp-action="Add" enctype="multipart/form-data">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Dish.DishName" class="control-label"></label>
<input asp-for="Dish.DishName" class="form-control" />
<span asp-validation-for="Dish.DishName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Dish.Category.CategoryId" class="control-label"></label>
<select class="form-control" asp-for="Dish.Category.CategoryId">
<option selected disabled>Select Category...</option>
#foreach (var item in Model.Categories)
{
<option value="#item.CategoryId">#item.CategoryName</option>
}
</select>
<span asp-validation-for="Category.CategoryId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Dish.Description" class="control-label"></label>
<input asp-for="Dish.Description" class="form-control" />
<span asp-validation-for="Dish.Description" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Add" class="btn btn-primary" />
</div>
</form>
</div>
</div>
DishController.cs
[HttpGet]
public IActionResult Add()
{
List<Category> categories = categoryService.GetAll();
DishCategoriesModel model = new DishCategoriesModel
{
Categories = categories
};
return View(model);
}
[HttpPost]
public IActionResult Add(DishCategoriesModel model)
{
dishService.Add(model.Dish);
return View(model);
}
When I sent a single model to View, validations were working, but if I made it like above, it doesn't work. What is the right way?
you don't have any requirements on category , this is why this part is not working
Try to fix your Dish class by adding CategoryId:
public class Dish
{
public int DishId { get; set; }
[Range(1, 100000, ErrorMessage="req")]
public int? CategoryId { get; set; }
public virtual Category Category { get; set; }
[Required(ErrorMessage = "req")]
public string DishName { get; set; }
[Required(ErrorMessage = "req")]
public string Description { get; set; }
}
public class Category
{
public int CategoryId { get; set; }
[Required(ErrorMessage = "req")]
public string CategoryName { get; set; }
public virtual ICollection<Dish> Dishes { get; set; }
}
and view:
<label asp-for="Dish.CategoryId" class="control-label"> Categories </label>
<select class="form-control" asp-for="Dish.CategoryId">
.....
<span asp-validation-for="Dish.CategoryId" class="text-danger"></span>
and add server side validation too
public IActionResult Add(DishCategoriesModel model)
{
if (ModelState.IsValid)
{
//...your code
}
Change your view like below:
<form asp-action="Add" enctype="multipart/form-data">
//...
<div class="form-group">
<label asp-for="Dish.Category.CategoryId" class="control-label"></label>
<select class="form-control" asp-for="Dish.Category.CategoryId">
<option selected disabled>Select Category...</option>
#foreach (var item in Model.Categories)
{
<option value="#item.CategoryId">#item.CategoryName</option>
}
</select>
//change here.....
<span asp-validation-for="Dish.Category.CategoryId" class="text-danger"></span>
</div>
//...
</form>
Be sure add jquery.validate.js and jquery.validate.unobtrusive.js in your razor view like below:
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Result:

Custom validation message not shown using IValidatableObject

I have a simple form with 2 buttons (Cancel and Submit) and a TextArea. The user types a list of email addresses and presses submit. I am trying to figure out why my custom message is not being shown when I submit my form. I know the validation logic works as it triggers my [Required] rule and I can see the error message for that:
However, when I type in data such as "test#" and then submit, the logic in the Validate gets triggered but I can't see my error message "Please make sure that all of the emails are valid". What am I doing wrong?
That is my Model:
public class ShareModel : IValidatableObject
{
[HiddenInput] public string Title { get; set; }
[Required]
public string Emails { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
// custom validation logic here
yield return new ValidationResult($"Please make sure that all of the emails are valid", new[] { "Emails" });
}
}
That is my view:
<div class="modal fade" id="shareFormModal" role="dialog">
<div class="modal-dialog modal-md">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Share Workbook - #Model.Title</h4>
</div>
#using (Html.BeginForm("ShareWorkbook", "Home", FormMethod.Post, new {#id = "partialform"}))
{
<div class="modal-body">
<label>#BaseLanguage.Share_workbook_Instruction_text</label>
<div class="form-group">
<textarea class="form-control" asp-for="Emails" rows="4" cols="50" placeholder="#BaseLanguage.ShareDialogPlaceholder"></textarea>
<span asp-validation-for="Emails" class="text-danger"></span>
</div>
<input asp-for="Title"/>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Share</button>
<button id="btnCancelDialog" type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
}
</div>
</div>
According to this post IValidatableObject is not considered on client-side. In order to display custom error message from custom validation you need to implement custom ValidationAttribute that also implements IClientModelValidator interface as described here.
For future reference, as Alexander explained above I had to use both ValidationAttribute, IClientModelValidator like that:
ShareModel:
public class ShareModel
{
[HiddenInput] public string Title { get; set; }
[Required]
[IsEmailAttribute(ErrorMessage = "Check all of the emails you have typed")]
public string Emails { get; set; }
}
public class IsEmailAttribute : ValidationAttribute, IClientModelValidator
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
return new ValidationResult("Check emails!");
}
public void AddValidation(ClientModelValidationContext context)
{
MergeAttribute(context.Attributes, "data-val", "true");
var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
MergeAttribute(context.Attributes, "data-val-isEmail", errorMessage);
}
private bool MergeAttribute(
IDictionary<string, string> attributes,
string key,
string value)
{
if (attributes.ContainsKey(key))
{
return false;
}
attributes.Add(key, value);
return true;
}
}
_ShareView.cshtml:
#using DNAAnalysisCore.Resources
#model DNAAnalysisCore.Models.ShareModel
<!-- Modal -->
<div class="modal fade" id="shareFormModal" role="dialog">
<div class="modal-dialog modal-md">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Share Workbook - #Model.Title</h4>
</div>
#using (Html.BeginForm("ShareWorkbook", "Home", FormMethod.Post, new {#id = "partialform"}))
{
<div class="modal-body">
<label>#BaseLanguage.Share_workbook_Instruction_text</label>
<div class="form-group">
<textarea class="form-control" asp-for="Emails" rows="4" cols="50" placeholder="#BaseLanguage.ShareDialogPlaceholder"></textarea>
<span asp-validation-for="Emails" class="text-danger"></span>
</div>
<input asp-for="Title"/>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Share</button>
<button id="btnCancelDialog" type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
}
</div>
</div>
</div>
index.cshtnl:
#using DNAAnalysisCore.Resources
#model DNAAnalysisCore.Models.WorkBookModel
#{
}
#section BodyFill
{
<div id="shareFormContainer">
<!--PLACEHOLDER FOR SHARE DIALOG -->
#{
#Html.Partial("_ShareView", new ShareModel())
}
</div>
<div class="workbook-container">
<table class="table">
<tbody>
#foreach (var workbook in Model.Workbooks)
{
<tr>
<td>#Html.ActionLink(workbook.Name, "Open", "OpenAnalytics", new { id = Model.Id, workbook = workbook.Name })</td>
<td>
<button title="Share" class="share-button" onclick='showSharingView("#workbook.Name")'> </button>
</td>
</tr>
}
</tbody>
</table>
</div>
}
#section Scripts
{
<!--Load JQuery 'unobtrusive' validation -->
#await Html.PartialAsync("_ValidationScriptsPartial")
<script type="text/javascript">
function showSharingView(title) {
var url = "#Url.Action("ShowShareDialog", "Home")" + "?workbookTitle=" + encodeURI(title);
$('#shareFormContainer').load(url,
function() {
$('#shareFormModal').modal("show");
// // We need to manually register the form for validation as the dialog is
// // not included in the page when it initially loads
$.validator.unobtrusive.parse("#partialform");
// email validation
$.validator.addMethod("isEmail",
function (value, element, parameters) {
// TODO CLIENT SIDE VALIDATETION LOGIC HERE
return false;
});
$.validator.unobtrusive.adapters.add("isEmail",
[],
function(options) {
options.rules.isEmail = {};
options.messages["isEmail"] = options.message;
});
});
}
</script>
}

How to Create Drop-Down-List from Database in (Asp.net Core - MVC)?

I have 2 models:
News Model
TypeOfNew Model
with (one to many relationship), every (TypeOfNew) has one or multiple news.
News Model:
public class News
{
[Required(ErrorMessage = "ID إجباري.")]
[Key]
public int ID { get; set; }
[Required(ErrorMessage = "الحقل إجباري.")]
[Display(Name = "عنوان الخبر")]
public string Title { get; set; }
[Required(ErrorMessage = "الحقل إجباري.")]
[Display(Name = "مصدر الخبر")]
public string Source { get; set; }
[Required(ErrorMessage = "الحقل إجباري.")]
[Display(Name = "الوصف")]
[MaxLength(5000)]
public string Description { set; get; }
[Display(Name = "نوع الخبر")]
public int NewsTypeId { set; get; }
public TypeOfNew TypeOfNew { set; get; }
}
TypeOfNew Model:
public class TypeOfNew
{
[Key]
public int TypeId { set; get; }
[Display(Name = " نوع الخبر")]
public string TypeName { set; get; }
public ICollection<News> News { get; set; }
}
in Create View(News), I want to display drop-down-list of (TypeOfNew).
so when I post (Create View) I want to store (TypeId) of (TypeOfNew model) in (NewsTypeId) of (News model).
So, what should I do in:
create Action (Get).
create Action (Post).
Create View.
Assume that you have set below tables in dbcontext:
public DbSet<News> News { get; set; }
public DbSet<TypeOfNew> TypeOfNews { get; set; }`
You could refer to below steps to achieve your requirements:
1.Create action GET
public IActionResult Create()
{
ViewData["NewsTypeId"] = new SelectList(_context.TypeOfNews, "TypeId", "TypeName");
return View();
}
2.Create action POST
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ID,Title,Source,Description,NewsTypeId")] News news)
{
if (ModelState.IsValid)
{
_context.Add(news);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ViewData["NewsTypeId"] = new SelectList(_context.TypeOfNews, "TypeId", "TypeName", news.NewsTypeId);
return View(news);
}
3.Create View
#model News
<h1>Create</h1>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Source" class="control-label"></label>
<input asp-for="Source" class="form-control" />
<span asp-validation-for="Source" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Description" class="control-label"></label>
<input asp-for="Description" class="form-control" />
<span asp-validation-for="Description" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="NewsTypeId" class="control-label"></label>
<select asp-for="NewsTypeId" class="form-control" asp-items="#ViewBag.NewsTypeId"></select>
<span asp-validation-for="NewsTypeId" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
For configuring one-to-many relationships,you could refer to
https://learn.microsoft.com/en-us/ef/core/modeling/relationships#definition-of-terms

The viewmodel does not update when I give Post using JS - Asp.net

I have a view model PesoaViewModel and inside it have 2 properties of type PersonFisicaViewModel and PessoaJuridicaViewModel. In my view Create I render PessoaFisiicaViewModel and PessoaJuridicaViewModel according to the nature of the person (Physical or Legal). In my case, when the user completes the data of individual and change to legal entity (the nature), the system must give a Post, move some data from the individual to legal entity and then return to the view and show them only in rendering legal entity.
I can do the Post and return the viewmodel, but the partial view does not update to the fields linked to ViewModelPessoaPhysica / ViewModelPessoaJuridica ... I've already tried doing it by JS, but it does not work .. Does anyone know how to help me?
Thank you!! :)
[HttpPost]
[Authorize(Policy = "CanWriteCustomerData")]
[Route("pessoa-gerenciamento/cadastrar-novo")]
[ValidateAntiForgeryToken]
public IActionResult Create(PessoaViewModel pessoaViewModel)
{
//Este bloco faz o tratamento que converte PessoaFisica em PessoaJuridica e vice-versa
if (pessoaViewModel.PessoaFisicaViewModel != null || pessoaViewModel.PessoaJuridicaViewModel != null)
{
var pessoa = _pessoaAppService.Change(pessoaViewModel);
return View(pessoa);
}
if (!ModelState.IsValid) return View(pessoaViewModel);
_pessoaAppService.RegisterPessoaFisica(pessoaViewModel);
if (IsValidOperation())
ViewBag.Sucesso = "Pessoa Cadastrada!";
return View(pessoaViewModel);
}
#using SistemaComercial.Domain.ValueObjects
#model SistemaComercial.Application.ViewModels.Pessoa.PessoaViewModel
#{
ViewData["Title"] = "Cadastrar Nova Pessoa";
}
<div class="panel">
<div class="panel-heading">
<h2 class="panel-title">Cadastrar nova Pessoa</h2>
</div>
<form asp-action="Create" id="frmCreate">
<div class="panel-body container-fluid">
#* Replacing classic Validation Summary to Custom ViewComponent as TagHelper *#
<vc:summary />
<!-- Example Tabs -->
<div class="example-wrap">
<div class="nav-tabs-horizontal">
<ul class="nav nav-tabs" data-plugin="nav-tabs" role="tablist">
<li class="active" role="presentation">
<a data-toggle="tab" href="#exampleTabsOne" aria-controls="exampleTabsOne" role="tab">Dados Pessoais</a>
</li>
<li role="presentation">
<a data-toggle="tab" href="#exampleTabsTwo" aria-controls="exampleTabsTwo" role="tab">Documentos</a>
</li>
<li role="presentation">
<a data-toggle="tab" href="#exampleTabsThree" aria-controls="exampleTabsThree" role="tab">Endereços</a>
</li>
<li role="presentation">
<a data-toggle="tab" href="#exampleTabsFour" aria-controls="exampleTabsFour" role="tab">Contatos</a>
</li>
</ul>
<div class="tab-content padding-top-20">
<div class="tab-pane active" id="exampleTabsOne" role="tabpanel">
<div class="form-horizontal">
<div class="form-group">
<label asp-for="Id" class="col-md-2 control-label"></label>
<div class="col-md-2">
<input asp-for="Id" class="form-control" disabled="disabled" />
<span asp-validation-for="Id" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="PessoaNatureza" class="col-md-2 control-label"></label>
<div class="col-md-3">
<select id="PessoaNatureza" asp-for="PessoaNatureza" asp-items="Model.PessoasNaturezas" class="form-control">
<option value="" data-id="#Model.PessoaNatureza.ObterIdEnum()">--SELECIONE--</option>
</select>
<span asp-validation-for="PessoaNatureza" class="text-danger"></span>
</div>
</div>
#await Html.PartialAsync("_PessoaFisica")
#await Html.PartialAsync("_PessoaJuridica")
#*<div id="divPessoaFisica">
#await Html.PartialAsync("_PessoaFisica")
</div>
<div id="divPessoaJuridica" style="display: none">
#await Html.PartialAsync("_PessoaJuridica")
</div>*#
#*#if (Model.PessoaNatureza == PessoaNatureza.Fisica)
{
<div id="divPessoaFisica">
#await Html.PartialAsync("_PessoaFisica")
</div>
<div id="divPessoaJuridica" style="display:none">
#await Html.PartialAsync("_PessoaJuridica")
</div>
}
else if (Model.PessoaNatureza == PessoaNatureza.Juridica)
{
<div id="divPessoaFisica" style="display:none">
#await Html.PartialAsync("_PessoaFisica")
</div>
<div id="divPessoaJuridica">
#await Html.PartialAsync("_PessoaJuridica")
</div>
}*#
</div>
</div>
<div class="tab-pane" id="exampleTabsTwo" role="tabpanel">
</div>
<div class="tab-pane" id="exampleTabsThree" role="tabpanel">
</div>
<div class="tab-pane" id="exampleTabsFour" role="tabpanel">
</div>
</div>
</div>
</div>
<!-- End Example Tabs -->
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
#*<input type="submit" value="Gravar" class="btn btn-success" />
<a asp-action="Index" class="btn btn-info">Voltar à Lista</a>*#
<button type="submit" class="btn btn-success"><i class="icon wb-check" aria-hidden="true"></i> Gravar</button>
<a asp-action="Index" class="btn btn-danger">
<span title="Retornar à Lista" class="icon wb-arrow-left"></span> Retornar à lista
</a>
</div>
</div>
</div>
</form>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script>
$(function () {
$('#PessoaNatureza').change(function () {
var data = $('#frmCreate').serialize();
if (this.value === 'Fisica') {
$.ajax({
type: "POST",
traditional: true,
url: '#Url.Action("Create", "Pessoa")',
data: data
});
$('#divPessoaFisica').show();
$('#divPessoaJuridica').hide();
}
else if (this.value === 'Juridica') {
$.ajax({
type: "POST",
traditional: true,
url: '#Url.Action("Create", "Pessoa")',
data: data
});
$('#divPessoaFisica').hide();
$('#divPessoaJuridica').show();
}
else {
$('#divPessoaFisica').hide();
$('#divPessoaJuridica').hide();
}
});
});
</script>
}
public class PessoaViewModel
{
[DisplayName("Código")]
public int Id { get; set; }
[DisplayName("Natureza")]
[Required(ErrorMessage ="Escolha uma Natureza")]
public PessoaNatureza PessoaNatureza { get; set; }
[DisplayName("Natureza")]
public string PessoaNaturezaDescricao { get; set; }
[DisplayName("Naturezas")]
public IEnumerable<SelectListItem> PessoasNaturezas { get; set; }
public PessoaFisicaViewModel PessoaFisicaViewModel { get; set; }
public PessoaJuridicaViewModel PessoaJuridicaViewModel { get; set; }
public PessoaViewModel()
{
PessoasNaturezas = ExtensaoDeEnumerador.EnumParaSelectListGenerico<PessoaNatureza>("U", PessoaNatureza.ToString()).OrderBy(x => x.Text);
}
}
public class PessoaFisicaViewModel
{
[DisplayName("Código")]
public int Id { get; set; }
[DisplayName("Nome Completo")]
[Required(ErrorMessage = "O campo Nome Completo é obrigatório")]
[MaxLength(200, ErrorMessage = "O campo {0} deve ter no máximo {1} caracteres")]
//[MinLength(5, ErrorMessage = "O campo {0} deve ter no mínimo {1} caracteres")]
public string NomeCompleto { get; set; }
[DisplayName("Apelido")]
[MaxLength(200, ErrorMessage = "O campo {0} deve ter no máximo {1} caracteres")]
//[MinLength(5, ErrorMessage = "O campo {0} deve ter no mínimo {1} caracteres")]
public string Apelido { get; set; }
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
[DataType(DataType.Date, ErrorMessage = "Data em formato inválido")]
[DisplayName("Nascimento")]
public DateTime? DataNascimento { get; set; }
[DisplayName("Sexo")]
[Required(ErrorMessage = "Escolha o Sexo")]
public Sexo Sexo { get; set; }
[DisplayName("Sexo")]
public string SexoDescricao { get; set; }
[DisplayName("Sexos")]
public IEnumerable<SelectListItem> Sexos { get; set; }
[DisplayName("Estado Civil")]
[Required(ErrorMessage = "Escolha o Estado Civil")]
public EstadoCivil EstadoCivil { get; set; }
[DisplayName("Estado Civil")]
public string EstadoCivilDescricao { get; set; }
[DisplayName("Estados Civis")]
public IEnumerable<SelectListItem> EstadosCivis { get; set; }
public PessoaFisicaViewModel()
{
Sexos = ExtensaoDeEnumerador.EnumParaSelectListGenerico<Sexo>("U", Sexo.ToString()).OrderBy(x => x.Text);
EstadosCivis = ExtensaoDeEnumerador.EnumParaSelectListGenerico<EstadoCivil>("U", EstadoCivil.ToString()).OrderBy(x => x.Text);
}
}
public class PessoaJuridicaViewModel
{
[DisplayName("Código")]
public int Id { get; set; }
[DisplayName("Razão Social")]
[Required(ErrorMessage = "O Campo Razão Social é obrigatório")]
[MaxLength(200, ErrorMessage = "O campo {0} deve ter no máximo {1} caracteres")]
public string RazaoSocial { get; set; }
[DisplayName("Nome Fantasia")]
[Required(ErrorMessage = "Campo Nome Fantasia é obrigatório")]
[MaxLength(200, ErrorMessage = "O campo {0} deve ter no máximo {1} caracteres")]
public string NomeFantasia { get; set; }
[DisplayName("Data de Abertura")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
[DataType(DataType.Date, ErrorMessage = "Data em formato inválido")]
public DateTime? DataAbertura { get; set; }
}
Please try if adding the attribute [FromBody] helps:
public IActionResult Create([FromBody] PessoaViewModel pessoaViewModel)
....
This attribute tells the MVC Model Binder where to look for the data that it should bind. For a Form POST it should almost always use data from the 'BODY'-part of the submitted data, but you have to tell it that explicitly.

How to preserve current view after api call

Before asp.net core I would invoke a web api from a button by writing some jquery from behind the button click.
I would then handle the data returned from that api call.
Currently I have a view. this view contains a pop up window. In that window I have 3 div sections.
Login
Registration
ForgottenPassword
Focusing on Registration div I allow user to enter email/password/confirm password and let them press a button that calls my web api to validate this process.
So, this is my parent view snippet:
#model InformedWorker.Services.Models.Account
<div id="divLogForm" class="modal-dialog" style="display:none;position:absolute; ">
<div style="background-color: #fefefe;margin: auto;padding: 20px;border: 1px solid #888;">
<div class="modal-header">
<button id="btnClose" type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="hdrTitle">LogIn</h4>
</div>
<div class="modal-body">
#{Html.RenderPartial("~/Views/Segments/_Registration.cshtml", Model.Registration);}
#{Html.RenderPartial("~/Views/Segments/_LogIn.cshtml", Model.LogIn);}
#{Html.RenderPartial("~/Views/Segments/_ForgottenRegistration.cshtml", Model.ForgottenloginDetails);}
</div>
</div>
</div>
My registration partial view is this:
#model InformedWorker.Services.Models.Registration
#*
*#
<div class="row" style="display:none" id="divRegistration">
<div class="col-xs-6">
<div class="well">
<div class="form-group">
<label asp-for="EmailAddress" class="control-label"></label>
<input type="text" class="form-control" id="EmailAddress" name="EmailAddress" value="#Model.EmailAddress" required="" title="Please enter you username" placeholder="example#gmail.com">
<span class="help-block"></span>
</div>
<div class="form-group">
<label asp-for="Password" class="control-label">Password</label>
<input type="password" class="form-control" id="Password" name="Password" value="" required="" title="Please enter your password">
<span class="help-block"></span>
</div>
<div class="form-group">
<label asp-for="ConfirmPassword" class="control-label"></label>
<input type="password" class="form-control" id="ConfirmPassword" name="ConfirmPassword" value="" required="" title="Please confirm your password">
</div>
<div id="registerErrorMsg" class="alert alert-error hide">Invalid registration</div>
<a asp-area="" asp-controller="api/Registration" asp-action="Register" class="btn btn-success btn-block">Register</a>
</div>
</div>
<div class="col-xs-6">
<p class="lead">Already Registered?</p>
<p><a onclick="showLogInPage();" class="btn btn-info btn-block">LogIn</a></p>
</div>
</div>
My account Model is this:
public class Account
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long AccountId { get; set; }
public string AccountRef { get; set; }
[Display(Name = "Company Name")]
public string CompanyName { get; set; }
[Display(Name = "Email Address")]
[Required]
[RegularExpression(#"\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*", ErrorMessage = "Email address not found")]
[StringLength(60, MinimumLength = 3)]
public string EmailAddress { get; set; }
public string Salt { get; set; }
public string Hash { get; set; }
public bool Disabled { get; set; }
[Display(Name = "Date of Entry")]
public DateTime DOE { get; set; }
public ICollection<Client> Clients { get; set; }
public bool Activated { get; set; }
[NotMapped]
public Registration Registration { get; set; }
[NotMapped]
public LogIn LogIn { get; set; }
[NotMapped]
public ForgottenRegistration ForgottenRegistration { get; set; }
}
My homeController is this:
public IActionResult Index()
{
//var home = new Services.Models.Home();
//home.MyTest = _localizer["ActivationEmailSent"];
//return View(home);
var test = new Services.Models.Account();
test.Registration = new Services.Models.Registration();
test.Registration.EmailAddress = "aaa";
return View(test);
//return View(new Services.Models.Account());
}
My Registration Web api is this:
[Route("api/[controller]")]
public class Registration : Controller
{
// GET api/values/5
[HttpGet("{id}")]
public string Get(Registration Account)//int id)
{
return "Error in reg";
}
}
so my question is that when api is called the whole page page is replaced with 'value'.
how would I parse the data and populate the form fields with the result and preserve the original view?
Should i revert back to jquery and make api call that way?
Have I got this fundamentally wrong?
Thanks

Resources