MVC模型绑定不能工作12小时Timespan

时间:2017-08-02 15:52:03

标签: c# asp.net-mvc datetime

我有TimeSpan吗?在我的模型中的属性,我有一个视图,试图通过bootstrap datetimepicker获得12小时的时间值,格式为'hh:mm a'。

当我通过视图分配12小时的时间时,我的模型一直拒绝该值,我可以看到分配给该属性的值始终为null。 (当我使用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。

我尝试将自动属性分解为具有支持字段,以便检查进入该集合的“值”。我发现在集合中,值始终为null。所以mvc模型绑定器只是不知道如何处理12小时格式的时间。

有什么想法吗?非常感谢。

12小时格式化的时间跨度绑定是否需要自定义模型绑定器?

[UPDATE]: 所以我尝试了自定义模型活页夹。但同样的问题存在!!

当我检查ControllerContext.HttpContext.Request [“TheTime”]时,我看到正确的值;

我将它转换为使用时间跨度(注意TheVModel是我的viewmodel):

CUSTOM MODEL BINDER

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小时的时间 我可以看到,timepan ts是正确创建的,并且TheTime在属性中正确设置...但我认为,因为mvc绑定器已经尝试过这样做,所以做任何事都为时已晚。

1 个答案:

答案 0 :(得分:0)

好的,我接下来的解决方案...... MVC ModelBinder不喜欢处理TimeSpan吗?字段,它总是只返回INVALID的模型状态。因为我不知道如何告诉mvc模型绑定器SKIP绑定该字段,我采​​取了不让模型绑定器绑定到该字段的方法。

所以我在我的ViewModel中添加了一个额外的STRING属性,并让VIEW使用该属性。然后使用下面的CUSTOM MODEL Binder(类似但稍微改变前一个),我将STRING时间值移动到REAL TimeSpan?我的模特的财产。

所以:

CUSTOM BINDER

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;
            }
        }

查看

        <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>

支持原始TimeSpan的附加属性?属性。

public string TempTimeOnVM { get; set; }