MVC3 Xóa lỗi ModelState


83

Tôi gặp tình huống đang tải lên hình ảnh mà người dùng đã chọn từ hệ thống tệp cục bộ của họ. Biểu mẫu của tôi theo quan điểm của tôi, về cơ bản có hai nút gửi. Một được sử dụng để Gửi biểu mẫu một cách bình thường và tất cả quá trình xác thực sẽ thực thi. Cái thứ 2 chỉ để tải lên hình ảnh, trong trường hợp này tôi chưa muốn xác thực.

Tôi đã quản lý để tắt xác thực Phía máy khách bằng cách đặt cho nút gửi 'Hình ảnh tải lên' của mình một giá trị lớp là "hủy tên kiểu", vì vậy

<input type="submit" name="UploadImageButton" value="Upload Image" class="style-name cancel" /> 

Bây giờ, khi tôi đăng lại, mô hình của tôi có thuộc tính UploadImageButton, khi nhấp vào nút này, nó sẽ điền thuộc tính này (Tên của đầu vào khớp với Thuộc tính). Bằng cách này, tôi biết liệu biểu mẫu được gửi bởi nút Gửi thực sự của tôi hay bởi UploadImageButton.

Câu hỏi của tôi là ... Làm cách nào để tắt xác thực ServerSide? Tôi không muốn thông tin Tóm tắt xác thực hiển thị khi người dùng nhấp vào nút này. Tôi biết bạn có thể thêm lỗi mô hình tùy chỉnh bằng cách sử dụng

ModelState.AddModelError("{key}", "{error msg}");

Tôi đang tìm một phương tiện để loại bỏ lỗi mô hình. Điều này có khả thi không?

BIÊN TẬP:

Đây là những gì tôi nghĩ ra:

foreach (var key in ModelState.Keys.ToList().Where(key => ModelState.ContainsKey(key))) {
     //ModelState.Remove(key); //This was my solution before
     ModelState[key].Errors.Clear(); //This is my new solution. Thanks bbak
}

Tại sao bạn đang làm một Where(key => ModelState.Keys.Contains(key))? Có vẻ như mệnh đề Where là thừa, vì mỗi khóa trong ModelState.Keys sẽ có ModelState.Keys.Contains (khóa) trả về true.
Maxim Zaslavsky

1
Tôi đã cập nhật câu hỏi và nội dung, để sử dụng phương pháp ngắn hơn trên ModelState.ContainsKey, mặc dù giả định của bạn là sai. Chúng đang làm điều tương tự.
Jeff Reddy

Xin lỗi, tôi có thể đã giải thích kém hoặc hiểu sai câu trả lời của bạn. Bạn nói đúng ModelState.ContainsKey(key)ModelState.Contains(key)làm điều tương tự, nhưng quan điểm của tôi là tất cả các giá trị ModelState.Keys.ToList()theo bản chất sẽ được chứa trong đó ModelState, vì vậy toàn bộ Wheremệnh đề là thừa và sẽ làm chậm hiệu suất. Tuy nhiên, điều nhỏ nhặt.
Maxim Zaslavsky

Đó là ReSharper ném điều đó cùng nhau. Cảm ơn vì đã chỉ ra điều đó.
Jeff Reddy

1
Chỉ cần chú ý cách bạn tìm ra nút nào là nguồn của gửi. Trong ViewModel, bạn không cần phải có thuộc tính này. Chỉ cần thêm một tham số FormCollection vào Controller: public ActionResult Index (mô hình YourViewModelClass, FormCollection formCollection). Và kiểm tra xem tên nút có trong đó không: if (formCollection ["UploadImageButton"]! = Null). Tôi nghĩ sẽ tốt hơn khi bạn có nhiều nút gửi hơn.
jannagy02

Câu trả lời:


145

Bạn có thể xóa lỗi mô hình bằng cách làm như sau:

if (ModelState.ContainsKey("{key}"))
    ModelState["{key}"].Errors.Clear();

1
Điều này thật đúng với gì mà tôi đã tìm kiếm. Tôi đã thay đổi câu trả lời đã chọn của mình (xin lỗi Adam Tuliper).
Jeff Reddy

Cảm ơn, điều đó vừa tiết kiệm được vài giờ của tôi!
Agent007

1
Chỉ trong trường hợp bất cứ ai đã tự hỏi, điều này cũng ảnh hưởng đếnModelState.IsValid
Red Taz

2
kỳ lạ, điều này là không đủ trong trường hợp của tôi. Tôi đã phải thêm ModelState ["{key}"]. ValidationState = ModelValidationState.Valid;
AGuyCalledGerald

67

Điều này dựa trên các câu trả lời trước đó, nhưng đơn giản hóa nó hơn một chút:

foreach (var modelValue in ModelState.Values)
{
    modelValue.Errors.Clear();
}

7

Nói chung, bạn không muốn tắt xác thực phía máy chủ hoặc xóa lỗi ModelState theo cách thủ công. Nó có thể làm được, nhưng dễ xảy ra lỗi vì nó phải dựa vào chuỗi làm khóa. Tôi đã ủng hộ câu trả lời về cách loại bỏ các phím, vì nó đúng và hữu ích, nhưng tôi khuyên bạn không nên tự thiết kế mình vào một trường hợp mà bạn phải hết sức cân nhắc.

Trong trường hợp của bạn, bạn có nhiều nút gửi cho cùng một biểu mẫu, nhưng bạn thực sự không gửi biểu mẫu khi tải hình ảnh lên. Để ngăn xác thực phía máy khách, bạn có thể sử dụng lớp "hủy" như bạn đã chỉ định, nhưng tôi cũng khuyên bạn nên có nút gửi thứ hai ở một biểu mẫu khác, trong trường hợp đó, nó không gây ra xác thực trên biểu mẫu chính của bạn.

Có một lợi thế thứ hai khi sử dụng biểu mẫu khác: bạn có thể gửi nó đến một phương thức ActionResult khác, phương thức này sẽ chỉ xử lý logic của việc tải lên hình ảnh. Phương pháp khác biệt này sẽ không bận tâm đến việc kiểm tra thuộc tính "IsValid" của trạng thái mô hình: nó chỉ quan tâm nếu có thông tin trong hình ảnh và điều đó có thể được kiểm tra riêng. (Ngay cả khi bạn sử dụng cùng một phương thức ActionResult, bạn có thể phân bố logic để không dựa vào thuộc tính IsValid của trạng thái mô hình.)

Nếu bạn phải xóa các lỗi khỏi trạng thái mô hình và việc xóa tất cả chúng là hợp lý, hãy thử cách này:

foreach (var key in ModelState.Keys)
{
    ModelState[key].Errors.Clear();
}

Điều này giúp bạn không phụ thuộc vào việc đặt tên khóa chính xác, nhưng vẫn giữ nguyên các giá trị nếu bất kỳ giá trị nào (hợp lệ hoặc không hợp lệ) đã tồn tại trong mô hình.

Một điều cuối cùng cần kiểm tra trong những trường hợp này là liệu bạn có các giá trị đôi khi chỉ có trong chế độ xem, điều này sẽ không gây ra xác thực phía máy khách (chúng không có trong chế độ xem), nhưng dẫn đến các vấn đề xác thực phía máy chủ. Trong trường hợp này, tốt nhất là sử dụng @ Html.HiddenFor (model => model.PropertyName, nếu bạn có thể, giả sử giá trị đã được đặt, nó sẽ không hiển thị trong chế độ xem này.


7

Đôi khi tôi sử dụng nó, vì vậy tôi đã tạo một phương thức mở rộng từ nó:

public static ModelStateDictionary ClearError(this ModelStateDictionary m, string fieldName)
{
    if (m.ContainsKey(fieldName))
        m[fieldName].Errors.Clear();
    return m;
}

Nó có thể được sử dụng thành thạo để xóa lỗi cho nhiều trường.


3

sử dụng ModelState.Remove ("{key}") để xóa lỗi khỏi mô hình, điều này sẽ đặt lại ModelState.IsValid thành true

ModelState.Remove("{key}");
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.