Как визуализировать только некоторые определенные поля модели с помощью InvariantCulture, в то время как остальные продолжают использовать культуру пользователей?

У меня есть несколько скрытых входных данных в представлении asp.net mvc. Их значения содержат объекты типа double. Я хочу, чтобы они отображались с помощью InvariantCulture, поскольку они используются для передачи в API (карты Google) на клиенте. Как и сейчас, они отображаются с запятой (,) в качестве десятичного разделителя, в то время как API ожидает точку (.) в качестве десятичного разделителя.

Лучшее решение было бы, если бы я мог указать культуру в атрибуте аннотации данных DisplayFormat для свойства модели, но я не думаю, что это возможно:

public class Position
{
    [DisplayFormat(DataFormatString="{0:G}, CultureInfo.InvariantCulture")]
    public double Latitude;
    ...
}

Я также не могу просто установить CurrentCulture в InvariantCulture в моем методе Application_Start, так как на экране есть другие значения, которые должны соответствовать культуре пользователя.

Итак, есть ли способ просто временно изменить текущую культуру прямо перед тем, как я сделаю Html.HiddenFor(Model => Model.Latitude) для этого конкретного свойства, а затем сбросить его после этого?

Или есть другой лучший способ сделать это? Что считается лучшей практикой в ​​этом отношении?


person fretje    schedule 14.03.2011    source источник


Ответы (2)


Один из способов добиться этого — написать собственный шаблон редактора ~/Views/Shared/EditorTemplates/InvariantDouble.cshtml:

@{
    object modelValue = string.Format(
        System.Globalization.CultureInfo.InvariantCulture,
        ViewData.ModelMetadata.DisplayFormatString, 
        ViewData.ModelMetadata.Model
    );
}
@Html.TextBox("", modelValue, new { @class = "text-box single-line" })

а затем на вашей модели:

[DisplayFormat(DataFormatString="{0:G}")]
[UIHint("InvariantDouble")]
public double Latitude;

и, наконец, на ваш взгляд:

@Html.EditorFor(x => x.Latitude)

или если вы хотите, чтобы все двойники в вашем приложении вели себя так, используйте ~/Views/Shared/EditorTemplates/Double.cshtml без UIHint.

person Darin Dimitrov    schedule 14.03.2011
comment
Спасибо, но что, если у меня также есть атрибут [HiddenInput(DisplayValue=false)] в свойстве? - person fretje; 14.03.2011
comment
@fretje, тогда переопределите HiddenInput.cshtml. Брэд Уилсон описывает шаблоны по умолчанию в этом сообщении блога: bradwilson.typepad.com/blog/2009/10/ - person Darin Dimitrov; 14.03.2011
comment
Я сделал это немного по-другому... см. мой ответ. - person fretje; 15.03.2011

В итоге я создал шаблон (Position.chtml) для конкретного подобъекта Position в моей модели следующим образом:

@model Models.Position 
@{
    var latitude = string.Format(System.Globalization.CultureInfo.InvariantCulture, 
                                 "{0:G}", Model.Latitude);
    var longitude = string.Format(System.Globalization.CultureInfo.InvariantCulture, 
                                  "{0:G}", Model.Longitude); 
} 
@Html.Hidden("Latitude", latitude) 
@Html.Hidden("Longitude", longitude) 
<p /> 
<div id="mapCanvas"></div>

<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 
<script type="text/javascript" src="@Url.Content("~/Scripts/maps.js")"></script>
<script type="text/javascript">
    $(function () {
        attachMap($('#mapCanvas'), $('#Position_Latitude'), $('#Position_Longitude'), true);
    }) 
</script>

Таким образом, мне не нужно добавлять какие-либо атрибуты в класс модели.

Мне интересно, хотя ... это хорошая практика, включая такой javascript? Я не знаю другого способа сделать это (кроме включения его в главную страницу, чего я не хочу делать, поскольку мне это не нужно на всех страницах) без необходимости повторяться. Я бы хотел, чтобы это было СУХИМ...

Кроме того (я мог бы лучше задать новый вопрос для этого): Как и сейчас, у меня есть этот шаблон 2 раза, один раз как шаблон редактора, один раз как шаблон отображения. Единственное отличие состоит в том, что последний параметр attachMap должен быть true для шаблона редактора и false для шаблона отображения. Есть ли простой способ сделать это СУХИМ?

person fretje    schedule 15.03.2011
comment
Старый пост, но я все равно добавлю свои два цента... Сначала ваши скрипты ~/Scripts/map.js и скрипт Google Maps будут включаться каждый раз, когда будет отображаться этот частичный вид. Может быть плохо, если вы показываете более одной карты в одном представлении. Кроме того, если у вас более одной карты, вы можете настроить идентификатор mapCanvas, чтобы он был уникальным на странице. В-третьих, вы можете использовать другое частичное представление, которое вызывается как редактором, так и шаблоном отображения, и получать информацию для attachMap логических параметров. - person Johnny5; 14.09.2011