开发者

Model Binding to Custom Types with different localization

开发者 https://www.devze.com 2023-03-19 07:51 出处:网络
I have a custom binding of objects array into IEnumerable bookings in a controller action HTML: <input class=\'textBox\' name=\'bookings[0].Date\' type=\'text\' value=\'0开发者_开发问答1/01/2001\

I have a custom binding of objects array into IEnumerable bookings in a controller action

HTML:

<input class='textBox' name='bookings[0].Date' type='text' value='0开发者_开发问答1/01/2001' />
<select name='bookings[0].StartTime' class='startTime'>
  <option value="7">7:00</option>
  <option value="7.5">7:30</option>
  <option value="8">8:00</option>
  <option value="8.5">8:30</option> 
</select>
<select name='bookings[0].EndTime' class='endTime'>
  <option value="7">7:00</option>
  <option value="7.5">7:30</option>
  <option value="8">8:00</option>
  <option value="8.5">8:30</option> 
</select>
....
<input class='textBox' name='bookings[5].Date' type='text' value='01/01/2001' />
<select name='bookings[5].StartTime' class='startTime'>
<select name='bookings[5].EndTime' class='endTime'>

Controller action:

public ActionResult CreateEvent(IEnumerable<BookingDetails> bookings)
{
  ....
}

And container class for binding

public class BookingDetails
{
    public string Date { get; set; }
    public float StartTime { get; set; }
    public float EndTime { get; set; }
}

"bookings" collection of controller action parameter contains data absolutely properly if culture of the page is en-US but if it is "fr-FR" floating values for time come as 0. ex:

-- Date: 1/1/2001 - StartTime: 0 - EndTime: 10 -- Date: 1/1/2001 - StartTime: 11 - EndTime: 0

where 0 appears decimal value was selected: 8.5 or 12.5 for example. I can't have values with comma and period for different cultures because of sophisticated javascript calculation on the page which supports only period for floating numbers.

Does anybody know a workaround to send data to the controller with "invariant" culture type? Thanks


you can create a custom modelbinder for float values only like

public class DecimalModelBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext,
            ModelBindingContext bindingContext)
        {
            ValueProviderResult valueResult = bindingContext.ValueProvider
                .GetValue(bindingContext.ModelName);
            ModelState modelState = new ModelState { Value = valueResult };
            object actualValue = null;
            try
            {
                actualValue = Convert.ToDecimal(valueResult.AttemptedValue,
                    CultureInfo.InvariantCulture);
            }
            catch (FormatException e)
            {
                modelState.Errors.Add(e);
            }

            bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
            return actualValue;
        }
    }

and then you can register it in global.asax in Application_Start

ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());

For code sample and detail explanation have a look at phil haack's post. I have just changed the Culture to invariant culture when calling Convert.ToDecimal

0

精彩评论

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

关注公众号