এএসপি.নেট এমভিসি কীভাবে মডেলস্টেট ত্রুটিগুলিকে জসনে রূপান্তর করতে পারে


127

আপনি কীভাবে সমস্ত মডেলস্টেট ত্রুটি বার্তাগুলির একটি তালিকা পাবেন? আমি সমস্ত কোডগুলি পেতে এই কোডটি পেয়েছি: ( মডেলস্টেট ত্রুটিযুক্ত কীগুলির একটি তালিকা ফেরত দেওয়া )

var errorKeys = (from item in ModelState
        where item.Value.Errors.Any() 
        select item.Key).ToList();

তবে আমি কীভাবে আইলিস্ট বা আইকিউয়ারিযোগ্য হিসাবে ত্রুটি বার্তা পাব?

আমি যেতে পারি:

foreach (var key in errorKeys)
{
    string msg = ModelState[error].Errors[0].ErrorMessage;
    errorList.Add(msg);
}

তবে এটি ম্যানুয়ালি করে চলেছে - অবশ্যই লিনকিউ ব্যবহার করে এটি করার একটি উপায় আছে? .ErrorMessage সম্পত্তিটি এতদূর নিচে রয়েছে যে আমি লিনকিউ লিখতে জানি না ...

উত্তর:


192

আপনি যে কিছু চাইবেন selectসেটির ধারাটির ভিতরে রাখতে পারেন :

var errorList = (from item in ModelState
        where item.Value.Errors.Any() 
        select item.Value.Errors[0].ErrorMessage).ToList();

সম্পাদনা : আপনি একটি fromধারা যুক্ত করে পৃথক তালিকা আইটেমগুলিতে একাধিক ত্রুটিগুলি বের করতে পারেন :

var errorList = (from item in ModelState.Values
        from error in item.Errors
        select error.ErrorMessage).ToList();

বা:

var errorList = ModelState.Values.SelectMany(m => m.Errors)
                                 .Select(e => e.ErrorMessage)
                                 .ToList();

2 তম সম্পাদনা : আপনি এটি সন্ধান করছেন Dictionary<string, string[]>:

var errorList = ModelState.ToDictionary(
    kvp => kvp.Key,
    kvp => kvp.Value.Errors.Select(e => e.ErrorMessage).ToArray()
);

দ্রুত জবাব দেয় :)! আরে এটি দেখতে দুর্দান্ত লাগছে তবে মডেলস্টেট [আইটেম.কি] এর 1 টিরও বেশি ত্রুটি থাকলে কী হবে? ত্রুটিগুলি [0] কেবল একটি একক ত্রুটি বার্তার জন্য কাজ করে
জে.কে.

আপনি কিভাবে তাদের একত্রিত করতে চান?
এসএলএক্স

ধন্যবাদ প্রায় এটি thats - তবে এটির কোনও ত্রুটি না থাকলেও প্রতিটি কী নির্বাচন করা - আমরা কীভাবে কোনও ত্রুটি ছাড়াই কীগুলি ফিল্টার করতে পারি?
জে.কে।

4
যোগ করুন.Where(kvp => kvp.Value.Errors.Count > 0)
এসএলএক্স

3
আপনার কাছ থেকে একই আউটপুট পেতে Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);ব্যবহার করা উচিত var errorList = modelState.Where(elem => elem.Value.Errors.Any()) .ToDictionary( kvp => kvp.Key, kvp => kvp.Value.Errors.Select(e => string.IsNullOrEmpty(e.ErrorMessage) ? e.Exception.Message : e.ErrorMessage).ToArray());অন্যথায় আপনার
এক্সপেশন ম্যাসেজগুলি নেই

74

এখানে একসাথে রাখা সমস্ত টুকরা সহ সম্পূর্ণ বাস্তবায়ন:

প্রথমে একটি এক্সটেনশন পদ্ধতি তৈরি করুন:

public static class ModelStateHelper
{
    public static IEnumerable Errors(this ModelStateDictionary modelState)
    {
        if (!modelState.IsValid)
        {
            return modelState.ToDictionary(kvp => kvp.Key,
                kvp => kvp.Value.Errors
                                .Select(e => e.ErrorMessage).ToArray())
                                .Where(m => m.Value.Any());
        }
        return null;
    }
}

তারপরে সেই এক্সটেনশন পদ্ধতিটি কল করুন এবং নিয়ন্ত্রণকারী ক্রিয়া থেকে ত্রুটিগুলি (যদি থাকে) জেসন হিসাবে ফিরিয়ে দিন:

if (!ModelState.IsValid)
{
    return Json(new { Errors = ModelState.Errors() }, JsonRequestBehavior.AllowGet);
}

এবং তারপরে, ক্লায়েন্টাইডে এই ত্রুটিগুলি দেখান (jquery. માન્યকরণ শৈলীতে, তবে সহজেই অন্য কোনও শৈলীতে পরিবর্তন করা যেতে পারে)

function DisplayErrors(errors) {
    for (var i = 0; i < errors.length; i++) {
        $("<label for='" + errors[i].Key + "' class='error'></label>")
        .html(errors[i].Value[0]).appendTo($("input#" + errors[i].Key).parent());
    }
}

এটি একটি আকর্ষণীয় পদ্ধতির মতো দেখায় তবে সহায়ক শ্রেণি আমার পক্ষে কাজ করছে না। এটি সম্ভবত এমভিসি 2 এর সাথে পরিবর্তনের কারণে রয়েছে? আমি একটি ত্রুটি পেয়ে যাচ্ছি যে মডেল স্টেটে টোডেয়ার অভিধানটি বিদ্যমান নেই।
সাইমন

@ সাইমন আপনি কি সিস্টেম.লিনক রেফারেন্স করতে ভুলে যাচ্ছেন? টোডিয়ামারিয়া () একটি লিনকিউ এক্সটেনশন পদ্ধতি।
নাথন টেলর

8
আপনার পছন্দগুলি সাপেক্ষে .Where(m => m.Value.Count() > 0)হিসাবে লেখা যেতে পারে .Where(m => m.Value.Any())
মানফ্রেড

গ্রিডে ত্রুটিগুলি ফিরিয়ে আনতে এবং সম্পাদনায় ত্রুটি বার্তাগুলি প্রদর্শন করতে এটি কেন্দো.এমভিসি থেকে মডেলস্টেট। টোডাটাসোর্স রেজাল্ট () হিসাবে একইভাবে ব্যবহার করা যেতে পারে।
মালনোস্না

22

আমি Hashtableএখানে ব্যবহার করতে চাই , যাতে আমি কী হিসাবে বৈশিষ্ট্যযুক্ত JSON অবজেক্টটি পাই এবং স্ট্রিং অ্যারের আকারে মূল্য হিসাবে ত্রুটি।

var errors = new Hashtable();
foreach (var pair in ModelState)
{
    if (pair.Value.Errors.Count > 0)
    {
        errors[pair.Key] = pair.Value.Errors.Select(error => error.ErrorMessage).ToList();
    }
}
return Json(new { success = false, errors });

এইভাবে আপনি নিম্নলিখিত প্রতিক্রিয়া পাবেন:

{
   "success":false,
   "errors":{
      "Phone":[
         "The Phone field is required."
      ]
   }
}

8

এটি করার বিভিন্ন উপায় রয়েছে যা সমস্ত কাজ করে। এখানে এখন আমি এটা ...

if (ModelState.IsValid)
{
    return Json("Success");
}
else
{
    return Json(ModelState.Values.SelectMany(x => x.Errors));
}

2
আপনিও ফিরে আসতে পারেন BadRequest(ModelState)এবং এটি এটি আপনার জন্য জেএসএনে সিরিয়ালিয়াল করে দেবে।
ফ্রেড

6

এটি করার সবচেয়ে সহজ উপায় হ'ল কেবল BadRequestমডেলস্টেটের সাথে একটি ফিরিয়ে দেওয়া:

উদাহরণস্বরূপ PUT:

[HttpPut]
public async Task<IHttpActionResult> UpdateAsync(Update update)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    // perform the update

    return StatusCode(HttpStatusCode.NoContent);
}

যদি আমরা Updateক্লাসে উদাহরণস্বরূপ একটি মোবাইল নম্বর ব্যবহার করে ডেটা টীকা ব্যবহার করি :

public class Update {
    [StringLength(22, MinimumLength = 8)]
    [RegularExpression(@"^\d{8}$|^00\d{6,20}$|^\+\d{6,20}$")]
    public string MobileNumber { get; set; }
}

এটি একটি অবৈধ অনুরোধে নিম্নলিখিতটি ফিরিয়ে দেবে:

{
  "Message": "The request is invalid.",
  "ModelState": {
    "update.MobileNumber": [
      "The field MobileNumber must match the regular expression '^\\d{8}$|^00\\d{6,20}$|^\\+\\d{6,20}$'.",
      "The field MobileNumber must be a string with a minimum length of 8 and a maximum length of 22."
    ]
  }
}

1
BadRequest ওয়েবপিআই নির্দিষ্ট এবং এই প্রশ্নটি এমভিসি সম্পর্কে।
রগ্রিপার

5

@ জে কে এটি আমাকে অনেক সাহায্য করেছে তবে কেন নয়:

 public class ErrorDetail {

        public string fieldName = "";
        public string[] messageList = null;
 }

        if (!modelState.IsValid)
        {
            var errorListAux = (from m in modelState 
                     where m.Value.Errors.Count() > 0 
                     select
                        new ErrorDetail
                        { 
                                fieldName = m.Key, 
                                errorList = (from msg in m.Value.Errors 
                                             select msg.ErrorMessage).ToArray() 
                        })
                     .AsEnumerable()
                     .ToDictionary(v => v.fieldName, v => v);
            return errorListAux;
        }

3

System.Web.Http.Results.OkNegotiatedContentResult দেখুন।

এটি আপনি যা ফেলেছেন তা JSON এ রূপান্তর করে।

তাই আমি এটি করেছি

var errorList = ModelState.ToDictionary(kvp => kvp.Key.Replace("model.", ""), kvp => kvp.Value.Errors[0].ErrorMessage);

return Ok(errorList);

এর ফলস্বরূপ:

{
  "Email":"The Email field is not a valid e-mail address."
}

প্রতিটি ক্ষেত্রের জন্য একাধিক ত্রুটি থাকলে কী হয় তা আমি এখনও পরীক্ষা করতে পারছি না তবে পয়েন্টটি OkNegoriatedContentResult উজ্জ্বল!

@ এসএলক্স থেকে লিনক / ল্যাম্বদা ধারণা পেয়েছেন


3

সাধারণ উপায় অন্তর্নির্মিত কার্যকারিতা ব্যবহার করে এটি অর্জন করে

[HttpPost]
public IActionResult Post([FromBody]CreateDoctorInput createDoctorInput) {
    if (!ModelState.IsValid) {
        return BadRequest(ModelState);
    }

    //do something
}

জেএসএনের ফলাফল হবে


2

টোডিয়ামারিয়া হ'ল একটি গণনাযোগ্য এক্সটেনশন যা সিস্টেমে পাওয়া যায় package লিনকটি প্যাকেজড সিস্টেমে W ওয়েব x এক্সটেনশনস ডেল: http://msdn.microsoft.com/en-us/library/system.linq.enumerable.tod शब्दको . aspx । সম্পূর্ণ ক্লাসটি আমার কাছে কেমন দেখাচ্ছে তা এখানে।

using System.Collections;
using System.Web.Mvc;
using System.Linq;

namespace MyNamespace
{
    public static class ModelStateExtensions
    {
        public static IEnumerable Errors(this ModelStateDictionary modelState)
        {
            if (!modelState.IsValid)
            {
                return modelState.ToDictionary(kvp => kvp.Key,
                    kvp => kvp.Value.Errors.Select(e => e.ErrorMessage).ToArray()).Where(m => m.Value.Count() > 0);
            }
            return null;
        }

    }

}

2

আসল ModelStateঅবজেক্টটি ক্লায়েন্টকে কেন ফিরিয়ে দেবে না এবং তারপরে মানগুলি পড়তে jQuery ব্যবহার করুন। আমার কাছে এটি অনেক সহজ দেখাচ্ছে এবং সাধারণ তথ্য কাঠামো ব্যবহার করে (। নেট এর ModelState)

ফিরে যাওয়ার ModelStateJSON যেমন, সহজভাবে JSON বর্গ কন্সট্রাকটর তা পাস (যে কোন বস্তুর সঙ্গে কাজ)

সি #:

return Json(ModelState);

JS:

        var message = "";
        if (e.response.length > 0) {
            $.each(e.response, function(i, fieldItem) {
                $.each(fieldItem.Value.Errors, function(j, errItem) {
                    message += errItem.ErrorMessage;
                });
                message += "\n";
            });
            alert(message);
        }

1

ফিরিয়ে দেওয়ার পরিবর্তে আইকনামারেবলের পরিবর্তনের সাথে পরিবর্তিত হওয়া

public static class ModelStateHelper
{
    public static IEnumerable<KeyValuePair<string, string[]>> Errors(this ModelStateDictionary modelState)
    {
        if (!modelState.IsValid)
        {
            return modelState
                .ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Errors.Select(e => e.ErrorMessage).ToArray())
                .Where(m => m.Value.Any());
        }

        return null;
    }
}

0

আমি তৈরি এবং প্রসারিত করেছি যা পৃথকদলের সাথে স্ট্রিং "" ফেরত দেয় (আপনি নিজের ব্যবহার করতে পারেন):

   public static string GetFullErrorMessage(this ModelStateDictionary modelState) {
        var messages = new List<string>();

        foreach (var entry in modelState) {
            foreach (var error in entry.Value.Errors)
                messages.Add(error.ErrorMessage);
        }

        return String.Join(" ", messages);
    }

-1
  List<ErrorList> Errors = new List<ErrorList>(); 


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

        foreach (var x in modelStateErrors)
        {
            var errorInfo = new ErrorList()
            {
                ErrorMessage = x.ErrorMessage
            };
            Errors.Add(errorInfo);

        }

আপনি যদি jsonresult ব্যবহার করেন তবে ফিরে আসুন

return Json(Errors);

বা আপনি কেবল মডেল স্টেটইরিরগুলি সহজেই ফিরিয়ে দিতে পারেন, আমি এটি চেষ্টা করে দেখিনি। আমি যা করেছি তা হল আমার ভিউমোডেলে ত্রুটিগুলি সংগ্রহ বরাদ্দ করা এবং তারপরে লুপ করা .. এই ক্ষেত্রে আমি জাসসনের মাধ্যমে আমার ত্রুটিগুলি ফিরিয়ে আনতে পারি। আমার একটি ক্লাস / মডেল রয়েছে, আমি উত্স / কীটি পেতে চেয়েছিলাম তবে আমি এখনও এটি বের করার চেষ্টা করছি।

    public class ErrorList
{
    public string ErrorMessage;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.