MVC 3: कैसे अपने लेआउट पृष्ठ के बिना एक दृश्य प्रस्तुत करने के लिए जब AJAX के माध्यम से भरी हुई है?


153

मैं प्रोग्रेसिव एनहांसमेंट के बारे में सीख रहा हूं और मेरे पास AJAXifying विचारों के बारे में एक सवाल है। मेरे MVC 3 प्रोजेक्ट में मेरा एक लेआउट पृष्ठ, एक व्यूस्टार्ट पृष्ठ और दो सादे दृश्य हैं।

व्यूस्टार्ट पृष्ठ दृश्य फ़ोल्डर की जड़ में है और इस प्रकार सभी दृश्यों पर लागू होता है। यह निर्दिष्ट करता है कि सभी विचारों को _Layout.cshtmlउनके लेआउट पृष्ठ के लिए उपयोग करना चाहिए । लेआउट पृष्ठ में दो नेविगेशन लिंक होते हैं, प्रत्येक दृश्य के लिए एक। लिंक @Html.ActionLink()पृष्ठ पर खुद को प्रस्तुत करने के लिए उपयोग करते हैं ।

अब मैंने jQuery जोड़ लिया है और इन लिंक्स को हाईजैक करना चाहता हूं और पृष्ठ पर अपनी सामग्री को गतिशील रूप से लोड करने के लिए अजाक्स का उपयोग करना चाहता हूं।

<script type="text/javascript">
    $(function () {
        $('#theLink').click(function () {
            $.ajax({
                url: $(this).attr('href'),
                type: "GET",
                success: function (response) {
                    $('#mainContent').html(response);
                }
            });
            return false;
        });
    });
</script>

ऐसा करने के लिए मैं दो तरीके सोच सकता हूं, लेकिन मैं विशेष रूप से एक को पसंद नहीं करता हूं:

1) मैं संपूर्ण दृश्य की सामग्री ले सकता हूं और उन्हें आंशिक दृश्य में रख सकता हूं, फिर मुख्य दृश्य को आंशिक दृश्य के रूप में प्रस्तुत करता है जब यह प्रदान किया जाता है। इस तरह, Request.IsAjaxRequest()नियंत्रक में उपयोग करते हुए , मैं अनुरोध या अजाक्स अनुरोध के आधार पर View()वापस लौट सकता हूं PartialView()या नहीं। मैं अजाक्स अनुरोध पर नियमित दृश्य नहीं लौटा सकता क्योंकि तब यह लेआउट पृष्ठ का उपयोग करेगा और मुझे इंजेक्ट किए गए लेआउट पृष्ठ की दूसरी प्रतिलिपि मिलेगी। हालाँकि, मुझे यह पसंद नहीं है क्योंकि यह मुझे @{Html.RenderPartial();}मानक GET अनुरोधों के लिए उनके साथ खाली विचार बनाने के लिए मजबूर करता है।

    public ActionResult Index()
    {
        if (Request.IsAjaxRequest())
            return PartialView("partialView");
        else
            return View();
    }

फिर Index.cshtml में ऐसा करें:

@{Html.RenderPartial("partialView");}

2) मैं _viewstart से लेआउट पदनाम को हटा सकता हूं और अनुरोध अजाक्स नहीं होने पर इसे मैन्युअल रूप से निर्दिष्ट कर सकता हूं:

    public ActionResult Index()
    {
        if (Request.IsAjaxRequest())
            return View(); // Return view with no master.
        else
            return View("Index", "_Layout"); // Return view with master.
    }

क्या किसी के पास बेहतर सुझाव है? क्या इसके लेआउट पृष्ठ के बिना किसी दृश्य को वापस करने का कोई तरीका है? यह स्पष्ट रूप से कहना आसान होगा "यदि आपका लेआउट शामिल नहीं है" अगर यह एक अजाक्स अनुरोध है, तो यह स्पष्ट रूप से लेआउट को शामिल करने के लिए होगा यदि यह अजाक्स नहीं है।

जवाबों:


259

इन ~/Views/ViewStart.cshtml:

@{
    Layout = Request.IsAjaxRequest() ? null : "~/Views/Shared/_Layout.cshtml";
}

और नियंत्रक में:

public ActionResult Index()
{
    return View();
}

3
क्या इसे व्यूस्टार्ट में निर्दिष्ट किया जा सकता है?
Chev

10
@ मैट ग्रीर, आप इसे बुरा कहते हैं, मैं इसे DRY कहता हूं, वैसे भी व्यक्तिपरक सामान :-)
डारिन दिमित्रोव

2
मुझे स्वीकार करना होगा, मुझे यह पहले पसंद नहीं था, लेकिन इसे सहेजने वाले कोड की मात्रा बहुत कम है, यह उल्टा है। यह एक साधारण बूलियन है और अगर वास्तव में ज्यादा आईएमओ नहीं लगाया जाता है। मुझे अपने एक्शन के तरीकों को हर एक बार आधा करने से बेहतर है। साथ ही यह मुझे वह करने से रोकता है जो आपने कहा था कि मैट और संभावित रूप से एक्शन विधि में दो विशाल लॉजिक पथ नीचे जा रहे हैं। मैं या तो दोनों मामलों में समान काम करने के लिए कार्रवाई लिखता हूं, या एक नई कार्रवाई लिखता हूं।
Chev

1
क्या आप आधार नियंत्रक में ऐसा नहीं कर सकते, ViewData में एक संपत्ति सेट करें और उसका उपयोग करें? तब रेखा होगी Layout = ViewBag.LayoutFile
RPM1984

2
मुझे लगता है कि मैं कर सकता था, लेकिन वास्तव में एक छोटी सी रेखा के लिए बेसकंट्रोलर क्यों बना?
Chev

92

बस पृष्ठ के शीर्ष पर निम्नलिखित कोड डालें

@{
    Layout = "";
}

4
यह काम नहीं करता है क्योंकि मैं लेआउट को चालू या बंद करने में सक्षम होना चाहता हूं क्योंकि यह AJAX के माध्यम से अनुरोध किया गया है या नहीं। यह आपको केवल लेआउट को बंद करने की अनुमति देता है, इसे टॉगल करने की नहीं।
Chev

4
यह वोट अप क्यों है ?? pls समझाता हूं तो मैं भी इसे वोट करूंगा।
उस्मान यूनास

1
@UsmanY। आपको इसे वोट करने की आवश्यकता नहीं है। पर मै करता हू। मेरी दलीलें google.com.pk/#q=mvc3%20view%20without%20layout पर जाएं । और यह उस प्रश्न का सही उत्तर है।
सामी

3
विषय दो अलग-अलग परिदृश्यों पर लेआउट को टॉगल करने के बारे में है। यह उत्तर सिर्फ सेट को खाली करने के लिए है, चाहे वह कैसा भी हो।
राजशेखर रेड्डी

यार, यह काम करता है और यह वास्तव में अच्छा है। मैं जिस परिदृश्य का उपयोग करता हूं: अनधिकृत उपयोगकर्ता लॉग इन करने की कोशिश करता है, कोई नहीं चाहता कि त्रुटि पृष्ठ लिंक को दिखाए और अनधिकृत उपयोगकर्ता को आगे दिखाए! बेशक, यह बाकी सब के लिए भी काम करता है!
जोसेफडॉगी

13

मैं पसंद करता हूं, और आपके # 1 विकल्प का उपयोग करता हूं। मुझे # 2 पसंद नहीं है क्योंकि मुझे लगता है View()कि आप एक पूरा पृष्ठ वापस कर रहे हैं। एक बार व्यू इंजन के साथ हो जाने के बाद यह पूरी तरह से fleshed out और मान्य HTML पेज होना चाहिए। PartialView()HTML की मनमानी मात्रा वापस करने के लिए बनाया गया था।

मुझे नहीं लगता कि यह एक बड़ा दृष्टिकोण है जो सिर्फ एक आंशिक कॉल करता है। यह अभी भी DRY है, और आपको दो परिदृश्यों में आंशिक के तर्क का उपयोग करने की अनुमति देता है।

बहुत से लोग अपनी कार्रवाई के कॉल पथों को खंडित करना पसंद करते हैं Request.IsAjaxRequest(), और मैं इसकी सराहना कर सकता हूं। लेकिन IMO, यदि आप सब कर रहे हैं, तो यह तय करना है कि कॉल करना है View()या नहीं PartialView()तो शाखा कोई बड़ी बात नहीं है और इसे बनाए रखना आसान है (और परीक्षण)। यदि आप अपने आप को यह पता लगाने के IsAjaxRequest()लिए उपयोग कर रहे हैं कि आपका एक्शन कैसे चलता है, तो एक अलग AJAX कार्रवाई करना बेहतर है।


13

दो लेआउट बनाएँ: 1. खाली लेआउट, 2। मुख्य लेआउट और फिर _viewStart फ़ाइल में यह कोड लिखें:

@{
if (Request.IsAjaxRequest())
{
    Layout = "~/Areas/Dashboard/Views/Shared/_emptyLayout.cshtml";
}
else
{
    Layout = "~/Areas/Dashboard/Views/Shared/_Layout.cshtml";
}}

बेशक, शायद यह सबसे अच्छा समाधान नहीं है


8

आपको इसके लिए खाली दृश्य बनाने की आवश्यकता नहीं है।

नियंत्रक में:

if (Request.IsAjaxRequest())
  return PartialView();
else
  return View();

एक PartialViewResult को वापस करते हुए लेआउट की परिभाषा को ओवरराइड करेगा जब जिम्मेदारी प्रदान करना।


2

ASP.NET 5 के साथ अब कोई अनुरोध चर उपलब्ध नहीं है। अब आप इसे Context.Request के साथ एक्सेस कर सकते हैं

इसके अलावा कोई IsAjaxRequest () विधि नहीं है, आपको इसे अपने आप से लिखना होगा, उदाहरण के लिए एक्सटेंशन \ HttpRequestExtensions.cs में

using System;
using Microsoft.AspNetCore.Http;

namespace Microsoft.AspNetCore.Mvc
{
    public static class HttpRequestExtensions
    {
        public static bool IsAjaxRequest(this HttpRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            return (request.Headers != null) && (request.Headers["X-Requested-With"] == "XMLHttpRequest");
        }
    }
}

मैंने इस पर अब थोड़ी देर खोज की और आशा है कि कुछ अन्य लोगों को भी मदद मिलेगी;)

संसाधन: https://github.com/aspnet/AspNetCore/issues/2729


-5

रूल्स ऑन रेल्स एप्लिकेशन के लिए, मैं render layout: falseकंट्रोलर एक्शन में निर्दिष्ट करके एक लेआउट को लोड करने से रोकने में सक्षम था जिसे मैं ajax html के साथ जवाब देना चाहता था।


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