MVC3传递格式不正确的日期时间到控制器,但在控制器动作纠正它给人的ModelState错误 [英] MVC3 passing incorrectly formatted datetime to Controller but correcting it in the Controller action gives ModelState error

查看:167
本文介绍了MVC3传递格式不正确的日期时间到控制器,但在控制器动作纠正它给人的ModelState错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是不是有唯一一个这个问题,或者我在完全错误的方向做。

Am I the only one having this problem or I am doing it in totally wrong direction.

我有一个观点传递日期时间值:

I have a View passing DateTime value:

<div class="control-group">
@Html.Label("Appointment date", null, new { @class = "control-label" })
<div class="controls">
    <div class="input-append">
        @Html.TextBoxFor(model => model.Appointment.Client_PreferredDate, new { @readonly = "readonly" })
        <span class="add-on margin-fix"><i class="icon-th"></i></span>
    </div>
    <p class="help-block">
        @Html.ValidationMessageFor(model => model.Appointment.Client_PreferredDate)
    </p>
</div>

中的值传递到控制器的动作(可以看我的价值,我也知道这是给这不是日期时间格式,即它要在DD-MM-YYYY)。然后在控制器我会重新格式化。

The values are passed into the Controller action ( I can see the value, and I know it is giving the format that is not DateTime, i.e. it is going to be in dd-MM-yyyy). Then in the Controller I will reformat it.

[HttpPost]
public ActionResult RequestAppointment(General_Enquiry model, FormCollection fc)

{       
    model.Appointment.Client_PreferredDate = Utilities.formatDate(fc["Appointment.Client_PreferredDate"]);
    ModelState.Remove("Appointment.Client_PreferredDate");

try
{
    if (ModelState.IsValid)
    {
        model.Branch_Id = Convert.ToInt32(fc["selectedBranch"]);
        model.Appointment.Branch_Id = Convert.ToInt32(fc["selectedBranch"]);
        db.General_Enquiry.AddObject(model);
        db.SaveChanges();
        return RedirectToAction("AppointmentSuccess", "Client");
    }
}
catch (Exception e)
{
    Debug.WriteLine("{0} First exception caught.", e);
    Debug.WriteLine(e.InnerException);
    ModelState.AddModelError("", e);
}

return View(model);

}

我能做的最好是使用ModelState.Remove(),我感到很不舒服。我怀疑,当我的模型是从视图控制器过去了,ModelState中已设置为无效之前,我可以做到在任何控制器。任何想法?

The best I can do is to use ModelState.Remove(), which I feel really uncomfortable with. I suspect that when my Model is passed from the View to Controller, the ModelState is already set to Invalid before I can do anything in the Controller. Any ideas?

如果我所说的ModelState.Remove()一切顺利,日期时间由SQL Server数据库所接受。

If I call the ModelState.Remove() everything went smoothly, the DateTime is accepted by SQL server database.

如果至少我可以更新或刷新的ModelState它会解决我的问题的任何一点。

If at least I can update or 'refresh' ModelState at any point it'll fix my problem.

干杯。

推荐答案

我建议你使用视图模型和日期时间格式的自定义模型粘合剂。

I'd recommend you using a view model and a custom model binder for the DateTime formats.

我们首先来定义这个视图模型:

We start by defining this view model:

public class MyViewModel
{
    [DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}", ApplyFormatInEditMode = true)]
    public DateTime PreferredDate { get; set; }
}

然后控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel
        {
            PreferredDate = DateTime.Now.AddDays(2)
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        // model.PreferredDate will be correctly bound here so
        // that you don't need to twiddle with any FormCollection and 
        // removing stuff from ModelState, etc...
        return View(model);
    }
}

视图:

@model MyViewModel

@using (Html.BeginForm())
{
    @Html.LabelFor(x => x.PreferredDate)
    @Html.EditorFor(x => x.PreferredDate)
    @Html.ValidationMessageFor(x => x.PreferredDate)
    <button type="submit">OK</button>
}

和最后一个自定义的模型绑定使用指定的格式为:

and finally a custom model binder to use the specified format:

public class MyDateTimeModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var displayFormat = bindingContext.ModelMetadata.DisplayFormatString;
        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

        if (!string.IsNullOrEmpty(displayFormat) && value != null)
        {
            DateTime date;
            displayFormat = displayFormat.Replace("{0:", string.Empty).Replace("}", string.Empty);
            // use the format specified in the DisplayFormat attribute to parse the date
            if (DateTime.TryParseExact(value.AttemptedValue, displayFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
            {
                return date;
            }
            else
            {
                bindingContext.ModelState.AddModelError(
                    bindingContext.ModelName,
                    string.Format("{0} is an invalid date format", value.AttemptedValue)
                );
            }
        }

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

这将在的Application_Start 注册:

ModelBinders.Binders.Add(typeof(DateTime), new MyDateTimeModelBinder());

这篇关于MVC3传递格式不正确的日期时间到控制器,但在控制器动作纠正它给人的ModelState错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆