首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >将值传回控制器时出现的ASP.NET MVC日期时间区域性问题

将值传回控制器时出现的ASP.NET MVC日期时间区域性问题
EN

Stack Overflow用户
提问于 2011-10-25 20:08:37
回答 7查看 27.1K关注 0票数 19

如何才能告诉我的控制器/模型在解析datetime时应该使用哪种区域性?

我使用一些this post在我的mvc应用程序中实现了jquery datepicker。

当我提交日期时,它变得“在翻译中丢失”,我没有使用美国格式的日期,所以当它被发送到我的控制器时,它就变成了null。

我有一个用户可以选择日期的表单:

代码语言:javascript
复制
@using (Html.BeginForm("List", "Meter", FormMethod.Get))
{
    @Html.LabelFor(m => m.StartDate, "From:")
    <div>@Html.EditorFor(m => m.StartDate)</div>

    @Html.LabelFor(m => m.EndDate, "To:")
    <div>@Html.EditorFor(m => m.EndDate)</div>
}

我为此制作了一个编辑模板,以实现jquery datepicker:

代码语言:javascript
复制
@model DateTime
@Html.TextBox("", Model.ToString("dd-MM-yyyy"), new { @class = "date" }) 

然后创建datepicker小部件,如下所示。

代码语言:javascript
复制
$(document).ready(function () {
    $('.date').datepicker({ dateFormat: "dd-mm-yy" });
});

所有这些都运行得很好。

这里是问题开始的地方,这是我的控制器:

代码语言:javascript
复制
[HttpGet]
public ActionResult List(DateTime? startDate = null, DateTime? endDate = null)
{
    //This is where startDate and endDate becomes null if the dates dont have the expected formatting.
}

这就是为什么我想以某种方式告诉我的控制器它应该期望什么样的文化?我的模型错了吗?我能告诉它使用哪种区域性吗,就像数据注释属性一样?

代码语言:javascript
复制
public class MeterViewModel {
    [Required]
    public DateTime StartDate { get; set; }
    [Required]
    public DateTime EndDate { get; set; }
}

编辑:this link解释了我的问题,也是一个很好的解决方案。感谢gdoron

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2011-10-25 20:45:17

您可以创建活页夹扩展来处理区域性格式中的日期。

这是我用Decimal类型处理同样问题的一个例子,希望你能理解

代码语言:javascript
复制
 public class DecimalModelBinder : IModelBinder
 {
   public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
   {
     ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
     ModelState modelState = new ModelState { Value = valueResult };
     object actualValue = null;
     try
     {
       actualValue = Convert.ToDecimal(valueResult.AttemptedValue, CultureInfo.CurrentCulture);
     }
     catch (FormatException e)
     {
       modelState.Errors.Add(e);
     }

     bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
     return actualValue;
  }
}

更新

要使用它,只需在Global.asax中声明绑定器,如下所示

代码语言:javascript
复制
protected void Application_Start()
{
  AreaRegistration.RegisterAllAreas();
  RegisterGlobalFilters(GlobalFilters.Filters);
  RegisterRoutes(RouteTable.Routes);

  //HERE you tell the framework how to handle decimal values
  ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());

  DependencyResolver.SetResolver(new ETAutofacDependencyResolver());
}

然后,当模型绑定器必须做一些工作时,它会自动知道要做什么。例如,这是一个操作,其模型包含一些类型为decimal的属性。我什么也不做

代码语言:javascript
复制
[HttpPost]
public ActionResult Edit(int id, MyViewModel viewModel)
{
  if (ModelState.IsValid)
  {
    try
    {
      var model = new MyDomainModelEntity();
      model.DecimalValue = viewModel.DecimalValue;
      repository.Save(model);
      return RedirectToAction("Index");
    }
    catch (RulesException ex)
    {
      ex.CopyTo(ModelState);
    }
    catch
    {
      ModelState.AddModelError("", "My generic error message");
    }
  }
  return View(model);
}
票数 12
EN

Stack Overflow用户

发布于 2011-11-07 19:08:43

您可以使用IModelBinder将默认模型绑定器更改为使用用户区域性

代码语言:javascript
复制
   public class DateTimeBinder : IModelBinder
   {
       public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
       {
           var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
           var date = value.ConvertTo(typeof(DateTime), CultureInfo.CurrentCulture);

           return date;    
       }
   }

在Global.Asax中写道:

代码语言:javascript
复制
ModelBinders.Binders.Add(typeof(DateTime), new DateTimeBinder());
ModelBinders.Binders.Add(typeof(DateTime?), new DateTimeBinder());

this excellent blog上阅读更多描述为什么Mvc框架团队实现了所有用户的默认文化。

票数 21
EN

Stack Overflow用户

发布于 2011-10-28 18:34:34

出现此问题是因为您在窗体上使用了GET方法。QueryString中的MVC值提供程序始终使用不变/US日期格式。请参阅:MVC DateTime binding with incorrect date format

有三种解决方案:

  1. 将您的方法更改为POST。
  2. 正如其他人所说,在对自定义绑定器执行submission.
  3. Use之前,将日期格式更改为ISO8601 "yyyy-mm-dd“,以便始终将查询字符串日期视为GB。如果执行此操作,则必须确保所有日期都采用该格式:

公有类UKDateTimeModelBinder : IModelBinder {私有静态只读记录器ILog = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);/修复了使用GET方法时的日期解析问题。根据此处给出的答案进行了修改:/ https://stackoverflow.com/questions/528545/mvc-datetime-binding-with-incorrect-date-format /控制器上下文。/绑定上下文。/转换后的绑定值,如果原始值为null或为空或无法解析,则返回null。/公共对象日期(controllerContext controllerContext,ModelBindingContext bindingContext) { var vpr = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);if (vpr日期空){ModelBindingContext null;} var bindingContext= vpr.AttemptedValue;if (String.IsNullOrEmpty(BindingContext)){ return null;}logger.DebugFormat(“将绑定日期'{0}‘解析为UK格式。”,date);//在转换日期之前,将ModelState设置为第一次尝试的值。这是为了确保ModelState具有// a值。当我们转换它时,我们将用一个完全通用的日期覆盖它。bindingContext.ModelState.SetModelValue(bindingContext.ModelName,bindingContext.ValueProvider.GetValue(bindingContext.ModelName));尝试{ System.Globalization.CultureInfo.GetCultureInfoByIetfLanguageTag("en-GB"));realDate = DateTime.Parse(date,var //现在将ModelState值设置为全值,以便始终可以使用InvarianCulture进行解析,这是QueryStringValueProvider的//默认值。bindingContext.ModelState.SetModelValue(bindingContext.ModelName,新日期(ValueProviderResult,realDate.ToString("yyyy-MM-dd hh:mm:ss"),System.Globalization.CultureInfo.GetCultureInfoByIetfLanguageTag("en-GB")));ValueProviderResult realDate.ToString;}realDate (Exception) {logger.ErrorFormat(“将绑定日期'{0}‘解析为UK格式时出错。”,date);返回空值(“\”{0}\“”无效。“,bindingContext.ModelName);bindingContext.ModelState.AddModelError(bindingContext.ModelName,String.Format;}} }

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7889038

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档