Search code examples
.netdata-annotationsglobalizationserver-side

.net DataAnnotation and Globalization issue (server side)


North America's format for dates is MM/dd/yyyy

I am working on project (asp.net MVC 2) for Australia where date format is d/MM/yyyy

in web.config I have

        <globalization
        fileEncoding="utf-8"
        requestEncoding="utf-8"
        responseEncoding="utf-8"
        culture="en-AU"
        uiCulture="en-AU"
        enableClientBasedCulture="true"
    />

in views .net renders dates in right format - "en-AU", but when I submit form with 14/11/2011 date my ModelState.IsValid equals to False.

How to teach dataannoation to properly validate dates in "en-AU" format?

//update

just found that issue related to GET only

using(Html.BeginForm("Search", "form", FormMethod.Post)) //Works
using(Html.BeginForm("Search", "form", FormMethod.Get)) //Does'n work

**Looks like it is a .net bug !!!

I tried on new mvc2/3 projects

when I use GET, mvc binding doesn't use current culture**

Thank you.


Solution

  • Finally I've got solution thank you for tens of different blog posts and articles. Work perfectly, plus you can apply it not just for dates.

    //Global.asax.cs
    protected void Application_Start()
    {
        ModelBinders.Binders[typeof (DateTime)] = new ForceCultureModelBinder<DateTime>();
        ModelBinders.Binders[typeof(DateTime?)] = new ForceCultureModelBinder<DateTime>();
    }
    

    and class

    public class ForceCultureModelBinder<T> : IModelBinder where T : struct
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
                throw new ArgumentNullException("bindingContext");
    
            T? valueAttempt = GetA(bindingContext);
            return valueAttempt == null ? (object) null : valueAttempt.Value;
        }
    
        private T? GetA(ModelBindingContext bindingContext)
        {
            ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
    
            if (valueResult == null)
                return null;
    
            T? result;
            try
            {
                result = (T?) valueResult.ConvertTo(typeof (T), Thread.CurrentThread.CurrentCulture);
            }
            catch (Exception)
            {
                bindingContext.ModelState.AddModelError(
                        bindingContext.ModelName, 
                        ex.InnerException.Message);
                return null;
            }
    
            return result;
        }
    }