2016-07-08 5 views
0

Как создать привязку модели для десятичных чисел, которая будет генерировать исключение, если пользователи отправляют его в неправильном формате?Web Api 2 Десятичный разделитель

мне нужно что-то вроде этого:

2 = OK 
2.123 = OK 
2,123 = throw invalid format exception 
+1

Исключение будет выбрано любым способом, если привязка к типу «decimal» не будет выполнена. – Fabio

+0

да, это будет иметь смысл наоборот, но вы хотите по умолчанию. Которое должно это сделать. Вы проверили это? – Liam

+0

@fabio это неправда. Я просто протестировал его. Это зависит от культуры. Я отправил 10,5 на мой api, и он хорошо привязался, но когда я отправил 10,5, он не стал исключением. Он просто устанавливает мое десятичное значение в моей модели как 0, что является десятичным значением по умолчанию. – Robert

ответ

1

Посмотрите на эту статью http://haacked.com/archive/2011/03/19/fixing-binding-to-decimals.aspx/

Вы можете просто использовать стандартное связующее с простой проверкой как этот

public class DecimalModelBinder : IModelBinder 
{ 
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) 
    { 
     ValueProviderResult valueResult = bindingContext.ValueProvider 
      .GetValue(bindingContext.ModelName); 
     ModelState modelState = new ModelState { Value = valueResult }; 
     object actualValue = null; 

     if (valueResult.AttemptedValue.Contains(",")) 
     { 
      throw new Exception("Some exception"); 
     } 
     actualValue = Convert.ToDecimal(valueResult.AttemptedValue, 
      CultureInfo.CurrentCulture); 


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

EDIT: В соответствии с @Liam предложение, вы должны добавить это связующее в свою конфигурацию сначала

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

Выше кода генерирует исключение в случае неудачного разделителя десятичных знаков, но вы должны использовать проверку модели для обнаружения таких ошибок. Это более гибкий способ.

public class DecimalModelBinder : IModelBinder 
{ 
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) 
    { 
     ValueProviderResult valueResult = bindingContext.ValueProvider 
      .GetValue(bindingContext.ModelName); 
     ModelState modelState = new ModelState { Value = valueResult }; 
     object actualValue = null; 
     try 
     { 
      if (valueResult.AttemptedValue.Contains(",")) 
      { 
       throw new Exception("Some exception"); 
      } 
      actualValue = Convert.ToDecimal(valueResult.AttemptedValue, 
       CultureInfo.CurrentCulture); 
     } 
     catch (FormatException e) 
     { 
      modelState.Errors.Add(e); 
      return false; 
     } 

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

Вы не выбрали исключение, а просто добавили ошибку проверки. Вы можете проверить его на своем контроллере позже.

if (ModelState.IsValid) 
{ 
} 
+0

Он хочет, чтобы она выбрала исключение! Вы генерируете исключение, но затем поймаете его. – Liam

+0

Вам нужно добавить о том, как на самом деле привязать это тоже, то есть 'ModelBinders.Binders.Add (typeof (десятичный), новый DecimalModelBinder());' – Liam

+0

Для WebAPI2 'BindModel' метод возвращает 'bool'. Мы не используем MVC здесь – suvroc

Смежные вопросы