Jquery ajax के साथ ASP.NET MVC सत्यापन का उपयोग करें?


119

मैं इस तरह ASP.NET MVC कार्रवाई सरल है:

public ActionResult Edit(EditPostViewModel data)
{

}

इस EditPostViewModelतरह सत्यापन गुण हैं:

[Display(Name = "...", Description = "...")]
[StringLength(100, MinimumLength = 3, ErrorMessage = "...")]
[Required()]
public string Title { get; set; }

देखने में मैं निम्नलिखित सहायकों का उपयोग कर रहा हूं:

 @Html.LabelFor(Model => Model.EditPostViewModel.Title, true)

 @Html.TextBoxFor(Model => Model.EditPostViewModel.Title, 
                        new { @class = "tb1", @Style = "width:400px;" })

यदि मैं एक फॉर्म पर सबमिट करता हूं कि यह टेक्स्टबॉक्स एक सत्यापन में रखा गया है तो पहले ग्राहक पर और फिर सेवा पर ( ModelState.IsValid) किया जाएगा।

अब मुझे कुछ प्रश्न मिले:

  1. क्या इसके बजाय jQuery के अजाक्स सबमिट के साथ इसका उपयोग किया जा सकता है? मैं जो कर रहा हूं वह केवल फॉर्म को हटा दें और सबमिट बटन पर क्लिक करने पर एक जावास्क्रिप्ट डेटा इकट्ठा करेगा और फिर रन करेगा $.ajax

  2. क्या सर्वर साइड ModelState.IsValidकाम करेगा?

  3. मैं सत्यापन समस्या को क्लाइंट को कैसे अग्रेषित कर सकता हूं और इसे पेश कर सकता हूं जैसे कि इम इंट इंटेलीजेंस ( @Html.ValidationSummary(true)) का उपयोग कर रहा है ?

अजाक्स कॉल का उदाहरण:

function SendPost(actionPath) {
    $.ajax({
        url: actionPath,
        type: 'POST',
        dataType: 'json',
        data:
        {
            Text: $('#EditPostViewModel_Text').val(),
            Title: $('#EditPostViewModel_Title').val() 
        },
        success: function (data) {
            alert('success');
        },
        error: function () {
            alert('error');
        }
    });
}

1 संपादित करें:

पेज पर शामिल:

<script src="/Scripts/jquery-1.7.1.min.js"></script>
<script src="/Scripts/jquery.validate.min.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.min.js"></script>

नीचे अच्छा जवाब। यहाँ एक संबंधित प्रश्न है। उत्तर क्लाइंट-साइड या सर्वर-साइड सत्यापन के लिए अनुमति देता है। मुझे उनके द्वारा प्रदान किए गए JQuery कोड से प्यार है। (नहीं, यह मेरा जवाब नहीं था।) stackoverflow.com/questions/28987752/…
एडवेंचर

जवाबों:


155

ग्राहक की ओर

jQuery.validateलाइब्रेरी का उपयोग करना बहुत आसान होना चाहिए।

अपनी Web.configफ़ाइल में निम्नलिखित सेटिंग्स निर्दिष्ट करें :

<appSettings>
    <add key="ClientValidationEnabled" value="true"/> 
    <add key="UnobtrusiveJavaScriptEnabled" value="true"/> 
</appSettings>

जब आप अपना दृष्टिकोण बनाते हैं, तो आप चीजों को इस तरह परिभाषित करेंगे:

@Html.LabelFor(Model => Model.EditPostViewModel.Title, true)
@Html.TextBoxFor(Model => Model.EditPostViewModel.Title, 
                                new { @class = "tb1", @Style = "width:400px;" })
@Html.ValidationMessageFor(Model => Model.EditPostViewModel.Title)

नोट: इनको एक तत्व तत्व के रूप में परिभाषित किया जाना चाहिए

फिर आपको निम्नलिखित पुस्तकालयों को शामिल करना होगा:

<script src='@Url.Content("~/Scripts/jquery.validate.js")' type='text/javascript'></script>
<script src='@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")' type='text/javascript'></script>

यह आपको क्लाइंट साइड सत्यापन के लिए सेट करने में सक्षम होना चाहिए

साधन

सर्वर साइड

नोट: यह केवल jQuery.validationलाइब्रेरी के शीर्ष पर अतिरिक्त सर्वर साइड सत्यापन के लिए है

शायद ऐसा कुछ मदद कर सकता है:

[ValidateAjax]
public JsonResult Edit(EditPostViewModel data)
{
    //Save data
    return Json(new { Success = true } );
}

कहाँ ValidateAjaxविशेषता के रूप में परिभाषित किया गया है:

public class ValidateAjaxAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!filterContext.HttpContext.Request.IsAjaxRequest())
            return;

        var modelState = filterContext.Controller.ViewData.ModelState;
        if (!modelState.IsValid)
        {
            var errorModel = 
                    from x in modelState.Keys
                    where modelState[x].Errors.Count > 0
                    select new
                           {
                               key = x,
                               errors = modelState[x].Errors.
                                                      Select(y => y.ErrorMessage).
                                                      ToArray()
                           };
            filterContext.Result = new JsonResult()
                                       {
                                           Data = errorModel
                                       };
            filterContext.HttpContext.Response.StatusCode = 
                                                  (int) HttpStatusCode.BadRequest;
        }
    }
}

यह क्या करता है एक JSON ऑब्जेक्ट को आपके सभी मॉडल त्रुटियों को निर्दिष्ट करते हुए लौटाता है।

उदाहरण प्रतिक्रिया होगी

[{
    "key":"Name",
    "errors":["The Name field is required."]
},
{
    "key":"Description",
    "errors":["The Description field is required."]
}]

यह $.ajaxकॉल के कॉलबैक से आपकी त्रुटि को वापस किया जाएगा

आप दिए गए कुंजी संदेशों के आधार पर त्रुटि संदेशों को सेट करने के लिए दिए गए डेटा के माध्यम से लूप कर सकते हैं (मुझे लगता है कि ऐसा कुछ $('input[name="' + err.key + '"]')आपके इनपुट तत्व को मिलेगा।


1
महान जवाब, विशेष रूप से भयानक ValidateAjaxAttribute के साथ! धन्यवाद!
रेने

3
मुझे समझ नहीं आता कि इस जवाब को इतने वोट क्यों मिले। यह प्रश्न 1 का उत्तर नहीं देता है: $ .ax के साथ पोस्ट करते समय क्लाइंट सत्यापन कैसे करें? मुझे लगता है कि @ श्याजू जवाब से मदद मिलती है।
वैलेंटाइन

2
@ वैलेंटिन - मेरा जवाब मदद करता है, क्योंकि डेटा के रूप में अच्छी तरह से सर्वर की ओर से मान्य है। सत्यापन प्लग-इन को गतिशील सत्यापन सक्षम करना चाहिए क्योंकि फ़ॉर्म भरा हुआ है, और जब फ़ॉर्म सबमिट किया जाता है (हालांकि ओपी ऐसा करना चाहता है), तो सर्वर अंतिम सत्यापन प्रदान करेगा, जो कि ग्राहक पक्ष सत्यापन को बाईपास किया जा सकता है, जो बेहतर है।
एंड्रयू बर्गेस

8
मैं लौटे हुए त्रुटियों के माध्यम से jQuery के सत्यापन संदेश स्पैन का उपयोग करता हूं और त्रुटि संदेश को सही अवधि में सम्मिलित करता हूं:for (var i = 0; i < modelStateErrors.length; i++) { $('span[data-valmsg-for="' + modelStateErrors[i].key + '"]').text(modelStateErrors[i].errors[0]); }
इयान

7
यह जवाब बहुत अच्छा है! लेकिन मुझे अभी भी लगता है कि ASP.NET MVC फ्रेमवर्क को ऐसा करने का एक अंतर्निहित तरीका प्रदान करना चाहिए।
जिगंड

40

आपको क्या करना चाहिए अपने प्रपत्र डेटा को क्रमबद्ध करें और इसे नियंत्रक कार्रवाई को भेजें। ASP.NET MVC EditPostViewModelऑब्जेक्ट के लिए प्रपत्र डेटा (आपके एक्शन विधि पैरामीटर) को बांध देगा , MVC मॉडल बाइंडिंग सुविधा का उपयोग करेगा।

आप क्लाइंट फॉर्म में अपना फॉर्म सत्यापित कर सकते हैं और यदि सब कुछ ठीक है, तो डेटा को सर्वर पर भेजें। valid()विधि काम में आ जाएगा।

$(function () {

    $("#yourSubmitButtonID").click(function (e) {

        e.preventDefault();
        var _this = $(this);
        var _form = _this.closest("form");

        var isvalid = _form .valid();  // Tells whether the form is valid

        if (isvalid)
        {           
           $.post(_form.attr("action"), _form.serialize(), function (data) {
              //check the result and do whatever you want
           })
        }

    });

});

1
धन्यवाद! मैंने इस $ ("फॉर्म #" + फॉर्मआईड) .validate () की कोशिश की, लेकिन यह कहता है कि फॉर्म (जो मिला है) में एक मान्य () नहीं है?
आइवी

Edit1 देखें जहां मैं दिखाता हूं कि वेबपेज पर मान्य स्क्रिप्ट शामिल है। मैं यह भी देखता हूं कि नियमित इनपुट प्रकार सबमिट बटन का उपयोग करते समय सत्यापन चल रहा है।
आइवी

मुझे समस्या मिली (मास्टरपेज से लिपियों को हटा दिया गया)। लेकिन अभी भी क्लाइंट के लिए ModelState सत्यापन त्रुटियों को वापस भेजने के लिए समस्याएं हैं? मैं कैसे कर सकता हूँ? उदाहरण के लिए यदि उपयोगकर्ता अब लॉगइन नहीं है (ModelState.AddModelError ("CustomError", "validation text")।
Ivy

1
आपको अपने पृष्ठ में jquery.validate और jquery.validate.unobtrusive js फ़ाइलों को शामिल करने की आवश्यकता है। आपके HTML इनपुट में वह विशेषता है जो सत्यापन प्लगइन्स के लिए है?
श्यजु

1
Ivy: आपका रिटर्न प्रकार (ActionResult) JsonResult का एक आधार वर्ग है। इसलिए यह JSON डेटा वापस कर सकता है। आपको क्या करना चाहिए, यदि यह एक अजाक्स कॉल है (Request.IsAjax की जांच करें), सत्यापन त्रुटियां प्राप्त करें और JSON का निर्माण करें और इसे क्लाइंट को वापस भेजें। $ .Post की कॉलबैक विधि में json की जाँच करें और त्रुटि संदेश दिखाएं।
श्यजु

9

यहाँ एक सरल समाधान है:

नियंत्रक में हम अपनी त्रुटियों को इस तरह वापस करते हैं:

if (!ModelState.IsValid)
        {
            return Json(new { success = false, errors = ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage).ToList() }, JsonRequestBehavior.AllowGet);
        }

यहाँ ग्राहक स्क्रिप्ट के कुछ है:

function displayValidationErrors(errors)
{
    var $ul = $('div.validation-summary-valid.text-danger > ul');

    $ul.empty();
    $.each(errors, function (idx, errorMessage) {
        $ul.append('<li>' + errorMessage + '</li>');
    });
}

हम इसे अजाक्स के माध्यम से कैसे संभालते हैं:

$.ajax({
    cache: false,
    async: true,
    type: "POST",
    url: form.attr('action'),
    data: form.serialize(),
    success: function (data) {
        var isSuccessful = (data['success']);

        if (isSuccessful) {
            $('#partial-container-steps').html(data['view']);
            initializePage();
        }
        else {
            var errors = data['errors'];

            displayValidationErrors(errors);
        }
    }
});

इसके अलावा, मैं निम्नलिखित तरीकों से ajax के माध्यम से आंशिक विचार प्रस्तुत करता हूं:

var view = this.RenderRazorViewToString(partialUrl, viewModel);
        return Json(new { success = true, view }, JsonRequestBehavior.AllowGet);

RenderRazorViewToString विधि:

public string RenderRazorViewToString(string viewName, object model)
    {
        ViewData.Model = model;
        using (var sw = new StringWriter())
        {
            var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext,
                                                                     viewName);
            var viewContext = new ViewContext(ControllerContext, viewResult.View,
                                         ViewData, TempData, sw);
            viewResult.View.Render(viewContext, sw);
            viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
            return sw.GetStringBuilder().ToString();
        }
    }

3
आपके "GetModelStateErrors" को एक तरह से सरल सिंगल-लाइन स्टेटमेंट में परिवर्तित करके पूरी तरह से सरल बनाया जा सकता है: वापसी ModelState.Values.SelectMany (x => x.Errors) .Select (x = >rrorMessage) .ToList ();
कैमिलो तेरेविंटो

1
क्यों नहीं PartialViewअजाक्स को प्रस्तुत करने के लिए बस एक वापसी ?
सिंजई

4

@Andrew Burgess द्वारा प्रदान किए गए समाधान के लिए कुछ और तर्क जोड़े। यहाँ पूर्ण समाधान है:

अजाक्स अनुरोध के लिए त्रुटियाँ प्राप्त करने के लिए एक एक्शन फ़िल्टर बनाया गया:

public class ValidateAjaxAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (!filterContext.HttpContext.Request.IsAjaxRequest())
                return;

            var modelState = filterContext.Controller.ViewData.ModelState;
            if (!modelState.IsValid)
            {
                var errorModel =
                        from x in modelState.Keys
                        where modelState[x].Errors.Count > 0
                        select new
                        {
                            key = x,
                            errors = modelState[x].Errors.
                                                          Select(y => y.ErrorMessage).
                                                          ToArray()
                        };
                filterContext.Result = new JsonResult()
                {
                    Data = errorModel
                };
                filterContext.HttpContext.Response.StatusCode =
                                                      (int)HttpStatusCode.BadRequest;
            }
        }
    }

फ़िल्टर को मेरी नियंत्रक विधि में जोड़ा गया:

[HttpPost]
// this line is important
[ValidateAjax]
public ActionResult AddUpdateData(MyModel model)
{
    return Json(new { status = (result == 1 ? true : false), message = message }, JsonRequestBehavior.AllowGet);
}

Jquery सत्यापन के लिए एक सामान्य स्क्रिप्ट जोड़ा गया:

function onAjaxFormError(data) {
    var form = this;
    var errorResponse = data.responseJSON;
    $.each(errorResponse, function (index, value) {
        // Element highlight
        var element = $(form).find('#' + value.key);
        element = element[0];
        highLightError(element, 'input-validation-error');

        // Error message
        var validationMessageElement = $('span[data-valmsg-for="' + value.key + '"]');
        validationMessageElement.removeClass('field-validation-valid');
        validationMessageElement.addClass('field-validation-error');
        validationMessageElement.text(value.errors[0]);
    });
}

$.validator.setDefaults({
            ignore: [],
            highlight: highLightError,
            unhighlight: unhighlightError
        });

var highLightError = function(element, errorClass) {
    element = $(element);
    element.addClass(errorClass);
}

var unhighLightError = function(element, errorClass) {
    element = $(element);
    element.removeClass(errorClass);
}

अंत में मेरे अजाक्स आरंभ फॉर्म में त्रुटि जावास्क्रिप्ट विधि जोड़ी गई:

@model My.Model.MyModel
@using (Ajax.BeginForm("AddUpdateData", "Home", new AjaxOptions { HttpMethod = "POST", OnFailure="onAjaxFormError" }))
{
}

1

आप इसे इस तरह से कर सकते हैं:

( संपादित करें: यह देखते हुए कि आप के jsonसाथ प्रतिक्रिया की प्रतीक्षा कर रहे हैं dataType: 'json')

नेट

public JsonResult Edit(EditPostViewModel data)
{
    if(ModelState.IsValid) 
    {
       // Save  
       return Json(new { Ok = true } );
    }

    return Json(new { Ok = false } );
}

जे एस:

success: function (data) {
    if (data.Ok) {
      alert('success');
    }
    else {
      alert('problem');
    }
},

यदि आपको आवश्यकता है, तो मैं यह भी समझा सकता हूं कि त्रुटि 500 ​​को वापस करके यह कैसे करें, और त्रुटि को त्रुटि (ajax) में प्राप्त करें। लेकिन आपके मामले में यह एक विकल्प हो सकता है


1
मुझे पता है कि नियमित जेसन अनुरोध कैसे किया जाता है, लेकिन यह मुझे अलग-अलग गुणों के सत्यापन के साथ मदद नहीं करेगा या यहां तक ​​कि एएसपी.नेट एमवीसी सत्यापन में निर्मित का उपयोग करें जो मैंने पूछा था। मैं शायद हर प्रॉब्लम के लिए वेलिडेशन एरर्स को समझाने के लिए एक जटिल जेसन ऑब्जेक्ट का निर्माण कर सकता हूं, लेकिन यह काम का एक बहुत कुछ होगा और मैं उम्मीद कर रहा हूं कि आप इसके लिए ASP.NET MVC वेलिडेशन की कार्यक्षमता में निर्मित पुन: उपयोग कर सकते हैं?
आइवी

1 - अपने फ़ंक्शन "SendPost" को कैसे चलाएं ?, और 2 - क्लाइंट पर आपका वैध डेटा?
andres descalzo

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