2012-04-23 57 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));