How to specify decimal separator for all input fields for a given property? - asp.net-core-mvc

I have a property:
public double FluidAddedQty { get; set; }
I'm rendering an input field for that property in an Edit view
<div class="form-group">
<label asp-for="FluidAddedQty" class="control-label"></label>
<input asp-for="FluidAddedQty" class="form-control" />
<span asp-validation-for="FluidAddedQty" class="text-danger"></span>
</div>
Unfortunately the value is rendered with a comma not a dot as a decimal separator, and I accept dot only on the backend side.
How to make <input> render 100.234 instead of 100,234 ?

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:

Server side validation problem - float value

I have a problem with data validation in my application.
Im using a Razor Pages and .Net Core 3.0 framework with EF Core orm.
In my model I have two properties:
public float WireCrosssection { get; set; }
public float CableLength { get; set; }
On page, I have inputs for them:
<div class="form-group">
<label asp-for="Cable.WireCrosssection"></label>
<input class="form-control" asp-for="Cable.WireCrosssection" />
<span class="text-danger" asp-validation-for="Cable.WireCrosssection"></span>
</div>
<div class="form-group">
<label asp-for="Cable.CableLength"></label>
<input class="form-control" asp-for="Cable.CableLength" />
<span class="text-danger" asp-validation-for="Cable.CableLength"></span>
</div>
Client side validation is turned on and this validation doesn't report problems with the form but the server side one do (ModelState.IsValid is false).
The number is provided with dot (".").
Any suggestions?
Be sure you have added the validation script in your view.
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
Here is a simple demo like below:
1.Model:
public class Test
{
public float WireCrosssection { get; set; }
public float CableLength { get; set; }
}
2.View:
#model Test
<form asp-action="Index">
<div class="form-group">
<label asp-for="WireCrosssection"></label>
<input class="form-control" asp-for="WireCrosssection" />
<span class="text-danger" asp-validation-for="WireCrosssection"></span>
</div>
<div class="form-group">
<label asp-for="CableLength"></label>
<input class="form-control" asp-for="CableLength" />
<span class="text-danger" asp-validation-for="CableLength"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
3.Controller:
[HttpPost]
public IActionResult Index(Test test)
{
//..
}
4.Result:
Reference:Client Side Validation
Ok, I solved the issue. The problem was a mismatch in culture on the server side and on the client side. Client side validation is written in "en-US" culture. To set the culture on the ASP.NET Core application you need to add following code to the Configure method in the Startup.cs class:
var cultureInfo = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;

Why passing a form control to a ViewModel is not working in ASP.NET Core 2.0?

I built a simple ASP.NET Core 2.0 application and I have a simple login view. I am using ASP.NET Core Identity which means I am using "IdentityUser" class
#model LoginViewModel
<h2 class="my-4 text-center text-lg-left">Before contacting us, please log in or
<a asp-action="Register" asp-controller="Account"> register!</a></h2>
<form asp-action="Login" asp-controller="Account" method="post" role="form">
<!-- To show form error after submission -->
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="UserName">User Name</label>
<input type="text" class="form-control" placeholder="Username">
<span asp-validation-for="UserName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Password">Password</label>
<input type="password" class="form-control" placeholder="Password">
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-primary">Log In!</button>
</form>
As you can see, I created a view model called "LoginViewModel" which is going to detect the passed parameters in the submitted form
LoginViewModel
public class LoginViewModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[DataType(DataType.Password)]
public string Password { get; set; }
}
When a user hits "Login" on the form, my ASP.NET tag helpers indicates that the post request is going to hit the "Login" action within the "Account" controller
Here is my "Login" Action
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<IdentityUser> _userManager;
public AccountController(SignInManager<IdentityUser> signInManager, UserManager<IdentityUser> userManager)
{
_signInManager = signInManager;
_userManager = userManager;
}
[HttpGet]
public IActionResult Login()
{
return View(new LoginViewModel());
}
[HttpPost]
public async Task<IActionResult> Login(LoginViewModel loginViewModel)
{
if (!ModelState.IsValid)
{
return View(loginViewModel);
}
var user = await _userManager.FindByNameAsync(loginViewModel.UserName);
if (user != null)
{
var result = await _signInManager.PasswordSignInAsync(user, loginViewModel.Password, false, false);
if (result.Succeeded)
{
return RedirectToAction("Index", "Home");
}
}
ModelState.AddModelError("", "User name/password not found");
return View(loginViewModel);
}
The object "loginViewModel" that I am passing to the "Login" action is null, this means that it is not grabbing the form data on the time the user submits the form.
Any idea what I am missing here, pretty sure it is something stupid?
You're missing the tag helpers on the inputs!!
<div class="form-group">
<label asp-for="UserName">User Name</label>
<input type="text" class="form-control" placeholder="Username"
asp-for="UserName" /> <!-- You're missing this -->
<span asp-validation-for="UserName" class="text-danger"></span>
</div>
My 2 cents:
You don't need to indicate the method="post". That's the default method. Also you might want to specify the area as well, just in case you have multiple controllers with the same name but live in different areas.
<form asp-area="" asp-controller="account" asp-action="login">
....
</form>
When you use tag helper on labels, you don't need to put the text in between. The tag helper will generate that based on your [Display] annotation.
<label asp-for="UserName"></label>
You can use HTML helpers to generate the placeholder text from [Display] as well if you want. That way you don't need to hard code the text on the view.
<div class="form-group">
<label asp-for="UserName"></label>
<input type="text" class="form-control" asp-for="UserName"
placeholder="#Html.DisplayNameFor(x => x.UserName)" />
</div>
You are generating manual html for you inputs and they do not have a name attribute so they do not post a value when the form is submitted.
Change your inputs to use the TagHelpers, which will generate the correct html, including the name attribute and the data-val-* attributes for client side validation
// <input type="text" class="form-control" placeholder="Username">
<input asp-for="UserName" class="form-control" placeholder="Username">
// <input type="password" class="form-control" placeholder="Password">
<input asp-for="Password" class="form-control" placeholder="Username">

Spring4 + Thymeleaf3 Form Validation : bean name #fields not available in templates

I get the below error in my spring4 + thymeleaf3 application when I try to show validation errors in my form template.
Neither BindingResult nor plain target object for bean name '#fields' available as request attribute
My form is as below.
<form th:action="#{/user/save}" method="post" th:object="${user}">
<ul th:if="${#fields.hasErrors()}">
<li th:each="err : ${#fields.errors('*')}" th:text="${err}"></li>
</ul>
<div>
<label>Name</label>
<div>
<input type="text" th:field="*{firstName}" placeholder="First Name">
<input type="text" th:field="*{lastName}" placeholder="Last Name">
<div th:if="${#fields.hasErrors('firstName')}" th:errors="${#fields.errors('firstName')}"></div>
<div th:if="${#fields.hasErrors('lastName')}" th:errors="${#fields.errors('lastName')}"></div>
</div>
</div>...
The form is rendered well for the following get request mapping.
#GetMapping("/create")
public String create(ModelMap model) {
model.put("user", new User());
return VIEW_DIR.concat("form");
}
But it gives the above error when the form is submitted with some invalid fields to the following method.
#PostMapping("/save")
public String save(#Valid User user, BindingResult bindingResult, ModelMap model) {
if(bindingResult.hasErrors()) {
return VIEW_DIR.concat("form");
}
userService.save(user);
return "redirect:list";
}
Can you please show me where the error is.
You are setting wrong values for th:errors inside your form element div. th:errors should contain field name. Update your form with this:
<div>
<input type="text" th:field="*{firstName}" placeholder="First Name">
<input type="text" th:field="*{lastName}" placeholder="Last Name">
<div th:if="${#fields.hasErrors('firstName')}" th:errors="*{firstName}"></div>
<div th:if="${#fields.hasErrors('lastName')}" th:errors="*{lastName}"></div>
</div>

Unable to validate only space in email validation by using [EmailAddress] annotation

I am using [EmailAddress] data annotation to validate email address. I've noticed that if I add space than it is not working. It works fine if I use period, hyphen, underscore but space.
Model:
[DisplayName(#"Custom Email Confirmation Address")]
[EmailAddress(ErrorMessage = #"Invalid Email Address")]
public string CustomEmailConfirmationAddress { get; set; }
Custom Control:
<div>
<%=Html.RequiredLabelFor(m => m.CustomEmailConfirmationAddress) %>
<%=Html.TextBoxFor(m => m.CustomEmailConfirmationAddress, new { maxlength = 100 })%>
<%=Html.ValidationMessageFor(m => m.CustomEmailConfirmationAddress)%>
</div>
On Browser: For space class="textboxhelp-focus valid"
<div>
<label class="required" for="CustomEmailConfirmationAddress">Custom Email Confirmation Address</label>
<input id="CustomEmailConfirmationAddress" class="textboxhelp-focus valid" type="text" value="" name="CustomEmailConfirmationAddress" maxlength="100" data-val-email="Invalid Email Address" data-val="true" help="noreply#example.com" style="width: 300px;">
<span class="field-validation-valid" data-valmsg-replace="true" data-valmsg-for="CustomEmailConfirmationAddress"></span>
</div>
For Underscore: class="textboxhelp-focus input-validation-error"
<div>
<label class="required" for="CustomEmailConfirmationAddress">Custom Email Confirmation Address</label>
<input id="CustomEmailConfirmationAddress" class="textboxhelp-focus input-validation-error" type="text" value="" name="CustomEmailConfirmationAddress" maxlength="100" data-val-email="Invalid Email Address" data-val="true" help="noreply#example.com" style="width: 300px;">
<span class="field-validation-error" data-valmsg-replace="true" data-valmsg-for="CustomEmailConfirmationAddress">
</div>
Am I missing something here?

Resources