2017-08-02 42 views
1

我有一個TimeSpan?屬性在我的模型中,我有一個視圖試圖通過引導datetimepicker以'hh:mm a'格式獲得12小時的時間值。MVC模型綁定不工作12小時Timespan

當我通過視圖分配12小時時,我的模型不斷拒絕該值,我可以看到分配給該屬性的值始終爲空。 (當我使用24小時的時候,這工作正常)。此外,如果我不輸入時間,並留下提示空視圖的作品。

這是我的看法

 <div class="form-group"> 
      @Html.Label("Time", new { @class = "control-label col-form-label text-right" }) 
      <div class=""> 
       @Html.TextBoxFor(x => x.TheTime, new {@class = "form-control form-control-sm", dataUserDefined = "true", placeholder = "Time"}) 
       @Html.ValidationMessageFor(x => x.TheTime, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

該模型中的時間僅僅是

[RegularExpression(@"^(0[1-9]|1[0-2]):[0-5][0-9] (am|pm|AM|PM)$", ErrorMessage = "Invalid Time.")] 
    public TimeSpan? TheTime {get; set;} 

現在reg表達式確實是在視圖上的東西,並驗證什麼進入一個12小時格式。驗證似乎通過..因爲我沒有得到一個無效的時間消息。回發顯示ModelBinder.IsValid爲false。

我試圖打破自動屬性有一個支持領域,以檢查進入該集的'價值'。並且我看到在該集合中該值始終爲空。因此,mvc模型綁定器不知道如何處理12小時格式的時間。

任何想法?非常感謝。

12小時格式化的時間範圍綁定是否需要自定義模型綁定器?

[更新]: 所以我嘗試了一個自定義模型活頁夾。但同樣的問題存在!

我看到正確的值進來時,我檢查ControllerContext.HttpContext.Request [「TheTime」];

我轉換成使用時間跨度(注意TheVModel是我的視圖模型):

自定義模型綁定

public class TimeModelBinder : DefaultModelBinder { 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { 
     var model = (TheVModel)base.BindModel(controllerContext, bindingContext); 
     var the12HrTime = controllerContext.HttpContext.Request["TheTime"]; 

     DateTime t = DateTime.ParseExact(the12HrTime, "h:mm tt", CultureInfo.InvariantCulture); 
     TimeSpan? ts = t.TimeOfDay; 

     model.TheTime = ts; 
     return model; 
    } 
} 

我可以看到HttpContext.Request [ 「TheTime」]有12小時。
我可以看到時間跨度ts正確創建,TheTime在屬性中正確設置......但是我認爲,既然mvc活頁夾已經試圖做到這一點,那麼做任何事情都爲時已晚。

+0

難道在處理視圖上的時間真的很複雜... gez – user1161137

回答

0

好的,所以我解決的方案... MVC ModelBinder只是不喜歡處理TimeSpan?字段,它總是會返回一個無效的模型狀態。所以,因爲我不知道如何告訴MVC模型聯編程序SKIP綁定該字段,我採​​取了不讓模型聯編程序綁定到該字段的方法。

因此,我添加了一個額外的STRING屬性到我的ViewModel並讓VIEW使用該屬性。然後使用下面的CUSTOM MODEL Binder(與前一個類似但略有變化),我將STRING時間值移入REAL TimeSpan?我的模特的財產。

所以:

定製綁定

public class TimeModelBinder : DefaultModelBinder 
     { 
      public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
      {  
       var model = (ReceiptClassifyDetailViewModel)base.BindModel(controllerContext, bindingContext); 
       var the12HrTime = controllerContext.HttpContext.Request["TempTimeOnVM"]; 

       if (!string.IsNullOrEmpty(the12HrTime)) 
       { 
        DateTime t = DateTime.ParseExact(the12HrTime, "h:mm tt", CultureInfo.InvariantCulture); 
        TimeSpan? ts = t.TimeOfDay; 
        model.TheTime = ts; 
       } 

       return model; 
      } 
     } 

VIEW

 <div class="form-group"> 
      @Html.Label("The Time", new { @class = "col-xs-6 col-sm-6 col-md-4 col-lg-4 control-label col-form-label text-right" }) 
      <div class="col-xs-6 col-xs-6 col-sm-6 col-md-8 col-lg-8"> 
       @Html.TextBoxFor(x => x.TempTimeOnVM, new {@class = "form-control timemask form-control-sm", dataUserDefined = "true", placeholder = "Time"}) 
       @Html.ValidationMessageFor(x => x.TempTimeOnVM, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

附加屬性以支持原時間跨度?屬性。

public string TempTimeOnVM { get; set; }