2016-12-19 11 views
0

У меня есть проект MVC, где я показываю валютные суммы в разных форматах в зависимости от валюты объекта.
Мой проект обрабатывает формат ##. 00, просто найдите, но у меня есть некоторые объекты, которые используют евро, например, которые должны быть в формате ##, 00 вместо ##. 00.
Затем страница загружается в режиме только для чтения, и оба формата отображаются правильно, но затем форма редактируется, изначально она отображает валюты правильно, но если я выхожу из суммы, отформатированной в евро, она выталкивает "," из сумма (например, 1000,00 изменяется на 100000).
В модели поля DataType = Currency и десятичные числа. Кроме того, если 1000,00 пытается сохранить, он возвращается как недействительный.Отказ текстового поля ##, 00

Как я могу получить текстовое поле для обработки обоих форматов валют?

Это мой код

@model Projections.Web.ViewModels.Projections.ProjectionFormView 

@Html.HiddenFor(model => model.Number) 
@Html.HiddenFor(model => model.Department) 

@* -- Quarters -- *@ 
<div class="edit-fields"> 
    <div class="control-group"> 
     @Html.LabelFor(model => model.Q12017, new {@class = "control-label"}) 
     <div class="controls"> 
      @Html.EditorFor(model => model.Q12017) 
     </div> 
    </div> 
    <div class="control-group"> 
     @Html.LabelFor(model => model.Q22017, new {@class = "control-label"}) 
     <div class="controls"> 
      @Html.EditorFor(model => model.Q22017) 
     </div> 
    </div> 
    <div class="control-group"> 
     @Html.LabelFor(model => model.Q32017, new {@class = "control-label"}) 
     <div class="controls"> 
      @Html.EditorFor(model => model.Q32017) 
     </div> 
    </div> 
    <div class="control-group"> 
     @Html.LabelFor(model => model.Q42017, new { @class = "control-label" }) 
     <div class="controls"> 
      @Html.EditorFor(model => model.Q42017) 
     </div> 
    </div> 
    <div class="control-group"> 
     @Html.LabelFor(model => model.Q12018, new { @class = "control-label" }) 
     <div class="controls"> 
      @Html.EditorFor(model => model.Q12018) 
     </div> 
    </div> 
</div> 

Контроллер:

public ActionResult Edit(string number, string department) 
    { 
     // Get the project we're trying to edit a projection for. 
     var projects = _db.Projects.FindBy(
      x => x.Number == number && 
       x.PMUsername == SessionWrapper.CurrentManager, 
       null, 
       "Projection").ToList(); 

     if (!projects.Any()) 
     { 
      return Error(
       Notices.ProjectNotFoundTitle, 
       string.Format(Notices.ProjectNotFound, number) 
       ); 
     } 

     var project = projects.SingleOrDefault(x => x.Department == department); 
     var baseProject = projects.SingleOrDefault(x => x.Department == string.Empty); 

     // Project doesn't exist, error time! 
     if (project == null || baseProject == null) 
     { 
      return Error(
       Notices.DepartmentNotFoundTitle, 
       string.Format(Notices.DepartmentNotFound, department, number) 
      ); 
     } 

     project.Projection = project.Projection ?? new Projection { Number = number, Department = department, Project = project }; 

     SetProjectCulture(project.ProjectCurrencyCode); 
     var projection = Mapper.Map<ProjectionFormView>(project.Projection); 
     projection.BaseProjectName = baseProject.Name; 

     return View(projection); 
    } 

    private void SetProjectCulture(string currencyCode) 
    { 
     var uiHelper = DependencyResolver.Current.GetService<IThreadUIHelper>(); 

     if (!uiHelper.SetUICulture(currencyCode)) return; 
     var notice = new Notification(string.Format(Notices.ProjectCurrencyNotice, currencyCode)); 
     NotificationHandler.AddNotification(notice); 
    } 

Модель

using System; 
using System.ComponentModel; 
using System.ComponentModel.DataAnnotations; 
using System.Linq; 

namespace Projections.Web.ViewModels.Projections 
{ 
    public class Forecast : INotifyPropertyChanged 
    { 
     private decimal _q12017; 
     private decimal _q22017; 
     private decimal _q32017; 
     private decimal _q42017; 
     private decimal _q12018; 

    [DataType(DataType.Currency)] 
    public decimal Q12017 
    { 
     get { return _q12017; } 
     set { _q12017 = value; ForecastChanged("Q12017"); } 
    } 

    [DataType(DataType.Currency)] 
    public decimal Q22017 
    { 
     get { return _q22017; } 
     set { _q22017 = value; ForecastChanged("Q22017"); } 
    } 

    [DataType(DataType.Currency)] 
    public decimal Q32017 
    { 
     get { return _q32017; } 
     set { _q32017 = value; ForecastChanged("Q32017"); } 
    } 

    [DataType(DataType.Currency)] 
    public decimal Q42017 
    { 
     get { return _q42017; } 
     set { _q42017 = value; ForecastChanged("Q42017"); } 
    } 

    [DataType(DataType.Currency)] 
    public decimal Q12018 
    { 
     get { return _q12018; } 
     set { _q12018 = value; ForecastChanged("Q12018"); } 
    } 

    public decimal Total 
    { 
     get 
     { 
      var quarters = GetType().GetProperties().Where(x => x.Name.StartsWith("Q")).ToList(); 
      return quarters.Sum(q => (decimal?)q.GetValue(this, null) ?? default(decimal)); 
     } 
    } 

    public DateTime? Modified { get; set; } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void ForecastChanged(string name) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); 
    } 

    public decimal? this[string name] 
    { 
     get 
     { 
      var property = GetType().GetProperty(name); 
      if (property == null) throw new InvalidOperationException("Invalid property specified."); 
      if (property.PropertyType == typeof(decimal)) 
      { 
       return property.GetValue(this, null) as decimal?; 
      } 
      throw new InvalidOperationException("Invalid property specified."); 
     } 
    } 
} 

}

+0

Оставьте свой код, будет легче вам помочь. –

ответ

0

Модель по умолчанию связующий обрабатывает только DECIM als с десятичной точкой в ​​стиле США (.). Если вам нужно принять запятую, вам понадобится настраиваемое связующее устройство. Я использую следующее, которое я нашел оригинал here.

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.CurrentCulture); 
     } 
     catch (FormatException e) { 
      modelState.Errors.Add(e); 
     } 

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

Затем, зарегистрировать его в Application_Start в Global.asax:

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

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

+0

Я добавил класс и зарегистрировал его в Global.asax, но у него все еще есть такая же проблема. Нужно ли мне что-то менять, чтобы использовать новое связующее? –