Display/Edit a Currency in ASP.NET MVC Core, why so complicated?

家住魔仙堡 提交于 2019-12-22 10:47:05

问题


In an ASP.NET Core 2.0 application, I have a Foo class with a lot of classical string or numeric members and also a int? Budget field.

using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace MyProj.ViewModels {
    public class RecordEditViewModel {
        public RecordEditViewModel() { }

        public string Name { get; set; }
        public string Prop1 { get; set; }
        public string Prop2 { get; set; }
        public string Prop3 { get; set; }
        public string Prop4 { get; set; }    
        public string Prop5 { get; set; }

        /// <summary>The project budget</summary>        
        //[Range(0, int.MaxValue, ErrorMessage = "Must be a positive number")]
        [Display(Name = "Budget REVM"), 
         DataType(DataType.Currency), 
         DisplayFormat(NullDisplayText = "-", 
                       ApplyFormatInEditMode = true, 
                       DataFormatString = "{0:C}")]
        public int? Budget { get; set; }

        public string Prop6 { get; set; }
        public string Prop7 { get; set; }
        public string Prop8 { get; set; }
        public DateTime CreatedOn { get; set; }    
        public string Prop9 { get; set; }
        public string Prop10 { get; set; }        
        public string Prop11 { get; set; }    
        [Display(Name = "Attachments"), UIHint("IFromFile")]
        public IEnumerable<IFormFile> Attachments { get; set; }
        public string Id { get; set; }
    }
}

I want to
a) display it in the 14 000 € format
b) edit it in the 14 000 € format

this is a classic behavior, display/edit a currency in the currency format, but is seems hard to implement in the latest Microsoft .NET Framework.

a) CustomModelBinder? Should rewrite a binder for all the rest of the fields, but I need only the Budget
b) TypeConverter?
c) DataType(DataType.Currency)? does not seem to work in edit mode (not in display for int?)

My view:

<div class="col-md-6">
    <label asp-for="Budget" class="control-label"></label>
    <div>
        <input asp-for="Budget" class="form-control" />
        <span asp-validation-for="Budget" class="text-danger"></span>
    </div>
</div>

回答1:


I noticed that InputTagHelper has a Format property, which means one can write :

<input asp-for="Budget" asp-format="{0:C}" class="form-control" />

Finding that though was not easy. It wasn't mentioned in the Input Tag Helper section of the intro. In the end I found it through ASP.NET Core MVC Input Tag Helper Deep Dive

Now I understand why people say ASP.NET Core's documentation is lacking - the intro goes to great lenghts to explain the various tag helpers in a single article, explains their relation to HTML Helpers, but ommits significant properties like Format. Without direct link to the class's documentation, it takes a bit of digging to find it.

There are quite a few similar questions in SO with answers that say "you can't format" or propose custom solutions.

UPDATE

An issue was opened on July 2017 about POSTing currency values that included a currency symbol. The thread is insteresting as it explains that asp-format only affects display, so the recommended solution is to put the symbol outside the input, possibly using Bootstrap input groups :

The recommended solution here is to place the currency indicator outside of the editable field (e.g. before or after)

Perhaps something like this:

<div class="input-group">
    <input asp-for="Budget" asp-format="{0:#,###.00}" class="form-control" />
    <span class="input-group-addon">€</span>
</div>



回答2:


My biggest finding was to ensure you are not just rendering the field via your own tag within the .cshtml; rather, ensure you are using the @Html.EditorFor() syntax to render the field:

                <div class="col-md-10">
                    @Html.EditorFor(model => Model.AmountPaid)
                    <span asp-validation-for="AmountPaid" class="text-danger" />
                </div>

Once I used this, the validation worked correctly. You can also decorate your field, such as:

    [DataType(DataType.Currency)]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal AmountPaid { get; set; }

https://docs.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/validation?view=aspnetcore-2.2



来源:https://stackoverflow.com/questions/48205531/display-edit-a-currency-in-asp-net-mvc-core-why-so-complicated

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!