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"/>
Related
I am trying to force my asp.net core 3.1 application to use the locale "en-US", no matter the default locale of the Windows server it runs on.
My main goal is to have ModelBinding correctly parse doubles entered by users. So far, I did not have any luck. The comma is interpreted as the decimal separator, whereas the point is interpreted as the thousands separator, which is consistent with the Windows default locale.
So my code looks (simplified) like this:
public class Model
{
public double Percentage {get; set;}
}
[HttpPost]
public ActionResult Index(Model model)
{
Debug.WriteLine(model.Percentage);
}
This results in data entered and posted as "12.34" to be cast to double 1234, etc.
Previously, in ASP.Net MVC 5, adding this to the web.config file solved this issue:
<configuration>
<system.web>
<globalization culture="en-US" uiCulture="en-US" />
I have tried various methods described, which I will list below, but to no avail. These seem to be revolving around localization of the mark-up, but do not affect model binding.
Apply the same settings as listed above.
Adding this to the Startup's ConfigureServices() method:
System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
Adding this to the same method:
services.Configure<RequestLocalizationOptions>(
options =>
{
options.DefaultRequestCulture = new RequestCulture(culture: "en-US", uiCulture: "en-US");
options.SetDefaultCulture("en-US");
});
The latter attempts being merely trial-and-error.
I tried running on IIS and on IIS Express.
I do realize I could write a custom model binder, but I think this adds unneeded complexity. Also, I could skip model binding and parse the post data manually, but the actual models are extensive and contain a lot of data. I do not want to go that way.
Addendum
I could reproduce this behavior with a small demo application. Steps to reproduce:
Create a new web application in Visual Studio .Net 2019 with:
ASP.Net Core Web Application
Web Application (Model-View-Controller)
Add a view model:
public class InputModel
{
[Range(0, 1)]
public double Fraction { get; set; }
}
Replace the index.cshtml with:
#model InputModel
#using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
#Html.LabelFor(m=>m.Fraction)
#Html.TextBoxFor(m=>m.Fraction)
#Html.ValidationMessageFor(m => m.Fraction)
<input type="submit" value="Submit" />
}
Add an action to the conntroller:
[HttpPost]
public IActionResult Index(InputModel input)
{
if (ModelState.IsValid)
{
return Content($"Received fraction: {input.Fraction:E3}");
}
return View(input);
}
On my development Pc:
input 0.5 is invalid and
input 0,5 is valid.
input 0,1 is valid, but the action will output:
Received fraction: 1,000E+000
Adding this to ConfigureServices in Startup.cs:
services.Configure<RequestLocalizationOptions>(
options =>
{
options.SupportedCultures = new List<CultureInfo> { new CultureInfo("en-US") };
options.SupportedUICultures = new List<CultureInfo> { new CultureInfo("en-US") };
options.SetDefaultCulture("en-US");
});
does not make a difference.
Only when I set change settings through Control Panel - Clock and Region - Change date time or number formats, can I make my web application accept the dot as the decimal separator. I do not like having to rely on that.
1.The Tester test my ASP.NET MVC website and report "Cookie not Sent Over SSL(4720)" issues.
2.And they provide me to solve this issue by Add <httpCookies httpOnlyCookies="true" requireSSL="true" /> in Web.config and then I followed the instructions.
3.The problem when i run and test my website the Session and TempData is null when change page. The code below is shown how i set Session and TempData.
3.1 I set Session and TempData when user go to "Home/Index".
public class HomeController : Controller
{
public ActionResult Index()
{
TempData["class"] = "A";
TempData.Keep();
Session["status"] = "NO";
return View();
}
}
3.2 When user change page to "Admin/User" i get TempData["class"] and Session["status"] but both is null.
public class AdminController : Controller
{
public ActionResult User()
{
string userclass = TempData["class"] != null ? TempData["class"].ToString() : "";
string userstatus = Session["status"] != null ? Session["status"].ToSring() : "";
UserModel usermodel = new UserModel(userclass, userstatus);
return View(usermodel);
}
}
If i delete <httpCookies httpOnlyCookies="true" requireSSL="true" /> from Web.config and test again it's work. but it's still issue "Cookie not Sent Over SSL (4720)" when tester test this website.
How to fix this problem?
P.S. Sorry for bad english skill.
If you set your cookies to be sent securely over SSL, then you must enable SSL in IIS Express for this to work.
Visual Studio configures all the necessary things (like your server certificate and the settings) when you select the SSL option for the web host.
You'll find here a full tutorial about it.
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
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
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.