Localization messages in Fluent validation (MVC3) - c#

In my MVC 3 application I am using fluent validation.
public class AccountModelValidator : AbstractValidator<AccountModel>
{
public AccountModelValidator()
{
m.NewPassword).WithMessage(Translator.Data["ConfirmPasswordValidation"]);
}
}
For localization I am using an example that I have found from here, but I have found that I have the same validation message for all languages.
The reason is that validator doesn't know that I have change the language.
How can I correctly do this?
Maybe I should use WithLocalizedMessage but it works only with .resx

When the WithLocalizedMessage returns the same value for all languages, most likely the culture isn't set yet (this happens on a POST, where the action handlers haven't run yet)
Solution is to set the culture in a different location:
Best place to set CurrentCulture for multilingual ASP.NET MVC web applications

Related

ASP.NET MVC application : could not localize MessageFormat in ApplicationUserManager.RegisterTwoFactorProvider in IdentityConfig.cs

In a standard ASP.NET MVC (5.2.7) application with Identity (2.2.1) I'm trying to localize the message sent during the two factor authentication.
I have both PhoneNumberTokenProvider and EmailTokenProvider.
There is also a project with *.resx files containing the text messages in different languages.
In the application the current language is set based on custom language cookie.
And in every controller or view if I use Resources.<<message_name>> I get the text of the specific message for the CurrentCulture (Resources is the class name for the text resources project).
Now in IdentityConfig.cs I have:
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
...
// Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
// You can write your own provider and plug it in here.
manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser>
{
MessageFormat = Resources.MESSAGE_PHONE
});
This ApplicationUserManager.Create method is called on every request and so the RegisterTwoFactorProvider. The problem is that the Resources.MESSAGE_PHONE return always the message corresponding to the server locale - it does not change when another language is set on the page.
The context parameter has the right language cookie.
So the question would be why in IdentityConfig\ApplicationManager.Create method Resource.MESSAGE_PHONE does not return the message in the proper language (as in every controller or view). The project is relatively big and maybe there is some setting for the controllers and view, which I overlook ...
How could one solve this problem?
Thanks in advance!
The answer is quite easy if you know where to look.
In my case the CurrentCulture is set in the global.asax.cs file in Application_AcquireRequestState and it is triggered after the ApplicationUserManager.Create method from the IdentityConfig.cs so in the ApplicationUserManager.Create the CurrentThread has only the default culture.
A solution would be to move the code setting the culture of the CurrentThread into the Application_BeginRequest method in the global.asax.cs which gets triggered before the ApplicationUserManager.Create method in the IdentityConfig.cs.
Full info here

ASP.NET local resources' Culture property scope

I have an ASP.NET 5 application and I am currently implementing a localization.
Resources are located in the ASP.NET folder App_LocalResources and everything is working properly. At least, while it is in development phase. I have the following ResourceCultureFilterAttribute:
using MyProject.App_LocalResources;
public class ResourceCultureFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
string language = GetClientLanguageFromCookiesDoesntMatter();
var culture = new CultureInfo(language);
GlobalResources.Culture = culture;
}
}
And now I access it this way in Razor view:
#GlobalResources.SomeResourceName
Now, I am worrying that Culture propery of auto-generated resource class is static.
Does it mean that this property is set per-thread or per-application-pool (please, specify the right one) but not per-user?
If yes, then several users will just override and use the single value and definitely cause problems to localization.
I know how to fix it by replacing direct access by:
#GlobalResources.ResourceManager.GetString("ResourceName",
new CultureInfo(GetClientLanguageFromCookiesDoesntMatter());
But, maybe, there is a more proper solution - something important that I just don't see or don't know. Maybe, there is a special property like CurrentUserCulture, special multi-user resource class, attribute or something else to provide a simple and plain localization into an ASP.NET project.

skip all Umbraco magic for single method

I was just assigned to implement one functionality in project that uses Umbraco. My job is to basically generate specific XML and return it to user. However i cannot get it to work, because when i create new controller (i've tried creating
Controller, RenderMvcController and SurfaceController
) and method in it (also if i just create new method in existing controller), i get error 404 after typing url into browser. Example: I create TestController and method Index in it. I've tried combinations where TestController was derived from RenderMvcController or SurfaceController or just Controller. After compiling, etc. when i run
http://my_address/Test
or
http://my_address/Test/Index
i get 404 error from umbraco. I looked at another pages in umbraco that were already in project and they all are also configured somehow in umbraco web panel:
http://my_address/umbraco
I aslo tried adding new methods to existings controllers, but no luck (again 404 errors). I've never worked with umbraco and i don't know how to configure it. I just want to know if there is any way to create method which will be accessible at:
http://my_address/MyMethod
or
http://my_address/MyController/MyMethod
and would return just exactly what i will program it to (without any Views, Partial Views, etc. - i can set Headers and ContentType manually and my content is pure text) in an existing Umbraco project without having to deal with umbraco admin panel?
Thanks for any help :)
//Edit
My mind is officially blown... My response is culture dependent (i mean i pull different data from db depending on country), but it's not as simple as
CurrentCulture.CultureInfo
Umbraco is configured to return different culture based on domain extension (Germany for .de, Great Britain for .co.uk, and Dennmark for .dk - it's just a manual configuration in umbraco admin panel assigning different culture info and views to different hostnames). Regular controllers get this modified culture from
RenderModel.CurrentCulture
passed as argument to controller's method. Is there a way to create umbraco controller/method/anthing that will not have layout/model assigned to it (so i can display pure XML data i receive from external service) and still have access to umbraco's RenderModel's culture? What i am trying to create is if user types url:
http://my_address.de/myController/myMethod
my controller will get current culture, call external service passing culture as parameter and display received data without wrapping it in any views. Example:
public class myController : SomeBaseUmbracoControllerOrsomething
{
public string/XmlDocument/ActionResult myMethod(RenderModel model)
{
int countryId = myFunctionToTranslateCultureToCountryId(model.CurrentCulture);
return MethodThatCallsExternalServiceAndReturnsXml(countryId);
}
}
Sorry for confusion, but i've learned about this whole mess with countries just now...
You don't want to use
controller, because this is not picked up by umbraco routing process
you don't want to use RenderMvcController, because this is overkill
you don't want to use Surfacecontroller because you are not using a Child action or form.
What you need is a UmbracoApiController (http://our.umbraco.org/documentation/Reference/WebApi/) or is your umbraco version is PRE 6.1 then use /Base extention (http://our.umbraco.org/documentation/Reference/Api/Base/Index)
Or if you really want to skip ALL umbraco magic for a certain route, add the path to the web.config/AppSettings/umbracoReservedUrls.

ASP.NET MVC Client-side validation with MvcContrib FluentHtml

What's the recommended way to do client-side validation using the built-in MVC2 code with MvcContrib's FluentHtml builders? We're using the jQuery client-side validation code, not the default Microsoft AJAX stuff, if that matters (though I don't think it should).
It seems the client-side validation only gets registered with jQuery Validate when you place a validation message (Html.ValidationMessageFor(x => x.FirstName)) on the page. MvcContrib's FluentHtml this.ValidationMessage(x => x.FirstName) only works with ModelState on the server side, doesn't write out any HTML if there's no error, and doesn't register the given property with jQuery Validate on the client-side.
So my question: is there a way to make the current trunk build of MvContrib work with MVC2's built-in client-side validation somewhat painlessly right now? If so, how? If not, is there another client-side validation that's recommended (other than xVal, which we're currently using and has been depreciated)? Should this be patched in MvcContrib so it works properly? A last resort would be to move to using ASP.NET MVC's built-in input builders, but we already invested a lot in MvcContrib's and would rather not.
Thanks!
Im in the exact same situation...i came across this post with in interesting comment further down although I couldn't quite get it to work.
http://lunaverse.wordpress.com/2008/11/24/mvcfluenthtml-fluent-html-interface-for-ms-mvc/
If you can make any sense of it would be good to post it back up here.
Paul
I got the comment from that blog article working Paul, and modified it to use all the known MVC validation adapters instead of just the Required one (basically mimicking much of what's in the framework itself). It gets kind of hairy with how it displays the error message and working with what we already have, and I implemented a patch for MVC Contrib to work with it, but in the end I'm giving up for now until MVC3 is finialized and MVC Contrib builds against it. No point in going through all this when there's an updated release coming soon.
Here's what I ended up with (FluentViewPage<T> is where we add behaviors):
public class ClientsideValidationBehavior<T> : IBehavior<IMemberElement> where T : class
{
private readonly FluentViewPage<T> _viewPage;
public ClientsideValidationBehavior(FluentViewPage<T> viewPage)
{
_viewPage = viewPage;
}
public void Execute(IMemberElement element)
{
var attribute = element.GetAttribute<ValidationAttribute>();
if (attribute == null)
{
return;
}
var formContext = _viewPage.ViewContext.FormContext;
var fieldMetadata = formContext.GetValidationMetadataForField(UiNameHelper.BuildNameFrom(element.ForMember), true);
var modelMetadata = ModelMetadata.FromStringExpression(element.ForMember.Member.Name, _viewPage.ViewData);
var validators = ModelValidatorProviders.Providers.GetValidators(modelMetadata, _viewPage.ViewContext);
validators.SelectMany(v => v.GetClientValidationRules()).ForEach(fieldMetadata.ValidationRules.Add);
fieldMetadata.ValidationMessageId = element.ForMember.Member.Name + "_Label";
}
}
Hope that helps some.

NHibernate Validation Localization with S#arp Architecture

I'm trying to localize error messages from NHibernate.Validator. From what I have read, the messages should automaticaly be localized if I set the CurrentCulture/CurrentUICultule ; wich I tried without success. I'm using S#arp Architecture with the default configuration. As I said, the only thnig I changed is the CurrentCulture/CurrentUICultule.
Do I have to create a custom message interpolator for nhibernate validator?
I have posted in my blog about creating a Custom Interpolator that overrides the default messages if they exist in your resources. It allows you to override the default messages and add new messages for your validators.
Check it out: NHibernate Validator Custom Messages
Changing the culture for was not a good idea, since all my website is in spanish, so the path that I took was to create a SpanishMessageInterpolator and then set it up in my nhv.config like:
<property name="message_interpolator_class">NHibernateValidator.SpanishMessageInterpolator, Assembly</property>
And finally I did modify my global.asax.cs file to include the nhv.config file on NHibernate initialization, like:
NHibernateSession.Init(
webSessionStorage,
new string[] { Server.MapPath("~/bin/Assembly.dll") },
new AutoPersistenceModelGenerator().Generate(),
Server.MapPath("~/NHibernate.config"), Server.MapPath("~/nhv.config"));

Categories

Resources