如何使用 InvariantCulture 只渲染某些特定的模型字段,而其余部分继续使用用户区域性?

发布于 2024-10-22 17:31:01 字数 700 浏览 7 评论 0原文

我在 ASP.NET MVC 视图上有几个隐藏的输入。它们的值包含 double 类型的对象。我希望它们使用 InvariantCulture 进行渲染,因为它们被用来提供给客户端上的 api(谷歌地图)。现在,它们使用逗号 (,) 作为小数分隔符来呈现,而 api 需要使用点 (.) 作为小数分隔符。

最好的解决方案是,如果我可以在模型属性的 DisplayFormat 数据注释属性中指定区域性,但我认为这是不可能的:

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

我也不能只设置 <在我的 Application_Start 方法中将 code>CurrentCulture 更改为 InvariantCulture,因为屏幕上还有其他值必须采用正确的用户区域性。

那么,有没有一种方法可以在我为该特定属性执行 Html.HiddenFor(Model => Model.Latitude) 之前临时更改当前区域性,然后再重置它?

或者还有其他更好的方法吗?与此相关的最佳实践是什么?

I have a couple of hidden inputs on an asp.net mvc view. Their values contain objects of type double. I want them to be rendered with the InvariantCulture as they are used to be fed to an api (google maps) on the client. As it is now, they get rendered with a comma (,) as decimal separator, while the api expects a point (.) as decimal separator.

The nicest solution would be if I could specify a culture in the DisplayFormat data annotation attribute on the property on the model, but I don't think that is possible:

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

I can't also just set the CurrentCulture to InvariantCulture in my Application_Start method, as there are other values on the screen which have to be in the proper user culture.

So, is there a way to just temporarily change the current culture, right before I do an Html.HiddenFor(Model => Model.Latitude) for that specific property, and then reset it afterwards?

Or is there another better way of doing this? What is considered best practice concerning this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一紙繁鸢 2024-10-29 17:31:01

实现此目的的一种方法是编写自定义编辑器模板 ~/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

One way to achieve this would be to write a custom editor template ~/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" })

and then on your model:

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

and finally on your view:

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

or if you wanted all doubles in your application to behave like this use the ~/Views/Shared/EditorTemplates/Double.cshtml without any UIHint.

镜花水月 2024-10-29 17:31:01

我最终为模型中的特定子对象 Position 创建了一个模板 (Position.chtml),如下所示:

@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 是个好习惯吗?我不知道有任何其他方法可以做到这一点(除了将其包含在母版页中,我不想这样做,因为我不需要在所有页面上都使用它)而不必重复自己。我想保持这个干燥...

另外(我最好为此问一个新问题):就像现在一样,我有这个模板两次,一次作为编辑器模板,一次作为显示模板。唯一的区别是 attachMap 的最后一个参数对于编辑器模板必须为 true,对于显示模板必须为 false。有没有简单的方法可以让这个变干?

I ended up creating a template (Position.chtml) for a specific sub-object Position in my model like this:

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

This way, I don't need to add any attributes to the model class.

I'm wondering though... is it good practice including javascript like this? I don't know of any other way to do it (except including it in the master page, which I don't want to do as I don't need it on all pages) without having to repeat myself. I'd like to keep this DRY...

Also (I might better ask a new question for this): As it is now, I have this template 2 times, once as an editor template, once as a display template. The only difference is that the last parameter to attachMap has to be true for the editor template and false for the display template. Is there an easy way to make this DRY?

咋地 2024-10-29 17:31:01
    public static MvcHtmlString HiddenForInvariant<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
    {
        var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        var id = string.Format("{0}", metadata.PropertyName);
        var compile = expression.Compile();
        string value = Convert.ToString(compile(htmlHelper.ViewData.Model), CultureInfo.InvariantCulture);
        var hidden = htmlHelper.Hidden(id, value).ToHtmlString();
        return new MvcHtmlString(hidden);
    }
    public static MvcHtmlString HiddenForInvariant<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
    {
        var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        var id = string.Format("{0}", metadata.PropertyName);
        var compile = expression.Compile();
        string value = Convert.ToString(compile(htmlHelper.ViewData.Model), CultureInfo.InvariantCulture);
        var hidden = htmlHelper.Hidden(id, value).ToHtmlString();
        return new MvcHtmlString(hidden);
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文