当我们选择文化时,我正试图在两种文化(en-US和fr-FR)的模型中绑定日期。 用户选择用于创建条目的Item语言。例如 : 在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"})
datepicker和解析的脚本:
$(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在控制器中也是假的。
请帮忙。 感谢
答案 0 :(得分:1)
asp.net mvc中的默认模型绑定器知道日期本地化问题。要使其在指定区域性中解析日期,您需要在调用操作方法之前设置CurrentCulture。我知道几种可行的方法。
Globalization element可以自动将CurrentCulture设置为用户的操作系统默认值。 web.config中:
<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());
答案 1 :(得分:1)
谢谢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);
}
答案 2 :(得分:0)
在我们的例子中,我们在JQuery中的视图上设置了一个默认日期,由于某种原因导致绑定失败。我们删除了设置日期的JQuery,并从控制器中设置了viewmodel中的默认日期,以解决问题。