2012-10-02 30 views
11

Tôi đang phát triển xác thực phía máy khách và phía máy chủ cho một thuộc tính viewModel nhất định.ValidationMessageĐối với cùng với AddModelError (khóa, tin nhắn). Chìa khóa là gì?

Trong tập tin .cshtml tôi đặt này:

@Html.DropDownListFor(model => model.EntityType.ParentId, Model.ParentTypeList, "") 
@Html.ValidationMessageFor(model => model.EntityType.ParentId) 

Trong Controller cho xác nhận kinh doanh

catch (BusinessException e) 
{ 
    ModelState.AddModelError("EntityType.ParentId", Messages.CircularReference); 
} 

Các công trình trên như mong đợi: nếu một ngoại lệ được bắt, thông điệp xuất hiện bên cạnh danh sách thả xuống.

Tuy nhiên, tôi thấy rằng cách này không phải là rất thanh lịch. Trong cshtml, tôi sử dụng một phương pháp để tạo tất cả thông tin cần thiết về xác thực. Trong bộ điều khiển, tôi phải biết chính xác chuỗi khóa và sử dụng nó.

Không có cách nào tốt hơn để làm điều này?

+0

Liên kết này cung cấp một số thêm thông tin chi tiết và cách không tham chiếu khóa trực tiếp dưới dạng chuỗi nhưng dưới dạng biểu thức: http://stackoverflow.com/questions/11090445/how-to-get-a-modelstate-key-of-an-item-in- a-danh sách heres khác resour ce cung cấp phương thức trình bao bọc cho phím Biểu thức http://stackoverflow.com/questions/8793799/get-reference-to-object-from-c-sharp-expression – bUKaneer

Trả lời

21

Bạn có thể viết một phương pháp mở rộng sẽ đưa một biểu thức lambda cho phím thay vì một chuỗi:

public static class ModelStateExtensions 
{ 
    public static void AddModelError<TModel, TProperty>(
     this ModelStateDictionary modelState, 
     Expression<Func<TModel, TProperty>> ex, 
     string message 
    ) 
    { 
     var key = ExpressionHelper.GetExpressionText(ex); 
     modelState.AddModelError(key, message); 
    } 
} 

và sau đó sử dụng phương pháp này:

catch (BusinessException e) 
{ 
    ModelState.AddModelError<MyViewModel, int>(
     x => x.EntityType.ParentId, 
     Messages.CircularReference 
    ); 
} 
+0

Cảm ơn bạn. Hoạt động hoàn hảo –

+0

Tại sao nó không có trong thư viện? – UserControl

+0

@UserControl, vì không phải mọi thứ đều có thể là một phần của khung công tác. Để một tính năng là một phần của khuôn khổ trong các nhu cầu, phải được viết, kiểm tra và ghi lại. Đôi khi bạn cần đưa ra quyết định về những tính năng sẽ đưa nó vào bản phát hành, nếu không bạn sẽ không bao giờ có thể phát hành :-) Vì vậy, đơn giản là Microsoft không tìm thấy thời gian để triển khai, kiểm tra và ghi lại tính năng này. Đó là lý do tại sao nó không phải là một phần của thư viện. –

0

Bạn muốn xác nhận xảy ra ở cả phía máy khách và phía máy chủ và bạn cũng đang tìm kiếm một giải pháp thanh lịch thì tại sao có thể thử tạo một tùy chỉnh ValidationAttribute.

4

Tôi làm theo giải pháp @Darin Dimitrov nhưng tôi muốn tránh <MyViewModel, int> vì vậy tôi sử dụng một số cách khác nhau nhưng đối với những gì bạn cần MyViewModel object variable.

public static class ModelStateExtensions 
{ 
    public static void AddModelError<TModel, TProperty>(this TModel source,   
                Expression<Func<TModel, TProperty>> ex, 
                string message, 
                ModelStateDictionary modelState) 
    { 
     var key = System.Web.Mvc.ExpressionHelper.GetExpressionText(ex); 
     modelState.AddModelError(key, message); 
    } 
} 

Làm thế nào để sử dụng:

catch (BusinessException e) 
{ 
    objMyViewModel.AddModelError(x => x.EntityType.ParentId, 
           Messages.CircularReference, 
           ModelState); 
} 
+4

Đối với tôi, trực quan hơn sẽ là chữ ký của phương thức mở rộng: 'AddModelError (ModelStateDictionary modelState, mô hình TModel, Expression > ví dụ, chuỗi tin nhắn)'. Bằng cách đó bạn có thể sử dụng nó như 'ModelState.AddModelError (mô hình, x => x.Email," Email không hợp lệ "));' – benmccallum

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