In the ViewModel, I have Data Annotations for few fields.
public class EmployeeContactInfoVM
{
[Key]
public int slNo { get; set; }
[Required]
[Display(Name = "Employee GlobalView ID *")]
[StringLength(8,MinimumLength = 8,ErrorMessage ="GV ID should be 8 digits")]
[RegularExpression(#"^[0-9]+$", ErrorMessage = "Please use Numeric data")]
public string EmployeeID { get; set; }
[Required]
[Display(Name = "First Name *")]
[RegularExpression(#"^[a-zA-Z]+[ ]*[a-zA-Z]*$", ErrorMessage = "Please use letters")]
public string FirstName { get; set; }
}
My View code is given below
#model EmployeeContactInformation.ViewModel.EmployeeContactInfoVM
#using EmployeeContactInformation.Classes;
#{
ViewBag.Title = "Index";
}
#section Scripts
{
<script src="https://www.google.com/recaptcha/api.js?render=#ViewBag.SiteKey"></script>
<script>
function CreateToken() {
$.blockUI();
grecaptcha.execute('#ViewBag.SiteKey', { action: 'homepage' }).then(function (token) {
document.getElementById("tokenID").value = token;
document.EmpContactFrm.submit();
});
}
</script>
}
#using (Html.BeginForm("Index", "EmployeeContactInformation", FormMethod.Post, new { name ="EmpContactFrm", id = "EmpContactFrmID" }))
{
<div class="form-horizontal" role="form">
<hr />
#Html.ValidationSummary(true)
<input type="hidden" id="tokenID" name="token" />
<div class="form-group" style="margin-bottom:5px">
#Html.LabelFor(model => model.EmployeeID, new { #class = "col-md-2 editor-label" })
<div class="col-md-10 inputText">
#Html.TextBoxFor(model => model.EmployeeID, htmlAttributes: new { #title = "Employee
GlobalView ID should consist of 8 digits and in some countries it may start with a leading
zero" })
#Html.ValidationMessageFor(model => model.EmployeeID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FirstName, new { #class = "editor-label col-md-2" })
<div class="inputText col-md-10">
#Html.TextBoxFor(model => model.FirstName)
#Html.ValidationMessageFor(model => model.FirstName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SurName, new { #class = "editor-label col-md-2" })
<div class="col-md-10 inputText">
#Html.TextBoxFor(model => model.SurName)
#Html.ValidationMessageFor(model => model.SurName)
</div>
</div>
<div class="form-group">
<div class="col-md-10">
<input type="button" value="Submit" class="btn btn-create btnSave" style="font-size:
large;font-weight: 600;padding: 10px;" />
</div>
</div>
}
The form gets submitted in CreateToken function ( document.EmpContactFrm.submit(); ).
I am assuming that all of the validations happen at client Side as I have included
in configuration file.
Some of the validation happen at Client side for e.g If I input 7 digit EmployeeID, I get an message saying "GV ID should be 8 digits".
When I submit the form without entering for mandatory fields, client Side validation doesn't work, the control comes to Action Method.
I have included Server Side Validation like if(ModelState.IsValid) in the code, this will now throw validation error when I miss Mandatory fields.
Do I need to include validation at both Server & Client End?
I was assuming that if we include jquery unobtrusive file & the above mentioned config settings, validations can be purely at client side.
Please let me know
Change this line from
#Html.ValidationSummary(true)
to
#Html.ValidationSummary()
Read this answer
Related
I get my model name wrongly
instead of getting this way
<input class="text-box single-line" data-val="true" data-val-required="آدرس دریافت محصول اجباری میباشد." id="Address" name="Address" type="text" value="">
it renders it this way
<input class="text-box single-line" data-val="true" data-val-required="آدرس دریافت محصول اجباری میباشد." id="mod_Address" name="mod.Address" type="text" value="">
and my model defined this way:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using identity2.Models;
namespace identity2.ViewModels
{
public class OrderIndexViewModel
{
public products Product { get; set; }
public int Count_order { get; set; }
[Required(ErrorMessage = "آدرس دریافت محصول اجباری میباشد.")]
[Display(Name = "آدرس دریافت محصول")]
public string Address { get; set; }
[Display(Name = "سفارش به صورت آفلاین")]
public bool OfflineOrder { get; set; }
[Required(ErrorMessage = "تاریخ دریافت محخول را انتخاب کنید")]
[Display(Name = "تاریخ دریافت محصول")]
[RegularExpression(#"^([1][34]\d{2}\/((1[0-2]|[1-9]))\/(3[01]|[12][0-9]|[1-9]))$", ErrorMessage = "تاریخ معتبر نمیباشد")]
public string recive_date { get; set; }
}
}
and my view:
#model IList<identity2.ViewModels.OrderIndexViewModel>
#using System.Globalization;
#using identity2.Models;
#{
var mod = Model[0];
var dt = DateTime.Now;
PersianCalendar pc = new PersianCalendar();
var timenow = #pc.PearsianDate(dt);
}
<h4>سبد خرید</h4>
<div class="alert alert-warning alert-dismissible fade show" role="alert">
<strong>توجه!</strong> <p>کلیه محصولات در روز پنج شنبه از ساعت 13 الی 19 به صورت رایگان ارسال میگردد در غیر این صورت هزینه پیک بر عهده مشتری می باشد.</p>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<table class="table table-responsive">
<tr>
<th>نام محصول</th>
<th>تعداد سفارش </th>
<th>قیمت کل</th>
<th>عملیات</th>
</tr>
#if (Model != null)
{
foreach (var protoype in Model)
{
var totalprice = #protoype.Product.price * #protoype.Count_order;
<tr>
<td>
#protoype.Product.title
</td>
<td>
#protoype.Count_order
</td>
<td>
#totalprice تومان
</td>
<td>
</i>
</td>
</tr>
}//end foreach
}
</table>
<div class="row">
<div class="col">
<h3>سفارش آنلاین</h3>
#using (Html.BeginForm("CartPaymentPost", "Order", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="row">
<div class="col-md-6">
#if (!ViewData.ModelState.IsValid)
{
#Html.ValidationSummary("", new { #class = "alert alert-warning alert-dismissible fade show" })
}
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => mod.Address, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextAreaFor(model => mod.Address, new { #class = "form-control ", #rows = 5, #cols = 20, #id = "editor1" })
#Html.ValidationMessageFor(model => mod.Address, "آدرس الزامی میباشد", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => mod.recive_date, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => mod.recive_date, null, "recive_date", new { htmlAttributes = new { #class = "form-control", #id = "PersianDate" } })
#Html.ValidationMessageFor(model => mod.recive_date, "تاریخ معتبر نمیباشد!", new { #class = "field-validation-error " })
</div>
</div>
<div class="form-check">
#Html.LabelFor(model => mod.OfflineOrder, htmlAttributes: new { #class = "control-label col-md-2" })
#Html.EditorFor(model => mod.OfflineOrder, null, "OfflineOrder", new { htmlAttributes = new { #class = "form-check-input" } })
#Html.ValidationMessageFor(model => mod.OfflineOrder, "", new { #class = "field-validation-error " })
</div>
<div class="form-row">
<div class="col col-md-offset-2">
<input type="submit" value="پرداخت" class="btn btn-success" />
#*<a class="btn btn-default" href="/Order/BookPayment/"> <i class="fas fa-shopping-cart"></i> سفارش آفلاین </a>*#
</div>
</div>
}
</div>
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
And it cause a problem that cant bind my fields name to model when I use forms and what I cant figure out is why it just not recognizes address field but there no problem with other fields.
You need to use Html.TextArea (or write out the <input ...> by hand) instead of the Html.TextAreaFor.
You need to check the difference between control and controlFor (see below)
"Ultimately they both produce the same HTML but Html.TextBoxFor() is strongly typed where as Html.TextBox isn't.
Generally two things:
The typed TextBoxFor will generate your input names for you. This is usually just the property name but for properties of complex types can include an underscore such as 'customer_name'
Using the typed TextBoxFor version will allow you to use compile time checking. So if you change your model then you can check whether there are any errors in your views."
Please refer the :
Html.Textbox VS Html.TextboxFor
difference between Html.TextBox and Html.TextBoxFor
ASP.NET MVC 4 override emitted html name and id
You try with this, It will work
#Html.TextArea("Address",mod.Address, new { #class = "form-control ", #rows = 5, #cols = 20, #id = "editor1" })
I have few textbox that validates when its empty, but they dont work well. Below is my logic from the model to view, what could i be missing? Currently these textbox dont seem to work and no error when i inspect from the browser. The application is on asp.net mvc using bootstrap.
[DataType(DataType.EmailAddress)]
[Required(ErrorMessage = "This field is required")]
[RegularExpression(#"^\w + ([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*$")]
public string Email { get; set; }
// View
<div class="row">
<label for"Email">Email:</label>
<div class="input-group col-md-4 col-md-offset-2 col-sm-2 col-xs-2">
<div class="input-group pull-right">
#Html.TextBoxFor(m => m.Email, new { #class = "form-control", type = "text", id = "email", autofocus = "autofocus", placeholder = "example#example.com", required = "required" })
#Html.ValidationMessageFor(m => m.Email, " ", new { #class = "text-danger" })
<div class="input-group-append">
<div class="input-group-text">
</div>
</div>
</div>
</div>
</div>
NB: even if i use #html.EditorBoxFor(m=>m.Email, new {Form...}) still nothing and no error.
I've created new MemberType with some extra custom properties, marked as Mandatory.
In the registration form I want these properties to be set as required, so if you don't fill them, you won't be able to proceed with the registration of a new member.
In the Member section, the properties are correctly set as Mandatory.
Here's a screenshot: https://i.ibb.co/bR4sd2v/immagine.png
Here's my code of the registration form:
using (Html.BeginUmbracoForm<UmbRegisterController>("HandleRegisterMember"))
{
<div class="row justify-content-center no-gutters">
<div class="col-8 mx-auto pt-5">
#Html.ValidationSummary("registerModel", true)
#if (registerModel.MemberProperties != null)
{
<div class="form-row justify-content-center">
<div class="form-group col-md-6">
#Html.TextBoxFor(m => registerModel.MemberProperties[0].Value, new { #class = "form-control rounded-0", #placeholder = registerModel.MemberProperties[0].Name})
#Html.HiddenFor(m => registerModel.MemberProperties[0].Alias)
#Html.ValidationMessageFor(m => registerModel.MemberProperties[0].Alias)
</div>
<div class="form-group col-md-6">
#Html.TextBoxFor(m => registerModel.MemberProperties[1].Value, new { #class = "form-control rounded-0", #placeholder = registerModel.MemberProperties[1].Name})
#Html.HiddenFor(m => registerModel.MemberProperties[1].Alias)
#Html.ValidationMessageFor(m => registerModel.MemberProperties[1].Alias)
</div>
</div>
}
<div class="form-row justify-content-center pt-5">
<div class="form-group col-md-6">
#Html.TextBoxFor(m => registerModel.Email, new { #class = "form-control rounded-0", #placeholder = "Email"})
#Html.ValidationMessageFor(m => registerModel.Email)
</div>
<div class="form-group col-md-6">
#Html.PasswordFor(m => registerModel.Password, new { #class = "form-control rounded-0", #placeholder = "Password"})
#Html.ValidationMessageFor(m => registerModel.Password)
</div>
</div>
<div class="form-row justify-content-center pt-5">
<div class="form-group col-md-6">
<button class="btn btn-light text-uppercase w-100" type="submit">Registrati</button>
</div>
</div>
</div>
</div>
#Html.HiddenFor(m => registerModel.MemberTypeAlias)
#Html.HiddenFor(m => registerModel.RedirectUrl)
#Html.HiddenFor(m => registerModel.UsernameIsEmail)
}
I expect that when I click on the Sumbit button (in my case is "Registrati"), under the input fields will appear the validation message saying that those fields are required. And the registration could not proceed until I fill them.
Like it happens with the standard fields Email and Password. Here's a screenshot: https://i.ibb.co/z2cD3TC/immagine.png
How can I check if those fields are required, and show the error message?
Your fields may be required within Umbraco, but the code in your views doesn't know that. In order to achieve validation through the HTML Helpers you're using, you'll need to create a ViewModel like this:
public class MyViewModel
{
[Required(ErrorMessage = "Full name is required")]
public string FullName { get; set; }
[Required(ErrorMessage = "Email is required")]
public string Email { get; set; }
[Required(ErrorMessage = "Password is required")]
[DataType(DataType.Password, ErrorMessage = "Password is invalid")]
public string Password { get; set; }
}
Your HTML helpers should then understand which fields are required and which aren't, which means you can get both clientside validation as well as serverside validation :)
Currently im working on a project where i have two buttons.
"Windows Login" and "Login". When i click on "Windows Login" i would like to submit the form and before submitting i would like to change my model choosenProvider string property value to "Windows".
Here is my model:
public class LogInUserViewModel
{
public LogInUserViewModel() { }
[Required]
[Display(Name = "Name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
public string ReturnUrl { get; set; }
public string ChoosenProvider { get; set; } = "idsrv";
}
And here is my Razor page:
<body>
<div class="background">
<div class="login-area">
<br />
<div class="login-title">Control Unit Registry</div>
<br />
#Html.ValidationSummary(true, "", new { #class = "text-warning-login" })
<div class="holder-form-login">
<div class="form-group">
<div class="text-login">
#Html.LabelFor(model => model.UserName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.UserName, new { htmlAttributes = new { #class = "input-name-login" } })
#Html.ValidationMessageFor(model => model.UserName, "", new { #class = "text-warning-login" })
</div>
</div>
</div>
<br />
<div class="form-group">
<div class="text-login">
#Html.LabelFor(model => model.Password, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Password, new { htmlAttributes = new { #class = "input-password-login" } })
#Html.ValidationMessageFor(model => model.Password, "", new { #class = "text-warning-login" })
</div>
</div>
</div>
</div>
#Html.HiddenFor(x => x.ChoosenProvider)
<div class="form-group">
<div class="holder-button-login">
<br />
<input type="submit" value="Login" class="button-login" />
</div>
</div>
<br />
<br />
<div class="form-group">
<div class="holder-button-login">
<br />
<input type="submit" value="Windows Login" class="button-login" onclick="chooseWindowsProvider()" />
</div>
</div>
<br />
<br />
<br />
<br />
<div class="link-register-login">
Register
</div>
</div>
</div>
</body>
This is the only page what i have in razor and it completely drives me mad.
You can see that i was experiencing with:
#Html.HiddenFor(x => x.ChoosenProvider)
And javascript onclick() but it did not change the value.
So to SUM UP:
I dunno how to change choosenProvider property value to "Windows", and then submit the form, on button click.
Any help is appreciated.
Okey i finally found it out, i hope it will help someone in the future, also please not that intelisense will might tell you that x or y function on field dont even exists but they do.
So the solution was that js was executed later then the submit, so the thing you need to do is:
Change the button type to <input type="button" from type="submit"
Then insert the following script at the end of your file
<script>
function chooseWindowsProvider() {
document.getElementById('ChoosenProvider').value = 'Windows';
document.getElementById('loginForm').submit();
}
</script>
So we are basically submitting the form from js rather then from the button so this way we can assign the string value before the submitting.
Some additional info:
#Html.HiddenFor(x => x.ChoosenProvider)
Already contains an id because its HTML result is:
<input id="ChoosenProvider" name="ChoosenProvider" type="hidden" value="idsrv" />
And finally how you can add an id to your form:
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "loginForm"}))
I´m new in MVC, and I´m working in a simple FORM, but,I have a problem,
for some reason I want to change the bound model in the controller operation and
render the view, but this not happen.
For example:
public class Product{
int id {get; set;}
string description {get; set;}
}
and the controller method:
[POST]
public ActionResult Edite(Product p){
p.description = "HELLOOOOOO!!!"
return View(P);
}
the view:
#model WebSite.Models.Product
#{
ViewBag.Title = "Modificar (Product)";
}
<h2>Modificar (Product)</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4></h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.Id)
<div class="form-group">
#Html.LabelFor(model => model.description, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.description, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Guardar" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Volver a la Lista", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
but in the rendered view, the description of the product is not "HELLOOOOO!!!!".
Why MVC render the view with the user entered values and not with the new model I want?
maybe isn't the best way to resolve the problem, but this post solved my problem:
Asp.net MVC ModelState.Clear