2012-04-23 64 views
2

我应该与要求的格式(“DD/MM/YYYY”)格式我所有的日期时间属性的通用日期时间编辑模板:MVC3儿童行动打破我的DateTime编辑模板

@Html.TextBox(string.Empty, Model.ToString("dd/MM/yyyy"), new { @class = "datepicker" }) 

但对于一些原因格式不适合我的孩子的行为。


如果我在做的MainPage @ Html.EditorFor(X => x.MyDate) .cshtml 我得到预期的结果: “23/04/2012”

如果我这样做@ Html.EditorFor(X => x.MyDate)在ChildAction .cshtml 我得到的出乎意料的结果是: “2012-04-24”


我可以确认正在使用的编辑器模板,be澳洲英语,如果我改变它,像这样(注意开头的字符串WTF):

WTF @Html.TextBox(string.Empty, Model.ToString("dd/MM/yyyy"), new { @class = "datepicker" }) 

然后,如果我在ChildAction.cshtml

做@ Html.EditorFor(X => x.MyDate)我得到:“跆拳道2012-04-24”

任何想法?

更新

在我的追求重现此错误的MVC示例应用程序,我发现,其他两两件事是必需的:

public class DateTimeModelBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
     DateTime date; 

     if (DateTime.TryParseExact(value.AttemptedValue, "dd/MM/yyyy", DateTimeFormatInfo.CurrentInfo, DateTimeStyles.AssumeLocal, out date)) 
     { 
      return date; 
     } 

     return base.BindModel(controllerContext, bindingContext); 
    } 
} 

我假设每个人都知道如何连接该向上。另外,在MainPage.cshtml你必须通过模型的第二个参数的RenderAction

@{Html.RenderAction("Child", Model);} 

当传递模型作为第二个参数,MVC使用模型绑定来调用子操作(为什么?)。但是,日期的格式为MM/dd/yyyy,因此它不适用于我的模型联编程序,它假定我所有的日期都是dd/MM/yyyy格式。这就是为什么这不起作用。

但我该如何解决?日期与我的默认格式dd/MM/yyyy不匹配的唯一地方是呈现子动作时。

+0

我不能重现此。你是否使用了一个javascript datepicker库来修改输入值?如果是,请尝试暂时禁用它以查看它是否仍然发生。 – pjumble 2012-04-23 21:38:52

+0

@pjumble查看更新。 – Kelly 2012-04-24 15:30:54

回答

1

问题

MVC使用的ModelState值,如果可能的,但值是在父作用VS孩子行动的模型状态不同:

  • 在父作用,模型状态包含字符串提交给操作的日期(valueproviderresult中的RawValue)或默认值。

  • 当父动作传递给它传递一个的dateTime在模型状态(RawValue在
    的valueproviderresult)的信息提供给子操作
    (的RenderAction)。

因此,在父操作中,如果未提交任何值,则正确使用Textbox(...)中提供的值。如果客户端以相同的格式提交了有效值,则它看起来也可以,因为它将模型状态中的字符串与displaytemplate中生成的字符串相同。

但在孩子的行动,它使用包含日期时间,而不是提交的字符串中的ModelState,MVC然后使用InvariantCulture的所以它会显示MM/DD/YYYY该时间值转换为字符串(我3年后来因此该值可以在框架中已经改变,因为你有YYYY-MM-DD)

解决方案

你需要用你想要的东西来代替值模型中的状态或删除它受影响的值。

public static void Fix(ModelStateDictionary dic, string key) 
{ 
    ModelState modelState = dic[key]; 

    if (!modelState.Errors.Any() && modelState.Value.RawValue != null 
     && (modelState.Value.RawValue is DateTime || modelState.Value.RawValue is DateTime?)) 
    { 
     var sValue = ((DateTime)modelState.Value.RawValue).ToString("dd/MM/yyyy"); 
     var value = new ValueProviderResult(sValue, sValue, CultureInfo.InvariantCulture); 
     dic.SetModelValue(key, value); 

     //or 

     //dic.Remove(key); 
    } 
} 

,然后调用该方法在你的孩子动作:

Fix(ModelState, nameof(viewModel.DateMax));