开发者

MVC 1 Parameter Binding

I'm passing a date to my server in Invariant Culture, the following format

'mm/dd/yy'

The parameter binding in MVC fails to parse this date and returns null for the parameter. This is persumably because IIS is running on a machine using English culture ('dd/mm/yy' works just fine).

I want to override the parsing of all date on my server to use Invariant Culture like so...

Convert.ChangeType('12/31/11', typeof(DateTime), Cultur开发者_运维问答eInfo.InvariantCulture);

even when the date is part of another object...

public class MyObj
{
    public DateTime Date { get; set; }
}

My controller method is something like this....

public ActionResult DoSomethingImportant(MyObj obj)
{
     // use the really important date here
     DoSomethingWithTheDate(obj.Date);
} 

The date is being sent as Json data like so....

myobj.Date = '12/31/11'

I've tried adding an implementation of IModelBinder to the binderDictionary in the global.asax

binderDictionary.Add(typeof(DateTime), new DateTimeModelBinder());

That doesn't work, and neither does

ModelBinders.Binders.Add(typeof(DateTime), new DataTimeModelBinder());

This seems like some ppl would want to do all the time. I can't see why you would parse dates etc. in the current culture on the server. A client would have to find out the culture of the server just to format dates the server will be able to parse.....

Any help appreciated!


I've solved the problem here, what I had missed was that in the object, the datetime was nullable

public class MyObj
{
    public DateTime? Date { get; set; }
}

Hence my binder wasn't being picked up.

If anyone is interested, this is what I did....

  1. In the global.asax added the following

    binderDictionary.add(typeof(DateTime?), new InvariantBinder<DateTime>());
    
  2. Created an invariant binder like so

    public class InvariantBinder<T> : IModelBinder
    {
        public object BindModel(ControllerContext context, ModelBindingContext binding)
        {
            string name = binding.ModelName;
    
            IDictionary<string, ValueProviderResult> values = binding.ValueProvider;
    
            if (!values.ContainsKey(name) || string.IsNullOrEmpty(values[names].AttemptedValue)
                return null;
    
            return (T)Convert.ChangeType(values[name].AttemptedValue, typeof(T), CultureInfo.Invariant);
        }
    }
    

Hope this comes in handy for someone else.....


Is your problem that your custom model binder is unable to parse some of the input dates or that your custom model binder never gets called? If it's the former then trying to use the culture of the user's browser might help.

public class UserCultureDateTimeModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        object value = controllerContext.HttpContext.Request[bindingContext.ModelName];
        if (value == null)
            return null;

        // Request.UserLanguages could have multiple values or even no value.
        string culture = controllerContext.HttpContext.Request.UserLanguages.FirstOrDefault();
        return Convert.ChangeType(value, typeof(DateTime), CultureInfo.GetCultureInfo(culture));
    }
}

...

ModelBinders.Binders.Add(typeof(DateTime?), new UserCultureDateTimeModelBinder());


Is it possible to pass the date to the server in ISO 8601 format? I think the server would parse that correctly regardless of its own regional settings.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜