Asp.net-Mvc-3

將值傳遞回控制器時的 ASP.NET MVC 日期時間文化問題

  • October 25, 2011

我如何告訴我的控制器/模型解析日期時間應該期望什麼樣的文化?

我正在使用這篇文章的一些內容將 jquery datepicker 實現到我的 mvc 應用程序中。

當我送出日期時,它“在翻譯中失去”我沒有使用美國格式的日期,所以當它被發送到我的控制器時,它就變成了空。

我有一個使用者選擇日期的表格:

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

@model DateTime
@Html.TextBox("", Model.ToString("dd-MM-yyyy"), new { @class = "date" }) 

然後我像這樣創建日期選擇器小元件。

$(document).ready(function () {
   $('.date').datepicker({ dateFormat: "dd-mm-yy" });
});

這一切都很好。

這是問題開始的地方,這是我的控制器:

[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.
}

這就是為什麼我想以某種方式告訴我的控制器它應該期待什麼文化?我的模型錯了嗎?我能以某種方式告訴它使用哪種文化,比如數據註釋屬性嗎?

public class MeterViewModel {
   [Required]
   public DateTime StartDate { get; set; }
   [Required]
   public DateTime EndDate { get; set; }
}

編輯:這個連結解釋了我的問題以及一個很好的解決方案。感謝gdoron

您可以創建一個 Binder 擴展來處理文化格式的日期。

這是我為處理 Decimal 類型的相同問題而編寫的範例,希望您能理解

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 中聲明活頁夾

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

然後當模型綁定器必須做一些工作時,它會自動知道該做什麼。例如,這是一個動作,其模型包含一些小數類型的屬性。我什麼都不做

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

您可以使用 IModelBinder 更改預設模型綁定器以使用使用者文化

  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 中寫道:

ModelBinders.Binders.Add(typeof(DateTime), new DateTimeBinder());
ModelBinders.Binders.Add(typeof(DateTime?), new DateTimeBinder());

在這個優秀的部落格上閱讀更多內容,該部落格描述了為什麼 Mvc 框架團隊為所有使用者實現了預設文化。

引用自:https://stackoverflow.com/questions/7889038