2012-06-30 39 views
54

Làm thế nào tôi có thể ép định dạng datetime trong asp.net mvc 4? Ở chế độ hiển thị, nó hiển thị như tôi muốn nhưng trong mô hình chỉnh sửa thì không. Tôi đang sử dụng displayfor và editorfor và applyformatineditmode = true với dataformatstring = "{0: dd/MM/yyyy}" Những gì tôi đã cố gắng:Định dạng ngày giờ trong asp.net mvc 4

  • toàn cầu hóa trong web.config (cả trong số họ) với văn hóa của tôi và uiculture.
  • sửa đổi văn hóa và uiculture trong Application_Start()
  • tùy chỉnh ModelBinder cho datetime

Tôi không có ý tưởng làm thế nào để buộc nó và tôi cần phải nhập ngày như dd/MM/yyyy không phải là mặc định.

MORE INFO: viewmodel của tôi là như thế này

[DisplayName("date of birth")] 
    [DataType(DataType.Date)] 
    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)] 
    public DateTime? Birth { get; set; } 

theo quan điểm của tôi sử dụng @Html.DisplayFor(m=>m.Birth) nhưng công trình này như mong đợi (tôi thấy các định dạng) và đầu vào ngày tôi sử dụng @Html.EditorFor(m=>m.Birth) nhưng nếu tôi cố gắng và đầu vào một cái gì đó như 13/12/2000 là không thành công với các lỗi mà nó không phải là một ngày hợp lệ (12/13/2000 và 2000/12/13 đang làm việc như mong đợi nhưng tôi cần dd/MM/yyyy).

Trình tùy chỉnh modelbinder được gọi trong application_start() b/c Tôi không biết nơi nào khác.

Sử dụng <globalization/> Tôi đã thử với culture="ro-RO", uiCulture="ro" và các nền văn hóa khác sẽ cung cấp cho tôi dd/MM/yyyy. Tôi cũng đã cố gắng để cài đặt nó trên một cơ sở cho mỗi chủ đề trong Application_Start() (có rất nhiều ví dụ ở đây, làm thế nào để làm điều này)


Đối với tất cả những gì sẽ đọc câu hỏi này: Dường rằng câu trả lời của Darin Dimitrov sẽ hoạt động miễn là tôi không có xác nhận của khách hàng. Cách tiếp cận khác là sử dụng xác thực tùy chỉnh bao gồm xác thực phía máy khách. Tôi rất vui vì tôi đã tìm thấy điều này trước khi tạo lại toàn bộ ứng dụng.

+0

Ông có thể vui lòng cung cấp một ít thông tin hơn? Mô hình, bộ điều khiển và chế độ xem của bạn? Cũng cung cấp một ví dụ về đầu ra khác nhau mà bạn nhận được giữa mẫu hiển thị và trình soạn thảo. Cũng lưu ý rằng văn hóa được thiết lập cho mỗi sợi. Bạn đã đề cập đến một cái gì đó về 'Application_Start' nhưng điều này được thực hiện chỉ một lần, khi ứng dụng của bạn bắt đầu. Điều gì về các yêu cầu tiếp theo? Làm thế nào bạn thiết lập văn hóa cho họ? –

+0

application_start chỉ được thực hiện một lần! Sử dụng application_beginRequest để thay thế! – Nas

+0

Nas, ở đâu application_beginYêu cầu là? Tôi chỉ thấy application_start trong Global. Trong mvc 4 thứ bắt đầu khác một chút thì mvc 3 – amb

Trả lời

96

Ahhhh, giờ đã rõ. Bạn dường như có vấn đề ràng buộc lại giá trị. Không hiển thị nó trên màn hình. Thật vậy, đó là lỗi của chất kết dính mô hình mặc định. Bạn có thể viết và sử dụng tùy chỉnh sẽ xem xét thuộc tính [DisplayFormat] trên mô hình của bạn. Tôi đã minh họa một mô hình tùy chỉnh như vậy ở đây: https://stackoverflow.com/a/7836093/29407


Rõ ràng một số vấn đề vẫn tồn tại. Đây là thiết lập đầy đủ của tôi làm việc hoàn toàn tốt trên cả hai ASP.NET MVC 3 & 4 RC.

mẫu:

public class MyViewModel 
{ 
    [DisplayName("date of birth")] 
    [DataType(DataType.Date)] 
    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)] 
    public DateTime? Birth { get; set; } 
} 

Bộ điều khiển:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(new MyViewModel 
     { 
      Birth = DateTime.Now 
     }); 
    } 

    [HttpPost] 
    public ActionResult Index(MyViewModel model) 
    { 
     return View(model); 
    } 
} 

Xem:

@model MyViewModel 

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

Đăng ký doanh nghiệp của mô hình tùy chỉnh chất kết dính trong Application_Start:

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

Và mô hình tùy chỉnh chất kết dính tự:

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

Bây giờ, không có vấn đề gì văn hóa bạn đã thiết lập trong web.config của bạn (<globalization> phần tử) hoặc văn hóa thread hiện hành, mô hình tùy chỉnh chất kết dính sẽ sử dụng DisplayFormat thuộc tính của định dạng ngày khi phân tích các ngày có thể vô hiệu hóa.

+1

Đây là cái tôi đã sử dụng nhưng không may mắn. Tôi đã đăng ký nó với cả datetime và datetime? Nó thậm chí không hiển thị thông báo lỗi của tôi vì vậy tôi không nghĩ rằng nó đang được sử dụng. – amb

+1

Sau đó, tôi sẽ đoán bạn sẽ phải hiển thị mã đầy đủ của bạn cho phép chúng tôi tái tạo vấn đề, bởi vì tôi đang sử dụng mô hình này chất kết dính mà không có bất kỳ vấn đề. –

+0

Trong tò mò, loại dự án MVC nào là (4 hoặc 3)? – amb

0

Cảm ơn Darin, Đối với tôi, để có thể gửi đến tạo phương pháp, Nó chỉ làm việc sau khi tôi sửa đổi mã BindModel tới:

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.TryParse(value.AttemptedValue, CultureInfo.GetCultureInfo("en-GB"), 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); 
} 

Hy vọng điều này có thể giúp người khác ...

0

Sự cố xác thực ứng dụng khách có thể xảy ra do lỗi MVC (ngay cả trong MVC 5) trong jquery.validate.unobtrusive.min.jskhông chấp nhận định dạng ngày/giờ theo bất kỳ cách nào. Thật không may bạn phải giải quyết nó bằng tay.

My giải pháp cuối cùng làm việc:

$(function() { 
    $.validator.methods.date = function (value, element) { 
     return this.optional(element) || moment(value, "DD.MM.YYYY", true).isValid(); 
    } 
}); 

Bạn phải bao gồm trước:

@Scripts.Render("~/Scripts/jquery-3.1.1.js") 
@Scripts.Render("~/Scripts/jquery.validate.min.js") 
@Scripts.Render("~/Scripts/jquery.validate.unobtrusive.min.js") 
@Scripts.Render("~/Scripts/moment.js") 

Bạn có thể cài đặt moment.js sử dụng:

Install-Package Moment.js 
Các vấn đề liên quan