2016-12-19 1 views
0

Ich habe ein MVC-Projekt, wo ich Währungsbeträge in verschiedenen Formaten basierend auf der Währung des Objekts anzeigen.
Mein Projekt behandelt das ##. 00-Format nur, aber ich habe einige Objekte, die beispielsweise Euros verwenden, die im ##, 00-Format anstelle von ##. 00 sein müssen.
Dann lädt die Seite im schreibgeschützten Modus beide Formate korrekt, aber dann wird das Formular bearbeitet, es zeigt zunächst die Währungen korrekt, aber wenn ich aus einem Euro-formatierten Betrag klicke, fällt die "," aus der Betrag (zum Beispiel 1000,00 ändert sich zu 100000).
In dem Modell sind die Felder DataType = Currency und sind Dezimalzahlen. Wenn 1000,00 versucht wird, zu speichern, wird es als ungültig zurückgegeben.Textfeld ablehnen ##, 00 Format

Wie bekomme ich die Textbox, um die beiden Währungsformate zu behandeln?

Dies ist mein Code

@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> 

Controller:

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); 
    } 

Modell

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

Poste deinen Code, es wird dir leichter helfen. –

Antwort

0

Das Bindemittel Standardmodell wird nur DECIM Griff mit einem Dezimalpunkt im US-Stil (.). Wenn Sie ein Komma akzeptieren müssen, benötigen Sie einen benutzerdefinierten Modellbinder. Ich benutze folgendes, was ich ursprünglich gefunden habe 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; 
    } 
} 

Dann registrieren es in Application_Start in Global.asax:

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

Möglicherweise müssen Sie das Modell Bindemittel auf Ihre spezifischen Einsatzszenario ändern. Diese Version konvertiert einfach basierend auf der aktuellen Kultur, aber Sie müssen hier möglicherweise eine andere Art der Verarbeitung vornehmen, wenn Sie sowohl Punkte als auch Kommas als "Dezimalpunkte" behandeln.

+0

Ich habe die Klasse hinzugefügt und in der Global.asax registriert, aber es ist immer noch das gleiche Problem. Muss ich etwas anderes ändern, damit es das neue Modellbinder verwendet? –

Verwandte Themen