Как глобализировать представления ASP.NET MVC (в частности, десятичные разделители)?

Я работаю с примером NerdDinner application и перешел в раздел, посвященный карте виртуальной Земли. Приложение сохраняет некоторые значения долготы и широты. К сожалению, в моей системе числа с плавающей запятой хранятся с запятой в качестве десятичного разделителя, а не с точкой, как в США. Итак, если у меня широта 47,64, она извлекается и отображается как 47,64. Поскольку это значение передается при вызове функции в Virtual Earth API, в этой точке происходит сбой (например, JavaScript API ожидает 47.64, -122.13, но получает 47,64, -122,13 < / em>).

Мне нужно убедиться, что приложение всегда использует точки. В приложении WebForms у меня был бы общий класс, который переопределяет метод System.Web.UI.Page.InitializeCulture(), и я бы унаследовал свои страницы от этого класса.

Я не уверен, как сделать то же самое с MVC. Мне нужен индивидуальный ViewPage или что-то в этом роде? Есть ли простой способ решить эту проблему? Примеры?


person Pawel Krakowiak    schedule 17.04.2009    source источник
comment
Похоже, что это уже зарегистрировано как ошибка: nerddinner.codeplex.com/WorkItem /View.aspx?WorkItemId=2616   -  person Steve    schedule 17.04.2009
comment
Хм. Может это баг? Я добавил ‹globalization /› в свой web.config, чтобы убедиться, что культура настроена как en-US для всего приложения, но это совсем не помогло, только после этого я разместил здесь.   -  person Pawel Krakowiak    schedule 23.04.2009


Ответы (5)


Поскольку установка <globalization/> на en-US совсем не помогла, я решил создать настраиваемый класс, который инициализирует правильные параметры культуры и гарантирует, что все представления, требующие такого поведения, унаследованы от моего настраиваемого класса.

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>" %>
person Pawel Krakowiak    schedule 27.04.2009

Я датский разработчик и столкнулся с той же проблемой. Я нашел рабочее решение, которое Кристоф Нейринк любезно описал в своем блоге разработчиков:

Пользовательская привязка модели

С уважением, Финн Вилсбек

person Community    schedule 15.08.2009

Когда ты говоришь

в моей системе числа с плавающей запятой хранятся с запятой в качестве десятичного разделителя

Я предполагаю, вы имеете в виду, что они отформатированы с запятой, числа с плавающей запятой хранятся как float.

Хотя вы можете решить проблему форматирования, установив Культуры, «реальное» исправление - это изменение кода. Хорошо, это не ваш код, поэтому, возможно, вы не хотите делать это в данном случае, но для общей справки вам необходимо убедиться, что при форматировании float или чего-либо еще вы используете соответствующую культуру. В случае создания числа для использования API вы должны использовать InvariantCulture.

Т.е. используйте foo.ToString(CultureInfo.InvariantCulture) вместо foo.ToString() и аналогично при использовании string.Format (...).

Изменить. Я только что взглянул на код NerdDinner и понял, что эта ошибка находится в Javascript, а не в C #, поэтому мой приведенный выше код не поможет. Я не знаю, можно ли форматировать числа в Javascript, но реальное решение, на мой взгляд, - исправить код модели, чтобы он возвращал правильно отформатированную строку.

Изменить 2. Я предлагаю вам попробовать следующее: В SearchController.cs измените Latitude и Longitude в JsonDinner на strings. т.е.

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

Затем прокрутите вниз до метода SearchByLocation и измените строки Lat / Long, чтобы правильно отформатировать строки для JavaScript:

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

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

person Steve    schedule 17.04.2009
comment
Я нахожусь в главе 11 этой книги. Еще не видел этого класса JsonDinner. :) Спасибо за усилия, Стив, я скоро проверю (и дам вам знать)! - person Pawel Krakowiak; 08.05.2009
comment
Я проработал до раздела «Интеграция карты с формами создания и редактирования», и тут он сломался. Вы, наверное, смотрели версию SVN, и это может быть другой код. Я просто слежу за книгой, пишу ее / наклеиваю. - person Pawel Krakowiak; 08.05.2009
comment
Да, мое исправление только продвинет вас немного дальше, я боюсь ... проблема в том, что VE Javascript просто не может справиться с разделителями запятой - либо переданными, либо извлеченными. Вы можете решить проблему с их передачей, используя мое исправление, но когда вы пытаетесь сохранить форму, отправленные обратно данные содержат. разделители снова и не могут быть проанализированы репозиторием :-( - person Steve; 08.05.2009
comment
Возможно, вы сформулировали это лучше, но, по сути, я пытался сказать именно это с самого начала. Я до сих пор не понимаю, почему тег ‹globalization /› в web.config не исправляет это. Я ожидал, что он будет работать так же, как в приложении WebForms. - person Pawel Krakowiak; 11.05.2009

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

В моих представлениях / Shared / EditorTemplates / Decimal.ascx:

person Jonas Stensved    schedule 24.05.2010

Вместо этого я исправил это на стороне JavaScript, убедившись, что то, что передается в библиотеку карт, использует точки (.), А то, что заполняется обратно в текстовые поля, использует запятые (,). Очевидно, это не для локализации, а для быстрого исправления.

Map.js в 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 в jquery-ready ():

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