Modify the default behavior of the properties of the models - asp.net-mvc

My question isn't ASP.NET Remote Validation only on blur? because I asked to do with model properties.
I'm using a a model with properties, which are reflected in the client's web browser, and then, when I press the submit button, the ErrorMessages are printed in the web browser.
I want that when the client leave the input focused, no when I press the submit button, the server process the request (only the input "disfocused") and, in error case, show the ErrorMessage in the web browser.
My register model:
[DataType(DataType.EmailAddress)]
[Required(ErrorMessage = "El field {0} is obligatory.")]
[Display(Name = "Email")]
[StringLength(80, ErrorMessage = "Email too large.")]
[RegularExpression(#"^([a-zA-Z0-9._-]+)#(outlook|hotmail|yahoo)\.\w{2,}$", ErrorMessage = "Invalid email")]
public string Email { get; set; }

This can been done on the client side with
Layout page needs
#Render.Section("Scripts",required:false)
Your view would then have
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Your Bundle would be . This Bundle is added by default in a standard ASP MVC project in visual studio
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.validate*"
));
The view would then just need a #Html.ValidationMessageFor for each property
see more info here
ASP MVC validation

Related

How to customize the error message for password field in registration form in ASP.NET MVC app?

1- start Visual studio 2013
2- create a project using the default MVC template that Microsoft provides.
3- Run the app and go to http://localhost:2618/Account/Register
4- enter an email address in the form
5- in the password fields enter: 12345678
6- Press Register button
You will see an this error message after form-post-back:
Passwords must have at least one non letter or digit character. Passwords must have at least one lowercase ('a'-'z'). Passwords must have at least one uppercase ('A'-'Z').
Where and how can I customize this message? I tried using data annotations but couldn't find a solution for it. Please give me specific details. I couldn't find an answer after a lot of searching for it even in the stackoverflow.
Thanks
******************** Note ************
The error message is different than the one which is available in AccountViewModels.cs file for the password field:
public class RegisterViewModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
To customize the datatype error messages you need to install the localized NuGet packages for AspNet.Identity.Core for each of the languages you want to support.
E.g. for German
Install-Package Microsoft.AspNet.Identity.Core.de
Note that the localized packages only exist for a few languages.
If you need other languages than the supported ones you will have to do some kind of hack. Have a look at the following, which includes a suggested workaround from one of the developers on the ASP.NET team: Asp.Net Identity Localization PublicKeyToken

ASP.NET 5: Is localization with DisplayAttribute gone?

I am migrating an application from previous ASP.NET version to ASP.NET 5(vNext, MVC 6). Previously I localized forms with DisplayAttribute attached to ViewModel's properties:
[Required(ErrorMessageResourceName = "FieldIsRequired", ErrorMessageResourceType = typeof(Resources.Validation))]
[Display(Name = "UserName", ResourceType = typeof(Resources.Common))]
public string UserName { get; set; }
I added DataAnnotations service:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddViewLocalization(options => options.ResourcesPath = "Resources/Views")
.AddDataAnnotationsLocalization();
}
When I submit an invalid form, an error message gets localized (as specified in the [Required] attribute).
But trying to display the form, I got an exception (No public property "UserName" in the resource class), until I commented out [Display] attribute.
Seems like input labels can't be localized with [DisplayAttribute] anymore?
Thank you!
It is indeed gone. According to the documentation:
The runtime doesn’t look up localized strings for non-validation attributes. In the code above, “Email” (from [Display(Name = "Email")]) will not be localized.
Update 20.03.2017:
Localization of non-validation attributes was re-enabled with the new .NET Core SDK, according to the updated documentation:
DataAnnotations error messages are localized with IStringLocalizer<T>.
Using the option ResourcesPath = "Resources", the error messages in RegisterViewModel can be stored in either of the following paths:
Resources/ViewModels.Account.RegisterViewModel.fr.resx
Resources/ViewModels/Account/RegisterViewModel.fr.resx

Alternative to hardcoding usernames and passwords

I am writing an MVC4 app using C# Razor and all that great stuff. It has full login and password along with an extra 2 questions required before the user can login.
Before I enabled the login feature several months back, it was a dream, I just start the app on the page I was interested in, and it loads away allowing me to instantly see my results.
Occasionally I would start on the wrong page and god forbid I might have to do an extra click or two to get to the right page. I considered this bad enough.
Now that I have enabled the login and since done several modifications to the code, it has been through the testing department, and out to the big bad world. I am not allowed to disable it again.
My alternative was to essentially hardcode the testing username and password and pin with the other default values required and then remove them upon release. Thank god for testing...I actually left them hardcoded once. This was enough to teach me the lesson never to do it again.
However, I start my application literally without exaggeration possibly hundreds (although it feels like thousands) of times a day and every single time I have to fill in this dreaded login form. this is extremely unproductive and really uses up a lot of my time. It actively encourages me to do bad programming habits of changing several things at once and then testing. A road I don't want to start down.
My question: Is there an alternative to this hardcoding practice that will let me get back my productivity?
Please don't suggest allowing the browser to remember the details. I tried, the problem is that my app must be cross browser and platform compatible which means it not only has to run in windows browsers (which has enough variation in themselves), but also on tablets, phones and even lunix and macs. So relying on the browser to remember the details is simply not an option.
Any suggestions.
Based on suggestions below I decided to explore the web/user.config route, here are my attempts so far which are not working.
Model:
public class LogOnModel
{
[Required]
[Display(Name = "User name")]
[StringLength(255, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 8)]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
[StringLength(255, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
public string Password { get; set; }
}
Controllers:
public ActionResult Login()
{
LogOnModel model = new LogOnModel();
model.UserName = ConfigurationManager.AppSettings["UserName"];
model.Password = ConfigurationManager.AppSettings["Password"];
return View("Login");
}
[HttpPost]
public ActionResult Login(LogOnModel model, string returnUrl)
{
model.UserName = ConfigurationManager.AppSettings["UserName"];
model.Password = ConfigurationManager.AppSettings["Password"];
//I am aware that this will presently overwrite the incoming model if it exists.
//I am just trying to get something work here and I will surround it with an if afterward.
if (ModelState.IsValid)
{
... Other code here
}
... Other code here (there are a variety of returns this is a long method with lots of checks
}
View:
#model YeatsClinical.PatientPortal.Web.Models.LogOnModel
...Lots of other code...
#Html.TextBoxFor(x=>x.UserName, new { #class = "m-wrap placeholder-no-fix", #placeholder="Username"})
...Lots of other code...
I didn't bother trying the password yet, I just wanted to get one thing working first.
Web.Config:
<appSettings file="user.config">
User.Config
<appSettings>
<add key="UserName" value ="someone#somewhere.com"/>
<add key="Password" value ="password"/>
</appSettings>
There are no longer any web/user.config errors or any build errors. It just loads a nicely formatted textbox with the placeholder text as before. So where am I going wrong. Thanks again everyone.
Put your login details in your local web.config file. Your code will look for the config values, and if there, will auto-fill them in for you. You can leave this code in when you deploy - since those values are not in the config file in production, you won't have to worry about it running there.
Or you can put them in a separate config file, like user.config, and reference that in your main config. Your user.config file will never be published. Just make sure your deployment practice doesn't bring this file in.
Web.config:
<configuration>
<appSettings file="user.config">
<!-- put your normal config values here -->
</appSettings>
</configuration>
user.config (only your local machine - not in source control, and not on the server)
<appSettings>
<add key="defaultUser" value ="someUser"/>
<add key="defaultPassword" value ="somePassword"/>
</appSettings>
Another alternative might be to use conditional compilation, assuming you're in debug mode locally and release in release mode.
#if DEBUG
PopulateTheUserCredentials();
#endif

Validation with DataAnnotations in Azure shows wrong Text

We creating a windows azure website in MVC4 and we are using dataannotation to set the display-name and also to validate the input fields. It is a multilanguage page and thus we are unsing Resource-Files to translate.
[Display(ResourceType = typeof(GlobalResource), Name = "LitZip")]
[Required(ErrorMessageResourceType = typeof(GlobalResource), ErrorMessageResourceName = "ErrRequiredZip")]
public string ZIP { get; set; }
Local all works perfect. Uploaded on windows azure all shows fine too but the errors after validation are not translated. When I'm returning the CurrentCulture, it's correctly set to german. We are using the custom tool "PublicResXFileCodeGenerator" to generate the resource files.
Hope anybody can help us with this issue.
thanks in advance!
kind reagrds
Edit:
The culture is set by a filterattribute as follows:
var culture = new CultureInfo("de-de");
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
Edit 2013-05-02:
I'm currently setting the culture in the ActionFilterAttribute. When I set the culture in the web.config-File it all works.
<globalization culture="de-DE" uiCulture="de-DE" />
Nevertheless, I need to be able to change the culture on runtime individual for the users. Maybe the ActionFilterAttribute is the wrong position here? I need to access cookie data..
Add this line to Web.Config file.
<globalization uiCulture="auto:ru-RU" culture="auto:ru-RU" requestEncoding="utf-8" responseEncoding="utf-8"/>

asp.net mvc validation must be a number custom error

I am new to asp.net and I have a problem. When the users insert in a editor for a decimal field something other than numbers, they get an error "Field name" is not a number. But I don't want them to receive this message I want them to receive another message. I have no problem with this with required and range validators.
Is there any way for me to do this?
I am not refering necessarily to changing the culture just displaying another message.
Thanks.
Hope I understand your, to change RangeValidator ErrorMessage just initialize ErrorMessage parameter:
[Range(0, 100, ErrorMessage = "Some another error message insert here!")]
[RegularExpression("\d", ErrorMessage = "!!!")]
public decimal DecimalField { get; set; }
This is the actual answer:
Create a class CustomClientDataTypeModelValidatorProvider. Copy the code from the MVC sources. Change the method MakeErrorString to output the appropiate message like this:
private static string MakeErrorString(string displayName)
{
return string.Format(
CultureInfo.CurrentCulture,
Core.Resources.Errors.EroareNuENr,
displayName);
}
I couldn't find a way not to copy the code just extend it as it uses this static method.
If anyone knows this please tell me.
Then, in global.asax, I wrote this:
var cdProvider = ModelValidatorProviders.Providers.SingleOrDefault(p => p.GetType().Equals(typeof(ClientDataTypeModelValidatorProvider)));
if(cdProvider != null)
{
ModelValidatorProviders.Providers.Remove(cdProvider);
ModelValidatorProviders.Providers.Add(
new CustomClientDataTypeModelValidatorProvider());
}
so that the flow would actually be routed to my class and not the class in the asp.net MVC dll
I got the idea from here:
Unfortunately this is is not a trivial task. However you can try the following hack...
Better to do this only on essential fields, as this is more code to maintain.
In the controller's action method
if(ModelState.IsValid)
{
// code
}
else
{
if (ModelState["YourField"].Errors.Count > 0)
{
ModelState["YourField"].Errors.Clear();
ModelState.AddModelError("YourField", "Your custom message here");
}
// code
}
You can set ResourceClassKey of ClientDataTypeModelValidatorProvider class to name of a global resource that contains FieldMustBeNumeric key to replace mvc validation error message of number with your custom message. Also key of date validation error message is FieldMustBeDate.
ClientDataTypeModelValidatorProvider.ResourceClassKey="MyResources"; // MyResource is my global resource
See here for more details on how to add the MyResources.resx file to your project:
The field must be a number. How to change this message to another language?
To change the error message you get after server side validation you need to change 'PropertyValueInvalid' key in your resource file and assign the resource file name to DefaultModelBinder.ResourceClassKey. See this question for details: localize default model validation in mvc 2
Look for solution at the end of this page:
http://jwwishart.wordpress.com/2010/03/22/custom-server-and-client-side-required-validator-in-mvc-2-using-jquery-validate/
I checked this in my MVC 3 RTM project and it works well.
... or use jQuery to change to message on the client.
A quick and simple hack for Customize RangeValidator ErrorMessage --"'Field name' is not a number"-- is using RegularExpression
[Range(0.5, 1000, ErrorMessage = "Amount should be in range {1} to {2}.")]
[DataType(DataType.Currency)]
[RegularExpression(#"\d", ErrorMessage = "Amount is not valid.")]
public decimal Amount{ get; set; }
You could implement your own custom validation attribute: http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx
It seems that since Para's answer MVC evolved and now the ClientDataTypeModelValidatorProvider accepts a ResourceClassKey property. It uses the FieldMustBeNumeric and FieldMustBeNumeric messages specified in your resource class.

Resources