How to globalize ASP.NET MVC views (decimal separators in particular)?

穿精又带淫゛_ 提交于 2020-01-10 04:05:07

问题


I'm working with the NerdDinner sample application and arrived at the section which deals with the Virtual Earth map. The application stores some values for the longitude and latitude. Unfortunately on my system floating point numbers are stored with a comma as the decimal separator, not a dot like in the US. So if I have a latitude of 47.64 it's retrieved and displayed as 47,64. Because that value is passed in a function call to the Virtual Earth API it fails at that point (e.g. JavaScript API expects 47.64, -122.13, but gets 47,64, -122,13).

I need to make sure that the application always uses dots. In a WebForms app I would have a common class which overrides the System.Web.UI.Page.InitializeCulture() method and I would be inheriting my pages from that class.

I am not sure about how to do the same with MVC. Do I need a customized ViewPage or something? Is there an easy way to solve this? Examples?


回答1:


Because setting <globalization/> to en-US did not help at all I decided to create a custom class which initializes the proper culture settings and make sure that all views which require this behavior are inherited from my custom class.

NerdDinnerViewPage.cs:

using System.Globalization;
using System.Threading;
using System.Web.Mvc;

namespace NerdDinner.Views
{
    public class NerdDinnerViewPage<T> : ViewPage<T> where T : class
    {
        protected override void InitializeCulture()
        {
            base.InitializeCulture();

            Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentCulture.Clone() as CultureInfo;

            if (Thread.CurrentThread.CurrentCulture != null)
            {
                Thread.CurrentThread.CurrentCulture.NumberFormat.CurrencyDecimalSeparator = ".";
                Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator = ".";
            }
        }
    }
}

Edit.aspx:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="NerdDinner.Views.NerdDinnerViewPage<NerdDinner.Models.DinnerFormViewModel>" %>



回答2:


I'm a Danish developer and was facing exactly the same problem. I found a working solution which has been kindly described by Kristof Neirynck on his dev blog:

Custom Model Binder

Best regards, Finn Vilsbaek




回答3:


When you say

on my system floating point numbers are stored with a comma as the decimal separator

I assume you mean that they are formatted with a comma, floating point numbers are stored as float.

Whilst you can tackle the formatting issue by setting Cultures the "real" fix is to change the code. OK, it's not your code so maybe you don't want to do that on this occassion, but for general reference you need to ensure that when formatting floats or anything else you use the appropriate culture. In the case of fomatting a number for use by an API you would use the InvariantCulture.

I.e. use foo.ToString(CultureInfo.InvariantCulture) instead of foo.ToString() and likewise when using string.Format(...).

Edit I've just taken a look at the NerdDinner code and have realised that this error is in the Javascript not in C#, so my code above isn't going to help. I don't know if it is possible to format numbers in Javascript, but the real solution I think is to fix the model code to return a correctly formatted string.

Edit 2 I'd suggest you try the following: In the SearchController.cs change the Latitude and Longitude in JsonDinner to strings. i.e.

public class JsonDinner {
    public int      DinnerID    { get; set; }
    public string   Title       { get; set; }
    public string   Latitude    { get; set; }
    public string   Longitude   { get; set; }
    public string   Description { get; set; }
    public int      RSVPCount   { get; set; }
}

Then scroll down to the SearchByLocation method and change the Lat/Long lines to format the strings correctly for JavaScript:

Latitude = dinner.Latitude.ToString(CultureInfo.InvariantCulture),
Longitude = dinner.Longitude.ToString(CultureInfo.InvariantCulture),

This should mean that you do not need the fix you put in, and should fix your other question... where I will leave a comment. Hope this helps, I haven't fully tested is as I am not in your locale, but it certainly appears to work.




回答4:


I'm using a simple quickfix in the TemplateEditor. My application is only using swedish (comma as decimal separator) so it's a single string.Replace but you could of course make it aware of multiple cultures.

In my Views/Shared/EditorTemplates/Decimal.ascx:




回答5:


I fixed this on the JavaScript-side instead, making sure that what is passed in to the map-library is using points (.), and what is populated back into the text boxes are using commas (,). Obviously, this is not meant for localization, but a quick fix.

Map.js in callbackForLocation:

//If we've found exactly one place, that's our address.
if (points.length === 1) {
    $("#Latitude").val(points[0].Latitude.toString().replace('.', ','));
    $("#Longitude").val(points[0].Longitude.toString().replace('.', ','));
}

Map.ascx in the jquery-ready():

    var latitude = <%=Model.Latitude.ToString().Replace(',', '.')%>;
    var longitude = <%=Model.Longitude.ToString().Replace(',', '.')%>;


来源:https://stackoverflow.com/questions/760258/how-to-globalize-asp-net-mvc-views-decimal-separators-in-particular

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