ASP.NET Core model binding - asp.net-core-mvc

I'm trying to bind an edit action to a model which doesn't work. Here below the controller:
[Route("[controller]/[action]")]
public class CustomerController : Controller
{
private readonly IUnitOfWork _unitOfWork;
public CustomerController(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
[HttpGet("{_customerCode}")]
public IActionResult Edit(int _customerCode)
{
var customer = _unitOfWork.Customers.getCustomerByCode(_customerCode);
var customerDTO = Mapper.Map<CustomerModelDTO>(customer);
return View(customerDTO);
}
[HttpPost]
public IActionResult Edit(CustomerModelDTO model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var _customer = _unitOfWork.Customers.getCustomerByCode(model.CustomerCode);
if (_customer==null)
{
return NotFound();
}
Mapper.Map(model, _customer);
_unitOfWork.Complete();
return RedirectToAction("Detail", new { customerCode = _customer.CustomerCode });
}
}
And here is the view I am using:
#model Almiz.Dtos.CustomerModelDTO
<form asp-action="Edit" method="post">
<div class="form-horizontal">
<h4>CustomerModelDTO</h4>
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="CustomerCode" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="CustomerCode" class="form-control" />
<span asp-validation-for="CustomerCode" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="FirstName" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="FirstName" class="form-control" />
<span asp-validation-for="FirstName" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="MiddleName" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="MiddleName" class="form-control" />
<span asp-validation-for="MiddleName" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="LastName" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="LastName" class="form-control" />
<span asp-validation-for="LastName" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="Telephone" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Telephone" class="form-control" />
<span asp-validation-for="Telephone" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="Mobile" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Mobile" class="form-control" />
<span asp-validation-for="Mobile" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="Email" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
</form>
<div>
<a asp-action="Index">Back to Index</a>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
When I call the view and with the ID http://localhost:65001/Customer/Edit/1001, I get the all the information. However when I edit it and post the edited form I get resource not found error. Please help. Here below the model:
public class CustomerModelDTO
{
public int CustomerCode { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public double Telephone { get; set; }
public double Mobile { get; set; }
public string Email { get; set; }
}

I got it working. Here below the change.
[HttpPost("{customerCode}")]
public IActionResult Edit(int customerCode, CustomerModelDTO data)

Related

How to update value progress bar bootstrap from controller in ASP .NET Core

I have a table that receive email of my users for newsletter .I Show it on my dashboard with count .but now I want to show on progress bar and its percentage per last month
how do I do ? I create another view model for show count of some things
I can show count of them but I need show on progress bar too.
my viewmodel:
public class NewsLetterViewModel
{
public string Phone { get; set; }
public string Email { get; set; }
public DateTime CreateDate { get; set; }
}
You can try to use ViewBag to pass count and percentage.Here is a demo:
Action:
public IActionResult News()
{
ViewBag.Count = 0;
ViewBag.Percentage = 0;
return View();
}
[HttpPost]
public IActionResult News(NewsLetterViewModel n,int Count)
{
//you can pass the count and percentage with ViewBag here
ViewBag.Count= Count+ 1;
ViewBag.Percentage=25;
return View();
}
View:
<div>
Count:#ViewBag.Count
</div>
<div class="progress">
<div class="progress-bar" role="progressbar" style="width: #ViewBag.Percentage%;" aria-valuenow="#ViewBag.Percentage" aria-valuemin="0" aria-valuemax="100">#ViewBag.Percentage%</div>
</div>
<form method="post">
<input hidden name="Count" value="#ViewBag.Count" />
<div class="form-group">
<label asp-for="Phone" class="control-label"></label>
<input asp-for="Phone" class="form-control" />
<span asp-validation-for="Phone" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Email" class="control-label"></label>
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="CreateDate" class="control-label"></label>
<input asp-for="CreateDate" class="form-control" />
<span asp-validation-for="CreateDate" class="text-danger"></span>
</div>
<input type="submit"value="submit" />
</form>
result:

How can I store records in a list request from an HttpPost

How can I store records in a list from an HttpPost request that sends an object
I want to store each record that it processes again from the view
Take the _students object and send it to a list:
List dbTempStudentList
To work locally with data and not depend on a database
[HttpPost]public ActionResult Create(Student _student)
{
return View("");
}
public class Student
{
public int StudentID { get; set; }
public string StudentName { get; set; }
public string StudentLastName { get; set; }
public string Creditbalance { get; set; }
public string CurrentBalance { get; set; }
}
My View Create
<h2>Create</h2>
<h4>Student</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="StudentID" class="control-label"></label>
<input asp-for="StudentID" class="form-control" />
<span asp-validation-for="StudentID" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="StudentName" class="control-label"></label>
<input asp-for="StudentName" class="form-control" />
<span asp-validation-for="StudentName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="StudentLastName" class="control-label"></label>
<input asp-for="StudentLastName" class="form-control" />
<span asp-validation-for="StudentLastName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Creditbalance" class="control-label"></label>
<input asp-for="Creditbalance" class="form-control" />
<span asp-validation-for="Creditbalance" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="CurrentBalance" class="control-label"></label>
<input asp-for="CurrentBalance" class="form-control" />
<span asp-validation-for="CurrentBalance" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</form>
</div>
</div>
[HttpPost]
public ActionResult Create(Student _student)
{
var list = (List<Student>)Session["studentList"];
//this is for first time
if(list==null||list.Count()==0) list = new List<Student>();
list.Add(_student);
Session["studentList"]=list;
return View();
}

Asp-validation-summary="ModelOnly" does not work for compare data-validator

View Does displays Span validation but Validation summary(blank validation-summary div also not present).if i change Asp-validation-summary="All".I am not getting why it is not working with ModelOnly.
My Class
public class RegistrationViewModel
{
[Required]
[EmailAddress]
[MinLength(5)]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Required]
[DataType(DataType.Password)]
[Compare("Password")]
[Display(Name = "Confirm Password")]
public string VerifiedPassword { get; set; }
}
view
<form asp-action="Registration">
<div asp-validation-summary="ModelOnly" val class="text-danger"></div>
<div class="form-group">
<label asp-for="Email" class="control-label"></label>
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Password" class="control-label"></label>
<input asp-for="Password" class="form-control" required />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="VerifiedPassword" class="control-label"></label>
<input asp-for="VerifiedPassword" class="form-control" required/>
#*<span asp-validation-for="VerifiedPassword" class="text-danger"></span>*#
</div>
<div class="form-group">
<input type="submit" value="Register" class="btn btn-default" />
</div>
</form>
Add this to post method in the controller:
if (!ModelState.IsValid)
{
AddErrorsFromModel(ModelState.Values);
return View();
}
Also add using and AddErrorsFromModel to controller:
using Microsoft.AspNetCore.Mvc.ModelBinding;
private void AddErrorsFromModel(ModelStateDictionary.ValueEnumerable values)
{
foreach (ModelStateEntry modelState in values)
foreach (ModelError error in modelState.Errors)
{
ModelState.AddModelError(string.Empty, error.ErrorMessage.ToString());
}
}

Model binding does not work, it brings all parameters null

I have Product Model in ProductCreate view and I am sending product property data from view to controller to ProductCreate Action, but in the controller I get null Product paramater, all Product model properties are null.
What is wrong with my code? Thanks for your helps.
here is my coding. I use FormCollection for Specification(named here Ozellik) data collection.
Product Model
public class Product : EntityBase
{
public Product()
{
this.Photos = new List<Photo>();
this.OrderDetails = new List<OrderDetail>();
this.Suppliers = new List<Supplier>();
this.Comments = new List<Comment>();
this.Ozelliks = new List<Ozellik>();
}
[MaxLength(100, ErrorMessage = "Max 100 karakter."), Required]
public string Name { get; set; }
[Required]
public decimal BuyingPrice { get; set; }
[Required]
public decimal SalesPrice { get; set; }
[Required]
public decimal DiscountedPrice { get; set; }
public decimal VATRatio { get; set; }
[MaxLength(250, ErrorMessage = "Max 3050 karakter."), Required]
public string DescriptionLong { get; set; }
[MaxLength(250, ErrorMessage = "Max 250 karakter."), Required]
public string DescriptionShort { get; set; }
[MaxLength(250, ErrorMessage = "Max 250 karakter."), Required]
public string Brand { get; set; }
[Required]
public string Size { get; set; }
public Gender Gender { get; set; }
public Color Color { get; set; }
public bool IsActive { get; set; }
public decimal? Discount { get; set; }
public int StockQuantity { get; set; }
public int LineNumber { get; set; }
public float CommentAvg { get; set; }
public bool IsNew { get; set; }
public string CategoryName { get; set; }
public virtual Mainproduct Mainproduct { get; set; }
public virtual List<Campaign> Campaigns{ get; set; }
public virtual List<OrderDetail> OrderDetails { get; set; }
public virtual List<Supplier> Suppliers { get; set; }
public virtual List<Photo> Photos { get; set; }
public virtual List<Comment> Comments { get; set; }
public virtual List<Ozellik> Ozelliks { get; set; }
}
my controller ProductCreate Action
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = "Admin")]
public ActionResult ProductCreate(Product Product, FormCollection form)
{
var itemno = 1;
for (int i = 2; i == form.Count; i++)
{
string name = "Name" + itemno;
string description = "Description" + itemno;
string isactive = "IsActive" + itemno;
db.Ozelliks.Add(new Ozellik
{
ProductId = Product.Id,
Name = form["name"].ToString(),
Description = form["description"].ToString(),
IsActive = Convert.ToBoolean(form["isactive"])
});
itemno++;
db.SaveChanges();
}
Product.DiscountedPrice = Product.SalesPrice * (1 - System.Convert.ToDecimal(Product.Discount) / 100);
db.Products.Add(Product);
db.SaveChanges();
ViewBag.CurrentUser = db.Users.Find(WebSecurity.CurrentUserId);
return RedirectToAction("ProductIndex");
}
and my ProductCreate view
#model Product
#{
ViewBag.Title = "Yeni Ürün Giriş";
Layout = "~/Views/Shared/_AdminLayout.cshtml";
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<header class="page-header">
<div class="container-fluid">
<h2 class="no-margin-bottom">Yeni Ürün Ekle</h2>
</div>
</header>
<!-- Breadcrumb-->
<div class="breadcrumb-holder container-fluid">
<!--<ul class="breadcrumb">
<li class="breadcrumb-item">Home</li>
<li class="breadcrumb-item active">Forms </li>
</ul>-->
</div>
<!-- Forms Section-->
<section class="forms">
<div class="container-fluid">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header d-flex align-items-center">
<h3 class="h4">Ürün Bilgileri</h3>
</div>
<div class="card-body">
<form class="form-horizontal">
<div class="form-group row">
<label class="col-sm-3 form-control-label">Ürün Adı</label>
<div class="col-sm-9">
<input type="text" name="Name" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 form-control-label"><br><small class="text-primary"></small></label>
<div class="col-sm-9">
<div class="i-checks">
<input id="checkboxCustom1" type="checkbox" value="" name="IsNew" class="checkbox-template">
<label for="checkboxCustom1">Yeni Ürün Etiketi Olsun Mu?</label>
</div>
</div>
</div>
</form>
</div>
</div>
<div class="card">
<div class="card-header d-flex align-items-center">
<h3 class="h4">Fiyat</h3>
</div>
<div class="card-body">
<form class="form-inline" style="text-align:center">
<label class="col-sm-3 form-control-label"><br><small class="text-primary"></small></label>
<table>
<tr>
<td>Alış Fiyatı</td>
<td>Satış Fiyatı</td>
</tr>
<tr>
<td><input id="inlineFormInput" type="number" name="BuyingPrice" step="any" min="1" class="mr-3 form-control"></td>
<td><input id="inlineFormInput" type="number" name="SalesPrice" step="any" min="1" class="mr-3 form-control"></td>
</tr>
</table>
</form>
<br />
<form class="form-inline" style="text-align:center">
<label class="col-sm-3 form-control-label"><br><small class="text-primary"></small></label>
<table>
<tr>
<td>İndirim Oranı</td>
<td>İndirimli Satış Fiyatı</td>
</tr>
<tr>
<td><input id="inlineFormInput" type="number" name="Discount" step="any" min="1" class="mr-3 form-control"></td>
<td><input id="inlineFormInput" type="number" name="DiscountedPrice" step="any" min="1" class="mr-3 form-control"></td>
</tr>
</table>
</form>
</div>
</div>
<div class="card">
<div class="card-header d-flex align-items-center">
<h3 class="h4">Açıklama</h3>
</div>
<div class="card-body">
<form class="form-horizontal">
<div class="form-group row">
<label class="col-sm-3 form-control-label">Kısa Ürün Açıklaması</label>
<div class="col-sm-9">
<input type="text" name="DescriptionShort" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 form-control-label">Uzun Ürün Açıklaması</label>
<div class="col-sm-9">
<input type="text" name="DescriptionLong" class="form-control">
</div>
</div>
</form>
</div>
</div>
<div class="card">
<div class="card-header d-flex align-items-center">
<h3 class="h4">Diğer</h3>
</div>
<div class="card-body">
<form class="form-horizontal">
<div class="form-group row">
<label class="col-sm-3 form-control-label">Marka</label>
<div class="col-sm-3">
<input type="text" name="Brand" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 form-control-label">KDV</label>
<div class="col-sm-3">
<input type="text" name="VATRatio" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 form-control-label">Kategori</label>
<div class="col-sm-9 select">
<select name="CategoryName" class="form-control">
#foreach (var item in (IEnumerable<SelectListItem>)ViewBag.Categories)
{
<option value=#item.Value id="CategoryName">#item.Text</option>
}
</select>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 form-control-label">Cinsiyet</label>
<div class="col-sm-9 select">
#Html.DropDownListFor(model => model.Gender, new SelectList(Enum.GetValues(typeof(IcatSite.Models.Gender))))
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 form-control-label">Tedarikçiler <br><small class="text-primary"></small></label>
<div class="col-sm-9">
<div>
<select name="Suppliers" class="form-control">
#foreach (var item in (IEnumerable<Supplier>)ViewBag.Suppliers)
{
<option value=#item.Id id="Suppliers">#item.CompanyName</option>
}
</select>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 form-control-label">Aktif mi?</label>
<div class="col-sm-6">
<div class="i-checks" style="width:60px;float:left;margin-right:10px">
<input id="radioCustom1" type="radio" checked="checked" value=true name="IsActive" class="radio-template">
<label for="radioCustom1">Aktif</label>
</div>
<div class="i-checks">
<input id="radioCustom2" type="radio" value=false name="IsActive" class="radio-template">
<label for="radioCustom2">Pasif</label>
</div>
</div>
</div>
</form>
</div>
</div>
<div class="card">
<div class="card-header d-flex align-items-center">
<h3 class="h4">Ürün Özellikleri</h3>
</div>
<div class="card-body">
<div class="form-group row">
<div class="col-lg-8">
<table class="table table-striped table-sm" id="ozellik">
<tr>
<td>Özellik</td>
<td>Değer</td>
<td style="width:80px">Aktif mi?</td>
</tr>
<tr>
<td><input type="text" name="Name0" value=" " /></td>
<td><input type="text" name="Description0" value=" " /></td>
<td><input type="checkbox" checked="checked" value="True" name="IsActive0"></td>
</tr>
</table>
<br />
<div class="box-footer">
<button type="button" id="ozellikbutton" class="btn btn-default">Yeni Özellik Ekle</button>
</div>
</div>
</div>
</div>
</div>
<div class="box-footer">
<button type="submit" class="btn btn-primary">Kaydet</button>
</div>
</div>
</div>
</div>
</section>
}
#section ozellikekle{
<script>
$(document).ready(function () {
var i = 1;
$('#ozellikbutton').click(function () {
$('#ozellik tr:last').after('<tr><td><input type="text" value=" "/></td><td><input type="text" value=" " /></td><td><input type="checkbox" value=" " /></td></tr>');
var name = "Name" + i;
var description = "Description" + i;
var isactive = "IsActive" + i;
$('#ozellik tr:last td:nth-child(1) input:nth-of-type(1)').attr("name", name);
$('#ozellik tr:last td:nth-child(2) input:nth-of-type(1)').attr("name", description);
$('#ozellik tr:last td:nth-child(3) input:nth-of-type(1)').attr("name", isactive);
$('#ozellik tr:last td:nth-child(3) input:nth-of-type(1)').attr("checked", "checked");
i++;
});
});
</script>
}

Display Friendly Error Message When using Decorators in Models

New to ASP.NET Core.
I have a view:
<form asp-action="LogIn">
<div class="form-horizontal">
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="EmailAddress" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="EmailAddress" class="form-control" style="min-width:350px" />
<span asp-validation-for="EmailAddress" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="Password" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Password" class="form-control" style="min-width:350px" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Enter" class="btn btn-default" />
</div>
</div>
</div>
</form>
I have this Model for it:
public class Subscription
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long SubscriptionId { get; set; }
[Display(Name = "Email Address")]
[Required]
[RegularExpression(#"\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*")]
public string EmailAddress { get; set; }
[NotMapped]
public string Password { get; set; }
}
So, when a User types in an email address that is not validated by the regular expression I get the error message:
How do i over-ride this 'default' error message to say (for example):
Email Address is Invalid
?
You need to add ErrorMessage property to the RegularExpression attribute like this-
[RegularExpression(#"\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*", ErrorMessage = "Your friendly message goes here")]

Resources