ฉันจะรับชุดข้อผิดพลาดสถานะของโมเดลใน ASP.NET MVC ได้อย่างไร


145

ฉันจะรับข้อผิดพลาดในมุมมองได้อย่างไร

ฉันไม่ต้องการใช้สรุปการตรวจสอบ Html Helper หรือข้อความการตรวจสอบความถูกต้อง แต่ฉันต้องการตรวจสอบข้อผิดพลาดและหากมีแสดงในรูปแบบเฉพาะ นอกจากนี้ในการควบคุมการป้อนข้อมูลฉันต้องการตรวจสอบข้อผิดพลาดของคุณสมบัติที่เฉพาะเจาะจงและเพิ่มชั้นเรียนเพื่อการป้อนข้อมูล

ป.ล. ฉันกำลังใช้ Spark View Engine แต่ความคิดควรเหมือนกัน

ดังนั้นฉันคิดว่าฉันสามารถทำอะไรบางอย่างเช่น ...

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

....and also...

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

....

หรืออะไรทำนองนั้น

UPDATE

ทางออกสุดท้ายของฉันดูเหมือนว่า:

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

นี่เป็นการเพิ่มข้อผิดพลาดคลาส css เท่านั้นหากคุณสมบัตินี้มีข้อผิดพลาด


คำตอบ:


210
<% ViewData.ModelState.IsValid %>

หรือ

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

และสำหรับสถานที่ให้บริการเฉพาะ ...

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

1
คุณสมบัติ ModelState เป็นประเภทพจนานุกรมเพื่อรับข้อผิดพลาดในการส่งผ่านชื่อคีย์ ViewData.ModelState ["ชื่อ"]

เกี่ยวกับ "ViewData.ModelState [" คุณสมบัติ "] ข้อผิดพลาด" สิ่งนี้จะทำให้เกิดข้อยกเว้นการอ้างอิงเป็นโมฆะหากไม่มีคีย์ที่มีชื่อ "คุณสมบัติ" หรือไม่? มันจะดีกว่าหรือไม่ถ้าให้ตรวจสอบ null ก่อนอื่นใน ViewData.ModelState ["คุณสมบัติ"] ก่อนที่จะอ่านในข้อผิดพลาด?
David Hollowell - MSFT

@ DaveHep คุณควรตรวจสอบการมีอยู่ทั้งหมดก่อน
Alex Lyman

61

หากต้องการรับข้อผิดพลาดจาก ModelState ให้ใช้ Linq นี้:

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

2
สิ่งนี้จะทำให้เกิดข้อยกเว้นการอ้างอิงโมฆะหากไม่มีรหัสที่มีชื่อที่ระบุหรือไม่ มันจะดีกว่าหรือไม่ถ้าให้ตรวจสอบค่า null ก่อนใน ViewData.ModelState [key] ก่อนที่จะอ่านในข้อผิดพลาด?
David Hollowell - MSFT

5
เนื่องจากเราเริ่มต้นด้วยการทำซ้ำสิ่งนี้ ModelState.Keys ฉันไม่เห็นความเป็นไปได้สำหรับ KeyNotFoundException ฉันคิดว่าการตรวจสอบนั้นจะเกินเลยไป
Chris McKenzie


28

สิ่งนี้จะทำให้คุณมีหนึ่งสตริงที่มีข้อผิดพลาดทั้งหมดที่มีการคั่นด้วยเครื่องหมายจุลภาค

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

นี่เป็นสิ่งเดียวที่ฉันพบในรายการทั้งหมดที่พิมพ์ข้อผิดพลาดจริง ๆ ! ขอบคุณ
Jamie

6

ขอบคุณแช้ด! เพื่อแสดงข้อผิดพลาดทั้งหมดที่เกี่ยวข้องกับกุญแจนี่คือสิ่งที่ฉันคิดขึ้นมา ด้วยเหตุผลบางอย่างตัวช่วยพื้นฐาน Html.ValidationMessage จะแสดงข้อผิดพลาดแรกที่เกี่ยวข้องกับคีย์เท่านั้น

    <%= 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

รวบรวมคำตอบหลายข้อจากด้านบนนี่คือสิ่งที่ฉันใช้:

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

validationErrorsจบลงด้วยการเป็นList<string>ที่มีแต่ละข้อความข้อผิดพลาด จากตรงนั้นมันง่ายที่จะทำสิ่งที่คุณต้องการด้วยรายการนั้น

ป้อนคำอธิบายรูปภาพที่นี่


2

นี่คือ 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

หากคุณไม่ทราบว่าคุณสมบัติใดที่ทำให้เกิดข้อผิดพลาดคุณสามารถใช้การสะท้อนวนรอบคุณสมบัติทั้งหมด:

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

โดยที่ T คือประเภทของ "ViewModel" ของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.