2010-01-07 33 views
5

Tôi có một hình thức tìm kiếm với một tiêu chí tìm kiếm DateTime, cộng với một số tiêu chí khác:Tạo một ActionLink với một DateTime trong chuỗi truy vấn trong ASP.NET MVC

<form method="get" action="/app/search"> 
    <input type="text" value="13/01/2010" name="BeginDate"/> 
    <input type="text" value="blah" name="SomeOtherCriterion"/> 
<form> 

Vì vậy, tôi có một bộ điều khiển Search với một mặc định Action (gọi nó là Index) và với tham số SearchCriteria.

public class SearchController 
{ 
    public ActionResult Index(SearchCriteria searchCriteria) {//blah } 
}  

public class SearchCriteria 
{ 
    public DateTime BeginDate {get; set;} 
    public string SomeOtherCriterion {get; set;} 
} 

Bây giờ nếu tôi muốn tạo một ActionLink, đi qua trong một giá trị SearchCriteria, như sau:

Html.ActionLink("Search", "Index", searchCriteria) 

tôi nhận được tham số chuỗi truy vấn BeginDate ở định dạng Mỹ. Nhìn vào Google và poking xung quanh trong System.Web.Routing bằng cách sử dụng Reflector nó có vẻ là bởi vì nó sử dụng InvariantCulture, vì vậy không có gì tôi có thể làm gì về nó.

Có vẻ như không ai đã hỏi câu hỏi này trước đây nên tôi đoán tôi đang làm điều gì đó rất ngu ngốc .... Xin hãy giúp!

EDIT: Chuyển trong SearchCriteria đến ActionLink thay vì đối tượng ẩn danh để hiển thị lý do tại sao tôi không thể chỉ thực hiện tùy chỉnh ToString().

Trả lời

3

Do khuôn khổ có vẻ khó mã hóa để xử lý đoạn dữ liệu này bằng cách sử dụng InvariantCulture, tôi không nghĩ bạn có thể làm gì để làm cho nó hoạt động một cách minh bạch.

Có một tùy chọn xấu - tải xuống nguồn MVC và trích xuất mã cho tất cả các lớp vi phạm từ Route xuống ParsedRoute để tạo triển khai RouteBase của riêng bạn thực hiện những gì bạn cần.

Nếu tôi hoàn toàn để giữ tờ khai DateTime trên lớp SearchCriteria, thì đó là tuyến đường (xin lỗi vì chơi chữ) tôi sẽ chọn.

Tuy nhiên, một giải pháp dễ dàng hơn sẽ được thay đổi lớp SearchCriteria bạn để sử dụng một tuyên bố hơi khác nhau cho trường DateTime, dựa trên một kiểu như thế này:

public class MyDateTime 
{ 
    public DateTime Value { get; set; } 
    //for passing MyDateTime in place of a DateTime without casting 
    public static implicit operator DateTime(MyDateTime instance) { return instance.Value; } 
    //so you can assign a MyDateTime from a DateTime without a cast 
    //- e.g. MyDateTime dt = DateTime.Now 
    public static implicit operator MyDateTime(DateTime instance) { return new MyDateTime() { Value = instance }; } 
    //override ToString so that CultureInfo.CurrentCulture is used correctly. 
    public override string ToString() 
    { 
    return Value.ToString(CultureInfo.CurrentUICulture); 
    } 
} 

Về lý thuyết bạn sẽ có thể để cuộn ra sự thay đổi này mà không có quá nhiều phiền toái.

Công việc lớn có thể là nếu bạn có nhiều mã sử dụng thành viên (ví dụ .Ngày vv) của cá thể DateTime trong SearchCriteria: bạn phải sao chép các thành viên đó trên MyDateTime, gói xung quanh bên trong DateTime Value hoặc thay đổi tất cả mã để sử dụng .Value.Member.

+0

Không thực sự thiết thực đối với chúng tôi nhưng chắc chắn là giải pháp sáng tạo nhất vì vậy tôi sẽ chấp nhận nó. Cảm ơn Zoltan. – Gaz

1

Bạn có thể cung cấp ngày được định dạng trong ActionLink của mình không? Hãy thử điều này:

Html.ActionLink("Search", 
       "Index", 
       new {BeginDate = 
         DateTime.Now.ToString("d", new CultureInfo("pt-BR");}) 

Tất nhiên những thay đổi này Bắt đầuDo chuỗi thay vì DateTime ... nhưng có thể điều đó sẽ phù hợp với bạn?

+0

Xem chỉnh sửa. Tôi muốn để có thể chỉ cần vượt qua một SearchCriteria thẳng thay vì sử dụng một đối tượng vô danh. Tôi biết tôi đã bỏ lỡ một cái gì đó từ câu hỏi! – Gaz

+0

Ah, đó là một chút khó khăn hơn. Tôi đoán bạn luôn có thể ẩn danh SearchCriteria chỉ để định dạng chuỗi ngày, nhưng đó sẽ là một nỗi đau lớn ... – womp

+0

Ai đó đã downvoted bạn womp. Đoán bạn không quan tâm với 23000 điểm nhưng nó có vẻ khắc nghiệt anyway. Tôi đã bỏ phiếu để đền bù. – Gaz

1

Chúng tôi sử dụng định dạng ISO ("s" trong định dạng chuỗi - YYYY-MM-DDTHH: MM: SS) cho việc này. Nó hoạt động chính xác và JavaScript cũng có thể xử lý nó.

+1

Nhưng làm thế nào để bạn có được ActionLink hoặc bất kỳ phương pháp MVC nào khác sử dụng RouteValueDictionary để chuyển đổi một DateTime thành định dạng này? – Gaz

+0

Chỉ cần đặt nó vào như một chuỗi: 'new RouteValueDictionary (new {SomeDate = anotherDate.ToString (" s ")})' –

1

Có lẽ bạn có thể sử dụng Model Binder để định dạng và phân tích cú pháp ngày? Chỉ cần đọc lại bài báo và nhận thấy rằng nó không định dạng ngày ... Có lẽ sẽ không làm việc ra ngoài. Tôi sẽ để lại câu trả lời mặc dù trong trường hợp nó cung cấp bất kỳ nguồn cảm hứng vô tình :)

+0

Cảm ơn Chris. AFAIK chỉ tốt cho việc xử lý các yêu cầu đến, không giúp tạo URL bằng ActionLink. – Gaz

+0

Nhận xét cùng lúc tôi đang chỉnh sửa :) –

1
poking around in System.Web.Routing using Reflector it 

có vẻ là vì nó sử dụng InvariantCulture

Bạn có thực sự shure về điều này? Các phần của Modelbinding và UrlBuilding tôi đã kiểm tra sử dụng CurrentCulture. Bạn có thể kiểm tra những gì sẽ xảy ra nếu bạn đặt CurrentCulture trước khi kết xuất?

+0

Bit tôi đang xem là System.Web.Routing.ParsedRoute.Bind. Xuống ở phía dưới, nơi nó đặt bất kỳ "giá trị không sử dụng" vào chuỗi truy vấn. (Mặc dù mọi ToString trong phương pháp này sử dụng InvariantCulture.) Tôi đã thử đặt CurrentCulture. Nó không giúp được gì. – Gaz

2

Để tránh các sự cố liên quan đến Cài đặt vùng và "Văn hóa", Tôi coi ngày và giờ là các trường không bị ràng buộc riêng biệt và sau đó lắp ráp chúng vào DateTime trong Bộ điều khiển của tôi.

Ví dụ:

Year [ ] Month [ ] Day [ ]

Tôi luôn textbox riêng món quà cho năm, tháng và ngày, theo thứ tự đó để không thể có sự nhầm lẫn giữa định dạng Mỹ (tháng/ngày/năm) và nhiều hơn nữa hoặc ít hơn phần còn lại của định dạng thế giới (ngày/tháng/năm).

1

Tải sách ASP.NET MVC 1.0 do Scott Hanselman, Scott Guthrie, Phil Haack và Rob Conery viết. Họ thực sự làm kịch bản chính xác này trong cuốn sách. Họ sử dụng một lộ trình cụ thể. Tôi đang xem nó ngay bây giờ trên trang 216.

Họ làm điều đó bằng cách chia nhỏ ngày, tháng và năm. Sau đó, bạn có trách nhiệm sử dụng những giá trị đó khi họ quay trở lại.

Các vấn đề liên quan