Làm cách nào để có được bộ sưu tập Lỗi trạng thái mô hình trong ASP.NET MVC?


145

Làm thế nào để tôi có được bộ sưu tập các lỗi trong một khung nhìn?

Tôi không muốn sử dụng Tóm tắt xác thực hoặc thông báo xác thực người trợ giúp Html. Thay vào đó tôi muốn kiểm tra lỗi và nếu có hiển thị chúng ở định dạng cụ thể. Ngoài ra trên các điều khiển đầu vào tôi muốn kiểm tra một lỗi thuộc tính cụ thể và thêm một lớp vào đầu vào.

PS Tôi đang sử dụng Spark View Engine nhưng ý tưởng nên giống nhau.

Vì vậy, tôi nghĩ rằng tôi có thể làm một cái gì đó như ...

<if condition="${ModelState.Errors.Count > 0}">
  DispalyErrorSummary()
</if>

....and also...

<input type="text" value="${Model.Name}" 
       class="?{ModelState.Errors["Name"] != string.empty} error" />

....

Hoặc điều tương tự.

CẬP NHẬT

Giải pháp cuối cùng của tôi trông như thế này:

<input type="text" value="${ViewData.Model.Name}" 
       class="text error?{!ViewData.ModelState.IsValid && 
                           ViewData.ModelState["Name"].Errors.Count() > 0}" 
       id="Name" name="Name" />

Điều này chỉ thêm lớp css lỗi nếu thuộc tính này có lỗi.


Câu trả lời:


210
<% ViewData.ModelState.IsValid %>

hoặc là

<% ViewData.ModelState.Values.Any(x => x.Errors.Count >= 1) %>

và cho một tài sản cụ thể ...

<% ViewData.ModelState["Property"].Errors %> // Note this returns a collection

1
thuộc tính ModelState thuộc loại từ điển để nhận lỗi khi vượt qua tên khóa ViewData.ModelState ["Name"]

liên quan đến "ViewData.ModelState [" Thuộc tính "]. Lỗi" điều này sẽ ném ngoại lệ tham chiếu null nếu không có khóa có tên "Tài sản"? trước tiên nên kiểm tra null trên ViewData.ModelState ["property"] trước khi đọc lỗi?
David Hollowell - MSFT

@DaveH Yep, bạn hoàn toàn nên kiểm tra sự tồn tại trước
Alex Lyman

61

Để nhận lỗi từ ModelState, hãy sử dụng Linq này:

var modelStateErrors = this.ModelState.Keys.SelectMany(key => this.ModelState[key].Errors);

2
điều này sẽ ném một ngoại lệ tham chiếu null nếu không có khóa với tên được chỉ định? trước tiên nên kiểm tra null trên ViewData.ModelState [key] trước khi đọc lỗi?
David Hollowell - MSFT

5
Bởi vì chúng tôi bắt đầu bằng cách lặp lại điều này.ModelState.Keys, tôi không thấy tiềm năng cho KeyNotFoundException. Tôi nghĩ rằng kiểm tra sẽ là quá mức cần thiết.
Chris McKenzie


28

Điều này sẽ cung cấp cho bạn một chuỗi với tất cả các lỗi với dấu phẩy phân tách

string validationErrors = string.Join(",",
                    ModelState.Values.Where(E => E.Errors.Count > 0)
                    .SelectMany(E => E.Errors)
                    .Select(E => E.ErrorMessage)
                    .ToArray());

Đây là điều duy nhất tôi tìm thấy trong toàn bộ danh sách này thực sự in ra các lỗi! Cảm ơn
Jamie

6

Cảm ơn Chad! Để hiển thị tất cả các lỗi liên quan đến khóa, đây là những gì tôi nghĩ ra. Vì một số lý do, trình trợ giúp cơ sở Html.ValidationMessage chỉ hiển thị lỗi đầu tiên được liên kết với khóa.

    <%= Html.ShowAllErrors(mykey) %>

HtmlHelper:

    public static String ShowAllErrors(this HtmlHelper helper, String key) {
        StringBuilder sb = new StringBuilder();
        if (helper.ViewData.ModelState[key] != null) {
            foreach (var e in helper.ViewData.ModelState[key].Errors) {
                TagBuilder div = new TagBuilder("div");
                div.MergeAttribute("class", "field-validation-error");
                div.SetInnerText(e.ErrorMessage);
                sb.Append(div.ToString());
            }
        }
        return sb.ToString();
    }

6

Tổng hợp một số câu trả lời từ phía trên, đây là những gì tôi đã sử dụng:

var validationErrors = ModelState.Values.Where(E => E.Errors.Count > 0)
    .SelectMany(E => E.Errors)
    .Select(E => E.ErrorMessage)
    .ToList();

validationErrorskết thúc là một thông List<string>báo chứa mỗi thông báo lỗi. Từ đó, thật dễ dàng để làm những gì bạn muốn với danh sách đó.

nhập mô tả hình ảnh ở đây


2

Đây là VB.

Dim validationErrors As String = String.Join(",", ModelState.Values.Where(Function(E) E.Errors.Count > 0).SelectMany(Function(E) E.Errors).[Select](Function(E) E.ErrorMessage).ToArray())

0

Nếu bạn không biết thuộc tính nào gây ra lỗi, bạn có thể, bằng cách sử dụng sự phản chiếu, lặp lại trên tất cả các thuộc tính:

public static String ShowAllErrors<T>(this HtmlHelper helper) {
    StringBuilder sb = new StringBuilder();
    Type myType = typeof(T);
    PropertyInfo[] propInfo = myType.GetProperties();

    foreach (PropertyInfo prop in propInfo) {
        foreach (var e in helper.ViewData.ModelState[prop.Name].Errors) {
            TagBuilder div = new TagBuilder("div");
            div.MergeAttribute("class", "field-validation-error");
            div.SetInnerText(e.ErrorMessage);
            sb.Append(div.ToString());
        }
    }
    return sb.ToString();
}

Trong đó T là loại "ViewModel" của bạn.

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.