.net 数据注释和全球化问题(服务器端)

发布于 2024-12-16 02:11:46 字数 785 浏览 3 评论 0原文

北美的日期格式是 MM/dd/yyyy

我正在为澳大利亚开发项目(asp.net MVC 2),其中

web.config 中的日期格式为 d/MM/yyyy 我

        <globalization
        fileEncoding="utf-8"
        requestEncoding="utf-8"
        responseEncoding="utf-8"
        culture="en-AU"
        uiCulture="en-AU"
        enableClientBasedCulture="true"
    />

在视图中 .net 以正确的格式呈现日期 - “en-AU”,但是当我提交日期为 14/11/2011 的表单时,我的 ModelState.IsValid 等于 False。

如何教数据注释正确验证“en-AU”格式的日期?

//更新

刚刚发现仅与 GET 相关的问题

using(Html.BeginForm("Search", "form", FormMethod.Post)) //Works
using(Html.BeginForm("Search", "form", FormMethod.Get)) //Does'n work

**看起来这是一个 .net bug !!!

当我使用 GET 时,我尝试了新的 mvc2/3 项目

,mvc 绑定不使用当前区域性**

谢谢。

North America's format for dates is MM/dd/yyyy

I am working on project (asp.net MVC 2) for Australia where date format is d/MM/yyyy

in web.config I have

        <globalization
        fileEncoding="utf-8"
        requestEncoding="utf-8"
        responseEncoding="utf-8"
        culture="en-AU"
        uiCulture="en-AU"
        enableClientBasedCulture="true"
    />

in views .net renders dates in right format - "en-AU", but when I submit form with 14/11/2011 date my ModelState.IsValid equals to False.

How to teach dataannoation to properly validate dates in "en-AU" format?

//update

just found that issue related to GET only

using(Html.BeginForm("Search", "form", FormMethod.Post)) //Works
using(Html.BeginForm("Search", "form", FormMethod.Get)) //Does'n work

**Looks like it is a .net bug !!!

I tried on new mvc2/3 projects

when I use GET, mvc binding doesn't use current culture**

Thank you.

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

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

发布评论

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

评论(3

挽清梦 2024-12-23 02:11:46

此行为是设计使然。当您执行 GET 请求时,它会将日期放入 URL 中。 ASP.NET MVC 假设 URL 中的日期是不变的区域性。

为什么?

假设我创建以下 URL:/posts/01-11-2011/ 并将其发送给您。这对你来说意味着什么?

嗯,这意味着向我展示 2011 年 1 月 11 日的帖子,因为这适合我的文化。但您的文化可能将其表示为 2011 年 11 月 1 日。URL 应唯一标识资源。同一 URL 不应该根据查看它的人而具有不同的含义。

因此,我们决定模型绑定程序不会将 URL 中的值转换为当前区域性,但会转换表单帖子中的值。这对我们来说很有意义,因为表单帖子无法发送,并且通常代表用户的输入。

This behavior is by design. When you do a GET request, it puts the date in the URL. ASP.NET MVC makes the assumption that dates in the URL are invariant culture.

Why?

Well suppose I create the following URL: /posts/01-11-2011/ and send that to you. What does that mean to you?

Well it means show me the posts on January 11, 2011, because that works for my culture. But your culture probably denotes it as November 01, 2011. URLs should uniquely identify a resource. The same URL should not have different meanings depending on who is looking at it.

So we decided that our model binders would not convert values from the URL to the current culture, but would convert values from a form post. That made sense to us because a form post cannot be sent around and generally represents a user's input.

别念他 2024-12-23 02:11:46

最后我得到了解决方案,感谢您提供的数十篇不同的博客文章和文章。工作完美,而且您不仅可以将其应用于约会。

//Global.asax.cs
protected void Application_Start()
{
    ModelBinders.Binders[typeof (DateTime)] = new ForceCultureModelBinder<DateTime>();
    ModelBinders.Binders[typeof(DateTime?)] = new ForceCultureModelBinder<DateTime>();
}

和班级

public class ForceCultureModelBinder<T> : IModelBinder where T : struct
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
            throw new ArgumentNullException("bindingContext");

        T? valueAttempt = GetA(bindingContext);
        return valueAttempt == null ? (object) null : valueAttempt.Value;
    }

    private T? GetA(ModelBindingContext bindingContext)
    {
        ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

        if (valueResult == null)
            return null;

        T? result;
        try
        {
            result = (T?) valueResult.ConvertTo(typeof (T), Thread.CurrentThread.CurrentCulture);
        }
        catch (Exception)
        {
            bindingContext.ModelState.AddModelError(
                    bindingContext.ModelName, 
                    ex.InnerException.Message);
            return null;
        }

        return result;
    }
}

Finally I've got solution thank you for tens of different blog posts and articles. Work perfectly, plus you can apply it not just for dates.

//Global.asax.cs
protected void Application_Start()
{
    ModelBinders.Binders[typeof (DateTime)] = new ForceCultureModelBinder<DateTime>();
    ModelBinders.Binders[typeof(DateTime?)] = new ForceCultureModelBinder<DateTime>();
}

and class

public class ForceCultureModelBinder<T> : IModelBinder where T : struct
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
            throw new ArgumentNullException("bindingContext");

        T? valueAttempt = GetA(bindingContext);
        return valueAttempt == null ? (object) null : valueAttempt.Value;
    }

    private T? GetA(ModelBindingContext bindingContext)
    {
        ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

        if (valueResult == null)
            return null;

        T? result;
        try
        {
            result = (T?) valueResult.ConvertTo(typeof (T), Thread.CurrentThread.CurrentCulture);
        }
        catch (Exception)
        {
            bindingContext.ModelState.AddModelError(
                    bindingContext.ModelName, 
                    ex.InnerException.Message);
            return null;
        }

        return result;
    }
}
油焖大侠 2024-12-23 02:11:46

Hanselman 有一篇关于如何处理此客户端的好文章,他在其中做了类似的事情:

$(document).ready(function () {
        //Ask ASP.NET what culture we prefer
        $.getJSON('/locale/currentculture', function (data) {
            //Tell jQuery to figure it out also on the client side.
            $.global.preferCulture(data);
        });
    });

来源: http ://www.hanselman.com/blog/GlobalizationInternationalizationAndLocalizationInASPNETMVC3JavaScriptAndJQueryPart1.aspx

我确实相信该插件现在称为 globalize(在此处找到),但 API 应该类似,即使不完全相同。

Hanselman has a good post on how to handle this client-side, where he does something like:

$(document).ready(function () {
        //Ask ASP.NET what culture we prefer
        $.getJSON('/locale/currentculture', function (data) {
            //Tell jQuery to figure it out also on the client side.
            $.global.preferCulture(data);
        });
    });

source: http://www.hanselman.com/blog/GlobalizationInternationalizationAndLocalizationInASPNETMVC3JavaScriptAndJQueryPart1.aspx

I do believe that the plugin is now called globalize (found here) but the API should be similar, if not the exact same.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文