【问题标题】:Date not binding with model for specific culture日期不与特定文化的模型绑定
【发布时间】:2015-06-12 10:47:16
【问题描述】:

当培养被选择时,我正在尝试在培养物(en-US和FR-FR)模型中绑定日期。 用户选择项目语言来创建条目。例如 : 在 en-US 中添加新闻 |在 fr-FR 中添加新闻

型号:

[Column(TypeName = "datetime2")]
public DateTime CreatedOn { get; set; }

查看:

@Html.TextBox("CreatedOn", Model.CreatedOn, new { @class = "form-control", @id = "datepicker" , @type="text"})

日期选择器和解析脚本:

$(document).ready(function () {
        $('#datetimepicker2').datetimepicker({
            locale: '@Model.CultureInfoCode',
            format: 'L'
        }).data("DateTimePicker").date();
        //$('#datetimepicker2').moment().format("MM/dd/YYYY");
    });

$(document).ready(function () {
    $.validator.methods.date = function (value, element) {
        moment.locale('@Model.CultureInfoCode'); // CultureInfoCode is the culture of item being entered. 
        return moment(value);
        //parseDate(value, null, "@Model.CultureInfoCode");
           // return this.optional(element) || Globalize.parseDate(value) !== null;
        }
});

解析日期似乎也可以正常工作。如果为整个网站选择了文化,则模型将绑定所有值,包括日期(en-US ) 与正在输入的项目的文化相匹配(即用英语添加新闻 (en-US))。但是,当我用法语(fr-FR)添加新闻并将日期输入为 26/01/0001 时,它会绑定除日期以外的所有字段,并将模型中的值设为 1/1/0001,并在显示错误消息的同一视图中返回:

**The value '26/01/0001' is not valid for 'CreatedOn' .**

model.Validate 在控制器中也是 false。

请帮忙。 谢谢

【问题讨论】:

    标签: jquery asp.net-mvc datetime momentjs globalization


    【解决方案1】:

    asp.net mvc 中的默认模型绑定器知道日期本地化问题。要使其以指定的文化解析日期,您需要在调用 action 方法之前设置 CurrentCulture。我知道有几种可能的方法来做到这一点。

    全球化元素

    Globalization element 可以自动将 CurrentCulture 设置为用户的操作系统默认值。网络配置:

    <globalization culture="auto" uiCulture="auto" />
    

    因此,如果用户来自 en-US 本地化操作系统,则日期将以 en-US 格式解析,从 fr-FR 本地化操作系统 - 以 fr-FR 格式解析,依此类推。

    动作过滤器

    如果您需要手动设置 CurrentCulture,您可以使用操作过滤器来执行此操作。更多信息可以在this answer找到。如果在 url 中指定了文化代码,则可以使用此方法。

    定义路线:

    routes.MapRoute(
        "DefaultLocalized",
        "{culture}/{controller}/{action}/{id}",
        new { culture = "en-US", controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
    

    定义动作过滤器:

    public class InternationalizationAttribute : ActionFilterAttribute 
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext) 
        {
            string culture = (string)filterContext.RouteData.Values["culture"] ?? "en-US";
    
            Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(culture);
            Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(culture);
        }
    }
    

    在每个动作/控制器中使用它作为属性或将其添加到 Application_Start() 中的全局过滤器集合中:

    GlobalFilters.Filters.Add(new InternationalizationAttribute());
    

    模型绑定器

    另一种方法是重新实现 DateTime 类型的模型绑定器。更多信息here。例如,您在表单中有文化领域。最简单的模型绑定器:

    public class DateTimeBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var provider = bindingContext.ValueProvider;
            var cultureValue = provider.GetValue("culture");
            var dateValue = provider.GetValue(bindingContext.ModelName);
    
            var cultureInfo = CultureInfo.CurrentCulture;
            if (cultureValue != null)
                cultureInfo = CultureInfo.GetCultureInfo(cultureValue.AttemptedValue);
    
            return dateValue.ConvertTo(typeof(DateTime), cultureInfo));
        }
    }
    

    在 Application_Start() 中将活页夹添加到集合中:

    ModelBinders.Binders.Add(typeof(DateTime), new DateTimeBinder());
    

    【讨论】:

      【解决方案2】:

      感谢ranquild,它解决了这个问题。虽然我从 Request 对象中选择了文化,如下所示。因为我需要用户输入的项目文化,而不是全球化设置。

         public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
                  {
                      string cultureName = controllerContext.HttpContext.Request.Form["CultureInfoCode"];
                      var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
                      System.Globalization.CultureInfo cultureinfo = new System.Globalization.CultureInfo(cultureName);
                      return value.ConvertTo(typeof(DateTime), cultureinfo);
                  }
      

      【讨论】:

        【解决方案3】:

        在我们的例子中,我们在 JQuery 中的视图上设置了一个默认日期,这导致绑定由于某种原因而失败。我们从控制器中删除了设置日期的 JQuery 并在 viewmodel 中设置默认日期以解决问题。

        【讨论】:

          猜你喜欢
          • 2013-10-11
          • 1970-01-01
          • 1970-01-01
          • 2014-04-20
          • 2017-09-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多