ASP.NET MVC में एक दृश्य मौजूद है?


95

क्या यह निर्धारित करना संभव है कि क्या दृश्य प्रदान करने से पहले एक नियंत्रक के भीतर एक विशिष्ट दृश्य नाम मौजूद है?

मुझे रेंडर करने के लिए दृश्य के नाम को गतिशील रूप से निर्धारित करने की आवश्यकता है। यदि उस नाम के साथ कोई दृश्य मौजूद है, तो मुझे उस दृश्य को प्रस्तुत करना होगा। यदि कस्टम नाम से कोई दृश्य नहीं है, तो मुझे एक डिफ़ॉल्ट दृश्य प्रस्तुत करना होगा।

मैं अपने नियंत्रक में निम्नलिखित कोड के समान कुछ करना चाहता हूं:

public ActionResult Index()
{
    var name = SomeMethodToGetViewName();

    // The 'ViewExists' method is what I've been unable to find.
    if (ViewExists(name))
    {
        retun View(name);
    }
    else
    {
        return View();
    }
}

14
इसके शीर्षक को पढ़ते हुए, यह एक बहुत ही गहरे दार्शनिक प्रश्न की तरह लगता है।

जवाबों:


154
 private bool ViewExists(string name)
 {
     ViewEngineResult result = ViewEngines.Engines.FindView(ControllerContext, name, null);
     return (result.View != null);
 }

कॉपी / पेस्ट एक्सटेंशन विधि की तलाश करने वालों के लिए:

public static class ControllerExtensions
{
    public static bool ViewExists(this Controller controller, string name)
    {
        ViewEngineResult result = ViewEngines.Engines.FindView(controller.ControllerContext, name, null);
        return (result.View != null);
    }
}

2
यह शायद बेहतर है। मुझे नहीं पता था कि ViewEngines संग्रह से ही एक FindView विधि बंद थी।
लांस हार्पर

1
लेकिन यह कैसे जांचें कि क्या दृश्य अन्य नियंत्रक के लिए मौजूद है?
सूर्यास्त

एक तरफ की तरह: हमारे इंजीनियरों में से एक (जब से चले गए) ने एक कस्टम व्यू इंजन बनाया (जिसे मल्टीटैन्टिव्यूएंगाइन कहा जाता है, इसलिए आपको इसके उद्देश्य की जानकारी मिलती है) जो दिए गए HttpException (404) को खोजने के लिए FindView को लागू करता है, अगर यह दिया नहीं जा सकता है राय। क्या यह अच्छा अभ्यास है? मुझे पता नहीं है। लेकिन आश्चर्य नहीं होगा अगर वहाँ इस तरह से अन्य कार्यान्वयन हैं। चूँकि आप दृश्य इंजन के आंतरिक कामकाज को नहीं जान पाएंगे क्योंकि यह कोड निष्पादित करता है, आप एक {{झूठा लौटना}; } इस पिल्ला के आसपास, बस सुरक्षित होने के लिए।
ब्रायन कोलोवितो

1
@SOReader, मैंने hvnt का परीक्षण किया लेकिन, IController कंट्रोलर = नया HomeController (); और फिर कंट्रोलर.कंट्रोलरकोनटेक्स्ट वह चीज देगा जिसे आप फाइंडव्यू मेथड में पास कर सकते हैं।
विशाल शर्मा

इस उत्तर के लिए धन्यवाद। इसने मुझे एक और समस्या में मदद की। मुझे यह देखने की ज़रूरत है कि क्या मेरा दृश्य आंशिक है या नहीं और जैसा कि मेरे सभी धारावाहिकों का नाम अंडरलाइन से शुरू होता है, अब मैं अपने समाधान की जाँच के साथ काम कर सकता हूँ अगर "result.View! = Null"
Deise Vicentin

19

निम्नलिखित में से कुछ की कोशिश करने के बारे में क्या आप केवल एक दृश्य इंजन का उपयोग कर रहे हैं:

bool viewExists = ViewEngines.Engines[0].FindView(ControllerContext, "ViewName", "MasterName", false) != null;

ऐसा लगता है कि स्वीकृत उत्तर से 3 मिनट पहले एक पोस्ट किया गया था और अभी तक कोई प्यार नहीं है ?! मुझ से +1।
ट्रेवर डी कोइकोक

@TrevordeKoekkoek ... हम्मम ... + 1
विशाल शर्मा

8

यह करने का एक और तरीका है [जरूरी नहीं कि अनुशंसित]

 try
 {
     @Html.Partial("Category/SearchPanel/" + Model.CategoryKey)
 }
 catch (InvalidOperationException) { }

यह एक .shtml फ़ाइल के भीतर एक आंशिक दृश्य की मौजूदगी के परीक्षण के लिए है। यह वास्तव में इस सवाल का जवाब नहीं है, लेकिन एक और सवाल यह है कि यहाँ लिंक गलत तरीके से बंद किया गया था इसलिए मैं अपना जवाब यहाँ छोड़ रहा हूँ
साइमन_वेचर

2
यह वास्तव में मेरे उपयोग के लिए हाजिर था, क्योंकि मैं एक संस्कृति विशिष्ट आंशिक दृश्य का उपयोग करने का एक तरीका ढूंढ रहा था। इसलिए मैंने इसे केवल संस्कृति विशिष्ट दृश्य नाम के साथ बुलाया, और फिर कैच के अंदर डिफ़ॉल्ट दृश्य कहा। और मैं एक उपयोगिता समारोह में यह कर रहा था, तो मैं करने के लिए पहुँच नहीं था ControllerContextके रूप में FindViewविधि की जरूरत है।
खौफ

2

यदि आप इसे कई नियंत्रक क्रियाओं में फिर से उपयोग करना चाहते हैं, तो डेव द्वारा दिए गए समाधान पर निर्माण करके, आप एक कस्टम दृश्य परिणाम को निम्नानुसार परिभाषित कर सकते हैं:

public class CustomViewResult : ViewResult
{
    protected override ViewEngineResult FindView(ControllerContext context)
    {
        string name = SomeMethodToGetViewName();

        ViewEngineResult result = ViewEngines.Engines.FindView(context, name, null);

        if (result.View != null)
        {
            return result;
        }

        return base.FindView(context);
    }

    ...
}

फिर अपनी कार्रवाई में बस अपने कस्टम दृश्य का एक उदाहरण लौटाएँ:

public ActionResult Index()
{ 
    return new CustomViewResult();
}

1
ViewEngines.Engines.FindView(ViewContext.Controller.ControllerContext, "View Name").View != null

मेरे 2 सेंट।


1

Asp.net core 2.x में वह ViewEnginesसंपत्ति मौजूद नहीं है जिससे हमें ICompositeViewEngineसेवा का उपयोग करना पड़े । यह निर्भरता इंजेक्शन का उपयोग करके स्वीकृत उत्तर का एक प्रकार है:

public class DemoController : Controller
{
    private readonly IViewEngine _viewEngine;

    public DemoController(ICompositeViewEngine viewEngine)
    {
        _viewEngine = viewEngine;
    }

    private bool ViewExists(string name)
    {
        ViewEngineResult viewEngineResult = _viewEngine.FindView(ControllerContext, name, true);
        return viewEngineResult?.View != null;
    }

    public ActionResult Index() ...
}

जिज्ञासु के लिए: आधार इंटरफ़ेस IViewEngineको एक सेवा के रूप में पंजीकृत नहीं किया गया है, इसलिए हमें ICompositeViewEngineइसके बजाय इंजेक्ट करना होगा । FindView()विधि तथापि द्वारा प्रदान की जाती है IViewEngineतो सदस्य चर आधार इंटरफ़ेस का उपयोग कर सकते हैं।


0

कोर 2.2 आदि के लिए रेजर में इसे कैसे करें, ध्यान दें कि कॉल "गेट व्यू" है, न कि "व्यू व्यू")

@using Microsoft.AspNetCore.Mvc.ViewEngines
@inject ICompositeViewEngine Engine
...
@if (Engine.GetView(scriptName, scriptName, isMainPage: false).Success) 
{
    @await Html.PartialAsync(scriptName)
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.