c# - सर्वर साइड मान्यकरण.नेट वेबएपीआई के साथ




css validation (4)

तर्कों के लिए हम कहते हैं कि मैं बनाएँ व्यू पर हूं। अगर मैंने सभी पाठ बॉक्स खाली छोड़ दिए और सबमिट करें, तो मैं उसी टेक्स्ट को वापस लौटा दूंगा, लेकिन प्रत्येक पाठ बॉक्स के तहत सत्यापन संदेशों के साथ, जो आवश्यक था, और यह ग्राहक पक्ष मान्यता द्वारा किया गया था। अब, जब ऐसा होता है, तो प्रत्येक टेक्स्ट बॉक्स को एक नाम के साथ सजाया जाता है जिसे input-validation-error कहा जाता है, और अगर मैं शैली करता हूं तो मैं इसे उपयोगकर्ता के लिए अधिक खड़ा करने के लिए बॉक्स को लाल रंग में बदल सकता हूं।

लेकिन अब, मान लें कि टेक्स्ट बॉक्स में से एक को ईमेल पते की आवश्यकता है ईमेल पते मेरे वेबपिया नियंत्रक में मेरे पास इतने अद्वितीय हैं:

// POST: api/ControllerName
[ResponseType(typeof(TestObject))]
public IHttpActionResult PostTestObject(TestObject testObject)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    if (
        db.TestObjects.Any(
            x =>
                x.Email.Equals(testObject.Email, StringComparison.CurrentCultureIgnoreCase) &&
                x.ID != testObject.ID))
    {
            ModelState.AddModelError("Email", "This Email Already Exists!");
            return BadRequest(ModelState);
    }

    db.TestObjects.Add(testObject);
    db.SaveChanges();

    return CreatedAtRoute("DefaultApi", new { id = testObject.ID }, testObject);
}

मेरे बनाएँ दृश्य में मुझे यह अपवाद संदेश प्रदर्शित करने के लिए है:

.error(function (jqXHR, textStatus, errorThrown) {
    var status = capitalizeFirstLetter(textStatus);
    var error = $.parseJSON(jqXHR.responseText);
    toastr.error(status + " - " + error.exceptionMessage);
 });

यह एक टोस्टर सूचना में अपवाद संदेश प्रदर्शित करता है लेकिन यह ईमेल टेक्स्ट बॉक्स को input-validation-error का वर्ग नाम नहीं देता, और मुझे यह पसंद है कि वह टेक्स्ट बॉक्स को लाल रंग में प्रदर्शित करेगा

क्या कुछ तरीका वापस करने के लिए वेबएपी नियंत्रक विधियों में कोई रास्ता है जो कि उस टेक्स्टबॉक्स में उस क्लास को जोड़ देगा? मुझे नियमित रूप से पता है। नेट नियंत्रक मैं कर सकता था

ModelState.AddModelError("Email", "This email already exists!")
return View(testObject);

यह उस पाठ बॉक्स के साथ दृश्य वापस करेगा, जिसमें सीएसएस वर्ग का नाम होगा।

किसी भी मदद की सराहना की है

नीचे दिए गए एनकोसी के जवाब के आधार पर:

जब मैं console.log(JSON.stringify(error));

प्रतिक्रिया यह है:

{"$id":"1","message":"The request is invalid.","modelState":
{"$id":"2","email":["This Email Already Exists!"]}} 

ठीक है, इसलिए मैंने JSON प्रतिक्रिया को फिट करने के लिए स्वरूपण बदल दिया है, और मैंने var id = "#" + key.replace('$', ''); भी बदल दिया है var id = "#" + key.replace('$', '');

अब मुझे valmsg.text(value.join()); पर एक त्रुटि प्राप्त हो valmsg.text(value.join()); कह रहा है कि Object doesn't support property or method 'join' .. इसलिए मैंने मूल्य को दिलासा दिया और यह 2 .. नहीं "This Email Already Exists!"

अद्यतन करें

.error(function (jqXHR, textStatus, errorThrown) {
    var error = jqXHR.responseJSON;
    console.log(JSON.stringify(error));
    var message = error.message;
    var modelState = error.modelState;

    $.each(modelState,
        function (key, value) {
            var id = "#" + key.replace('$', '');
            var input = $(id);
            console.log(id); // result is #id
            if (input) { // if element exists
                input.addClass('input-validation-error');
            }
            //get validation message
            var valmsg = $("[data-valmsg-for='" + key + "']");
            if (valmsg) {
                valmsg.text(value.join()); // Object doesn't support property or method 'join'
                valmsg.removeClass("field-validation-valid");
                valmsg.addClass("field-validation-error");
            }

क्या आप ने कोशिश की

return BadRequest("This Email Already Exists!");

BadRequest का एक और संस्करण अपवाद फेंकने के बजाय?


जब आपका दृश्य / एचटीएल वेब एपीआई पद्धति को कॉल करता है तो वेब एपीआई को मूल रूप से यह नहीं पता है कि आपका पेज या इनपुट बॉक्स भी मौजूद हैं। यह विशुद्ध रूप से कुछ इनपुट मिलता है और कुछ आउटपुट देता है। इस मामले में क्योंकि आपने वेब एपीआई में एक अपवाद डाल दिया है, तो http प्रतिसाद एक "आंतरिक सर्वर त्रुटि" के लिए एक त्रुटि कोड 500 है। यह xhr त्रुटि हैंडलर को चलाने के लिए कारण होगा। यह किसी और चीज़ के कारण आदर्श नहीं है (डेटाबेस डाउन, क्लाइंट कनेक्शन गिरा दिया, आदि) आप ईमेल सत्यापन त्रुटि प्रदर्शित करेंगे। प्रत्येक क्षेत्र में सत्यापन के परिणाम देने के लिए एक अधिक जानकारीपूर्ण प्रतिक्रिया देने के लिए एक बेहतर विचार होगा, लेकिन फिर आपको टेस्टऑब्जेक्ट की तुलना में एक प्रतिक्रिया प्रकार की ज़रूरत है, परिणाम की तरह कुछ, जिसके परिणामस्वरूप सत्यापन त्रुटियों के लिए कुछ फ़ील्ड हैं

एक त्वरित समाधान के रूप में आप संभवत: कुछ फ्रंट एंड UI लाइब्रेरी का उपयोग करना चाहते हैं ताकि मैन्युअल रूप से फ़ील्ड में उस क्लास को जोड़ा जा सके। JQuery में उदाहरण, आपके टोस्टर लाइन के पहले / बाद में:

$('#emailfield').addClass('input-validation-error')


यदि आप अपने नियंत्रक में लौट रहे हैं:

ModelState.AddModelError("Email", "This Email Already Exists!");
return BadRequest(ModelState);

फिर जेसन वापस आना चाहिए:

{"Email":["This Email Already Exists!"]}

आपके दृश्य के HTML आउटपुट में, आपके पास एक ऐसा इनपुट होना चाहिए जिसके लिए नाम विशेषता ईमेल पर सेट होनी चाहिए:

<input name="Email" type="text" />

इसी प्रकार, त्रुटि JSON में अन्य सभी कुंजियों के पास उन कुंजी से मिलान करने वाले नाम विशेषताओं के साथ मेल खाने वाला फॉर्म नियंत्रण होगा

तो अपने त्रुटि फ़ंक्शन में, आप चाबियों के माध्यम से लूप कर सकते हैं और उपयुक्त सीएसएस वर्ग लागू कर सकते हैं:

.error(function (jqXHR, textStatus, errorThrown) {
    var error = $.parseJSON(jqXHR.responseText);
    $(error).each(function(i,e)
    {
        $('[name="' + e + '"]').addClass('input-validation-error');
    });

 });

अद्यतन करें

इस नमूना डेटा पर आधारित

{"$id":"1","message":"The request is invalid.","modelState":
{"$id":"2","email":["This Email Already Exists!"]}} 

अमान्य तत्वों को उजागर करने के लिए स्निपेट बन जाएंगे

var handleError = function (jqXHR, textStatus, errorThrown) {
    var error = jqXHR.responseJSON;        
    var message = error.message;
    var modelState = error.modelState;
    //highlight invalid fields                    
    $.each(modelState, function (key, value) {
        var id = "#" + key; //construct id
        var input = $(id); //get the element
        if(input) { //if element exists
            input.addClass('input-validation-error'); //update class
        }            
    });
}

मूल

मूल पीओसी का मूल अंक प्रदर्शित करने के लिए निम्नलिखित पीओसी का इस्तेमाल किया गया था

WebAPI

[HttpGet]
[Route("testobject")]
public IHttpActionResult TestObject() {
    ModelState.AddModelError("Email", "This Email Already Exists!");
    return BadRequest(ModelState);
}

एमवीसी नियंत्रक

[HttpGet, Route("")]
public ActionResult Index() {
    var model = new TestVM();
    return View(model);
}

एमवीसी देखें: सूचकांक

@model TestVM
@{
    ViewBag.Title = "Index";
}
<div class="container">
    <div class="form-group">
        @Html.LabelFor(m => m.Email)
        @Html.TextBoxFor(model => model.Email, new { data_bind = "value: Email", @class = "form-control" })
        @Html.ValidationMessageFor(model => model.Email)
    </div>
    <button type="button" data-bind="click: testEmail" class="btn btn-success submit">Test</button>
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval", "~/bundles/knockout")
    <script type="text/javascript">
        //Pay no attention to this. custom strongly typed helper for routes
        var url = '@(Url.HttpRouteUrl<TestsApiController>(c => c.TestObject()))';
        $(function () {
            /*using knockout for binding*/
            function viewModel() {
                var self = this;
                //properties
                self.Email = ko.observable(@(Model.Email));
                //methods
                self.testEmail = function () {
                    $.ajax({
                        url: url,
                        type: 'Get',
                        contentType: 'application/json',
                        dataType: 'json',
                        success: handleResponse,
                        error: handleError,
                    });
                };

                var handleError = function (jqXHR, textStatus, errorThrown) {
                    var error = jqXHR.responseJSON;
                    console.log(JSON.stringify(error));
                    var message = error.Message;
                    var modelState = error.ModelState;
                    //highlight invalid fields                    
                    $.each(modelState, function (key, value) {
                        var id = "#" + key;
                        $(id).addClass('input-validation-error');
                        //get validation message
                        var valmsg = $("[data-valmsg-for='" + key + "']");
                        if (valmsg) {
                            valmsg.text(value.join());
                            valmsg.removeClass("field-validation-valid");
                            valmsg.addClass("field-validation-error");
                        }
                    });
                }

                var handleResponse = function (data) {
                    //No-op
                };
            }
            var vm = new viewModel();
            ko.applyBindings(vm);
        });

    </script>
}

प्रश्न में मूल उदाहरण के आधार पर अवधारणा के उपरोक्त सबूत का उपयोग करते हुए, परिणामी मॉडल इस तरह देखा गया।

{"Message":"The request is invalid.","ModelState":{"Email":["This Email Already Exists!"]}}

मुख्य रूप से त्रुटि प्रतिक्रिया को संभालने पर ध्यान केंद्रित करते हुए मैं निम्नलिखित संरचना का उपयोग करके वांछित व्यवहार प्राप्त करने में सक्षम था।

var handleError = function (jqXHR, textStatus, errorThrown) {
    var error = jqXHR.responseJSON;
    console.log(JSON.stringify(error));
    //logs {"Message":"The request is invalid.","ModelState":{"Email":["This Email Already Exists!"]}}
    var message = error.Message;
    var modelState = error.ModelState;
    //highlight invalid fields                    
    $.each(modelState, function (key, value) {
        var id = "#" + key;
        $(id).addClass('input-validation-error');
        //get validation message
        var valmsg = $("[data-valmsg-for='" + key + "']");
        if (valmsg) {
            valmsg.text(value.join());
            valmsg.removeClass("field-validation-valid");
            valmsg.addClass("field-validation-error");
        }
    });
}

उपरोक्त जब निष्पादित किया गया था

एक दृश्य से जो निम्नलिखित था

<div class="container">
    <div class="form-group">
        @Html.LabelFor(m => m.Email)
        @Html.TextBoxFor(model => model.Email, new { data_bind = "value: Email", @class = "form-control" })
        @Html.ValidationMessageFor(model => model.Email)
    </div>
    <button type="button" data-bind="click: testEmail" class="btn btn-success submit">Test</button>
</div>






asp.net-mvc-5