ASP.Net MVC मॉडलस्टेट से सभी त्रुटियां कैसे प्राप्त करें?


453

मैं प्रमुख मूल्यों को जाने बिना सभी त्रुटि संदेश मॉडलस्टेट से बाहर निकालना चाहता हूं। ModelState वाले सभी त्रुटि संदेशों को हथियाने के लिए लूपिंग।

मैं यह कैसे कर सकता हूँ?


5
यदि आप केवल त्रुटियां प्रदर्शित कर रहे हैं, तो @Html.ValidationSummary()उन सभी को रेजर में प्रदर्शित करने का एक त्वरित तरीका है।
लेविनिन्जा

11
foreach (var error in ViewData.ModelState.Values.SelectMany(modelState => modelState.Errors)) { DoSomething(error); }
रज़वान डुमित्रु

जवाबों:


531
foreach (ModelState modelState in ViewData.ModelState.Values) {
    foreach (ModelError error in modelState.Errors) {
        DoSomethingWith(error);
    }
}

यह भी देखें कि मुझे ASP.NET MVC में मॉडल स्टेट एरर्स का संग्रह कैसे मिलेगा?


22
बहुत मददगार। कुछ परिदृश्यों में, जैसे कि बाध्यकारी विफलताएं और बुरे अनुरोध, खाली स्ट्रिंग के साथ ModelState प्रविष्टियाँ होंगी Value.ErrorMessageऔर इसके बजायValue.Exception.Message
एरोनल्स

5
त्रुटियाँ अच्छी हैं लेकिन कभी-कभी आप मॉडलस्टेट की कुंजी भी चाहते हैं (अर्थात फ़ील्ड का नाम)। आप इसे पहली पंक्ति बदलकर प्राप्त कर सकते हैं: foreach (KeyValuePair<string, ModelState> kvp in htmlHelper.ViewData.ModelState) {और इसके नीचे यह पंक्ति डालें var modelState = kvp.Value;:। आप इस कुंजी से प्राप्त कर सकते हैंkvp.Key
viggity

534

LINQ का उपयोग करना :

IEnumerable<ModelError> allErrors = ModelState.Values.SelectMany(v => v.Errors);

69
IEnumerable <string> को केवल त्रुटि संदेश के साथ संशोधित करने के लिए संशोधित किया गया :: var allErrors = ModelState.Values.SelectMany (v => v.Errors.Select (b => b.ErrorMessage));
किरन

6
यह बहुत अच्छा है, लेकिन दुर्भाग्य से घड़ी / तत्काल खिड़कियों लैम्ब्डा के समर्थन नहीं करते :(
AaronLS

3
हाँ! मुझे (आपको, किसी को) "System.Linq का उपयोग करना चाहिए;" ऊपर में। अन्यथा आपको संदेश मिला 'मानों में चयन कई के लिए परिभाषा नहीं है'। यह मेरे मामले में गायब था।
एस्टेवेज

2
var के उपयोग से नरक में क्यों ?????? क्या आप इसके बजाय `IEnumerable <ModelError>’ नहीं लिख सकते थे ???
हकन फिएस्तिक

6
@ hakam-fostok @ jb06 तुम दोनों सही हो। List<string> errors = new List<string>()इसके बजाय टाइप करना var errors = new List<string>()वास्तव में समय की बर्बादी है, लेकिन लेखन IEnumerable<ModelError> allErrors = ModelState.Values.SelectMany(v => v.Errors);, जहां रिटर्न प्रकार वास्तव में स्पष्ट नहीं है, वास्तव में पठनीयता की अवधि में अधिक है। (भले ही दृश्य स्टूडियो आपको माउस होवर पर दे सकता है)
जुलाब

192

LINQ verison पर बिल्डिंग, यदि आप सभी एरर मैसेज को एक स्ट्रिंग में शामिल करना चाहते हैं:

string messages = string.Join("; ", ModelState.Values
                                        .SelectMany(x => x.Errors)
                                        .Select(x => x.ErrorMessage));

5
अन्य विकल्प निम्नलिखित करने के लिए है: ModelState.Values.SelectMany (x => x.EErrors) .Select (x => x.ErrorMessage) .JoinString (";");
टॉड थॉमसन

3
@Tod, IEnumerable.JoinString () आपका अपना एक्सटेंशन तरीका है? देखें stackoverflow.com/q/4382034/188926
Dunc

2
हे डनक - हाँ मुझे संदेह है कि मैंने उस विस्तार विधि को अपने कोड बेस में जोड़ दिया है और इसके बारे में भूल गया हूं और फिर सोचा कि यह एक रूपरेखा विधि थी LOL :(
टॉड थॉमसन

5
या ... ModelState.Values.SelectMany (O => O.Errors) .Select (O => O.ErrorMessage) .Aggregate ((U, V) => U +, "+ V)
fordareh

2
जब आप वेब एपीआई का उपयोग कर रहे हैं और IHttpActionResult परिणाम लौटा रहे हैं तो यह बहुत अच्छा काम करता है। तो, आप बस कर सकते हैं: बैडरेस्पेस्ट (संदेश) लौटाएं; धन्यवाद, डनक!
रिच वार्ड

32

मैं थोड़ा LINQ का उपयोग कर ऐसा करने में सक्षम था,

public static List<string> GetErrorListFromModelState
                                              (ModelStateDictionary modelState)
{
      var query = from state in modelState.Values
                  from error in state.Errors
                  select error.ErrorMessage;

      var errorList = query.ToList();
      return errorList;
}

उपरोक्त विधि सत्यापन त्रुटियों की एक सूची देता है।

आगे की पढाई :

कैसे ASP.NET MVC में ModelState से सभी त्रुटियों को पढ़ने के लिए


17

डिबगिंग के दौरान, मुझे सभी मॉडलस्टैट त्रुटियों को दिखाने के लिए अपने प्रत्येक पृष्ठ के नीचे एक टेबल लगाने के लिए उपयोगी लगता है।

<table class="model-state">
    @foreach (var item in ViewContext.ViewData.ModelState) 
    {
        if (item.Value.Errors.Any())
        { 
        <tr>
            <td><b>@item.Key</b></td>
            <td>@((item.Value == null || item.Value.Value == null) ? "<null>" : item.Value.Value.RawValue)</td>
            <td>@(string.Join("; ", item.Value.Errors.Select(x => x.ErrorMessage)))</td>
        </tr>
        }
    }
</table>

<style>
    table.model-state
    {
        border-color: #600;
        border-width: 0 0 1px 1px;
        border-style: solid;
        border-collapse: collapse;
        font-size: .8em;
        font-family: arial;
    }

    table.model-state td
    {
        border-color: #600;
        border-width: 1px 1px 0 0;
        border-style: solid;
        margin: 0;
        padding: .25em .75em;
        background-color: #FFC;
    }
 </style>

अगर यहाँ कोई किनारे मामले हैं जहाँ यह विफल रहता है तो कृपया इसे ठीक करने के लिए उत्तर को संपादित करें
Simon_Weaver

12

जैसा कि मैंने अब तक दिए गए उत्तरों में सलाह का पालन करने की खोज की है, आप बिना त्रुटि संदेशों को सेट किए हुए अपवाद प्राप्त कर सकते हैं, इसलिए सभी समस्याओं को पकड़ने के लिए आपको वास्तव में ErrorMessage और Exception दोनों प्राप्त करने की आवश्यकता है।

String messages = String.Join(Environment.NewLine, ModelState.Values.SelectMany(v => v.Errors)
                                                           .Select( v => v.ErrorMessage + " " + v.Exception));

या एक विस्तार विधि के रूप में

public static IEnumerable<String> GetErrors(this ModelStateDictionary modelState)
{
      return modelState.Values.SelectMany(v => v.Errors)
                              .Select( v => v.ErrorMessage + " " + v.Exception).ToList();

}

आप इसमें सभी त्रुटियों के साथ एक स्ट्रिंग क्यों चाहते हैं? यह समझ में नहीं आता है कि जब आप इसके साथ कुछ करना चाहते हैं, तो सूची की एक सरणी बेहतर imho है
Daniël Tulp

1
डिबग करना। मेरी पहली समस्या यह पता लगाना था कि मेरे ऐप में क्या गलत था। मैं उपयोगकर्ता को यह बताने की कोशिश नहीं कर रहा था कि क्या गलत है। इसके अलावा उस उदाहरण को किसी अन्य चीज़ की गणना करने के लिए तार की गणना से बदलने के लिए तुच्छ है, उदाहरण के लिए त्रुटि संदेश और अपवाद इसलिए वास्तव में उपयोगी चीज यह जान रही है कि आपको जानकारी के दोनों बिट्स की जरूरत है
एलन मैकडोनाल्ड

BTW आपको एहसास हुआ कि दूसरी एक्सटेंशन विधि रिटर्न IEnumerable <स्ट्रिंग> और न केवल एक बड़ी एकल स्ट्रिंग है?
एलन मैकडोनाल्ड

8

यदि कोई व्यक्ति त्रुटि संदेश को दृढ़ता से टाइप किए गए दृश्य में बांधने के लिए मॉडल संपत्ति का नाम वापस करना चाहता है।

List<ErrorResult> Errors = new List<ErrorResult>();
foreach (KeyValuePair<string, ModelState> modelStateDD in ViewData.ModelState)
{
    string key = modelStateDD.Key;
    ModelState modelState = modelStateDD.Value;

    foreach (ModelError error in modelState.Errors)
    {
        ErrorResult er = new ErrorResult();
        er.ErrorMessage = error.ErrorMessage;
        er.Field = key;
        Errors.Add(er);
    }
}

इस तरह आप वास्तव में त्रुटि को फेंकने वाले क्षेत्र के साथ त्रुटि को बाँध सकते हैं।


7

केवल त्रुटि संदेशों को आउटपुट करना मेरे लिए पर्याप्त नहीं था, लेकिन इसने यह चाल चली।

var modelQuery = (from kvp in ModelState
                  let field = kvp.Key
                  let state = kvp.Value
                  where state.Errors.Count > 0
                  let val = state.Value?.AttemptedValue ?? "[NULL]"

                  let errors = string.Join(";", state.Errors.Select(err => err.ErrorMessage))
                  select string.Format("{0}:[{1}] (ERRORS: {2})", field, val, errors));

Trace.WriteLine(string.Join(Environment.NewLine, modelQuery));

1
एक चेतावनी के रूप में, ModelState में प्रमुख मूल्य जोड़े में NULL मान शामिल हो सकते हैं, यही वजह है कि यहाँ मूल कोड में एक null-coalesce ऑपरेटर (?) के साथ कुछ प्यारा C # 6 व्यवसाय शामिल है, इसलिए ?? अभिव्यक्ति के अंत में। मूल अभिव्यक्ति जो अशक्त त्रुटियों से रक्षा करनी चाहिए थी: राज्य ।Value.?AttemptedValue ?? "[शून्य]"। जहां तक ​​मुझे पता है, अपने वर्तमान स्थिति में कोड, उन मामलों की चुपके से निपटने के बिना, जहां राज्य। वाल्यू == अशक्त, जोखिम में है।
जोश सटरफील्ड

5

बस किसी के लिए मुझे इसकी जरूरत है और मेरी परियोजनाओं में निम्नलिखित स्थिर वर्ग का उपयोग करें

उपयोग उदाहरण:

if (!ModelState.IsValid)
{
    var errors = ModelState.GetModelErrors();
    return Json(new { errors });
}

usings:

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using WebGrease.Css.Extensions;

वर्ग:

public static class ModelStateErrorHandler
{
    /// <summary>
    /// Returns a Key/Value pair with all the errors in the model
    /// according to the data annotation properties.
    /// </summary>
    /// <param name="errDictionary"></param>
    /// <returns>
    /// Key: Name of the property
    /// Value: The error message returned from data annotation
    /// </returns>
    public static Dictionary<string, string> GetModelErrors(this ModelStateDictionary errDictionary)
    {
        var errors = new Dictionary<string, string>();
        errDictionary.Where(k => k.Value.Errors.Count > 0).ForEach(i =>
        {
            var er = string.Join(", ", i.Value.Errors.Select(e => e.ErrorMessage).ToArray());
            errors.Add(i.Key, er);
        });
        return errors;
    }

    public static string StringifyModelErrors(this ModelStateDictionary errDictionary)
    {
        var errorsBuilder = new StringBuilder();
        var errors = errDictionary.GetModelErrors();
        errors.ForEach(key => errorsBuilder.AppendFormat("{0}: {1} -", key.Key,key.Value));
        return errorsBuilder.ToString();
    }
}

धन्यवाद CodeArtist !! मैंने इसके कार्यान्वयन के नीचे दिए गए कोड में एक छोटा सा बदलाव किया।
अल्फ्रेड सेवेरो

4

और यह भी काम करता है:

var query = from state in ModelState.Values
    from error in state.Errors
    select error.ErrorMessage;
var errors = query.ToArray(); // ToList() and so on...

@ यासर क्या आपने टोटो का जवाब देखा है?
मफिन मैन

@ TheMuffinMan हाँ मेरे पास है। इसके बारे में क्या है ?
यासर शेख

@ वायसर यह सबसे अच्छा जवाब है। इस एक के साथ कुछ भी गलत नहीं है, लेकिन जब SelectManyउपलब्ध है तो इसका उपयोग करने का कोई मतलब नहीं है।
मफिन मैन

4

Json के माध्यम से, शायद देखने के लिए त्रुटि संदेशों के सरणी के लिए उपयोगी:

messageArray = this.ViewData.ModelState.Values.SelectMany(modelState => modelState.Errors, (modelState, error) => error.ErrorMessage).ToArray();

4

यह @ डंक से उत्तर पर विस्तार कर रहा है। देखें xml doc टिप्पणियाँ

// ReSharper disable CheckNamespace
using System.Linq;
using System.Web.Mvc;


public static class Debugg
{
    /// <summary>
    /// This class is for debugging ModelState errors either in the quick watch 
    /// window or the immediate window.
    /// When the model state contains dozens and dozens of properties, 
    /// it is impossible to inspect why a model state is invalid.
    /// This method will pull up the errors
    /// </summary>
    /// <param name="modelState">modelState</param>
    /// <returns></returns>
    public static ModelError[]  It(ModelStateDictionary modelState)
    {
        var errors = modelState.Values.SelectMany(x => x.Errors).ToArray();
        return errors;            
    }
}

3

इसके अलावा, ModelState.Values.ErrorMessageखाली हो सकता है, लेकिन ModelState.Values.Exception.Messageएक त्रुटि का संकेत दे सकता है।


0

आपके कार्यान्वयन में आप स्थिर वर्ग को याद कर रहे हैं, यह होना चाहिए।

if (!ModelState.IsValid)
{
    var errors =  ModelStateErrorHandler.GetModelErrors(this.ModelState);
    return Json(new { errors });
}

बल्कि

if (!ModelState.IsValid)
{
    var errors = ModelState.GetModelErrors();
    return Json(new { errors });
}

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.