रेजर घोषणात्मक विचारों से MVC HtmlHelper एक्सटेंशन का उपयोग करना


121

मैं एक MVC 3 RTM प्रोजेक्ट के लिए अपने App_Code फ़ोल्डर में रेजर घोषणात्मक सहायक बनाने की कोशिश कर रहा था।

मैं जिस समस्या में भाग गया, वह एक्शनलिंक की तरह MVC HtmlHelper एक्सटेंशन उपलब्ध नहीं है। इसका कारण यह है कि संकलित सहायकों से प्राप्त होता है System.Web.WebPages.HelperPage, और यद्यपि यह एक Htmlसंपत्ति को उजागर करता है, इसके System.Web.WebPages.HtmlHelperबजाय इसके प्रकार का System.Web.Mvc.HtmlHelper

मुझे किस प्रकार की त्रुटि हो रही थी, उसका एक उदाहरण है:

'System.Web.Mvc.HtmlHelper' में 'ActionLink' के लिए कोई परिभाषा नहीं है और न ही कोई विस्तार विधि 'ActionLink' टाइप का पहला तर्क स्वीकार करते हुए 'System.Web.Mvc.HtmlHelper' पाया जा सकता है (क्या आप एक निर्देश का उपयोग कर गायब हैं या एक विधानसभा संदर्भ?)

मेरा एकमात्र समाधान मेरा अपना हेल्परपेज बनाना और Html संपत्ति को ओवरराइड करना है:

using System.Web.WebPages;

public class HelperPage : System.Web.WebPages.HelperPage 
{
    // Workaround - exposes the MVC HtmlHelper instead of the normal helper
    public static new HtmlHelper Html
    {
        get { return ((System.Web.Mvc.WebViewPage) WebPageContext.Current.Page).Html; }
    }
}

फिर मुझे प्रत्येक सहायक के शीर्ष पर निम्नलिखित लिखना होगा:

@inherits FunnelWeb.Web.App_Code.HelperPage
@using System.Web.Mvc
@using System.Web.Mvc.Html

@helper DoSomething()
{
    @Html.ActionLink("Index", "Home")
}

क्या MVC 3 में यह कठिन है, या मैं कुछ गलत कर रहा हूं?


4
अगर आपको भी Url हेल्पर की आवश्यकता है, तो आप HelperPage में कोड की इस पंक्ति को जोड़ते हैं: सार्वजनिक स्थैतिक UrlHelper Url {{{नया UrlHelper लौटाएं (Html.ViewContext.RequestConttext); }}
मार्को स्टेफोली

जवाबों:


42

इस प्रश्न के Marcindउत्तर पर एक नज़र डालें । आप जो अनुभव कर रहे हैं वह App_Codeफ़ोल्डर में घोषणात्मक विचार रखने की एक सीमा है ।

अपने सहायकों को App_Code कार्यों में लाना लेकिन कुछ सीमाएँ हैं जो कुछ MVC परिदृश्यों को प्रभावित करती हैं (उदाहरण के लिए: मानक MVC Html के लिए कोई पहुँच नहीं। सहायक)


1
अन्य पाठकों के लिए ध्यान दें: यह उत्तर बिल्कुल सही है, लेकिन संभावित वर्कअराउंड के लिए एंड्रयू नर्स के अतिरिक्त योगदान को भी देखें।
जॉर्डन ग्रे

38

मैंने वेबपेज हेल्पर के लिए एक एक्सटेंशन विधि बनाई ताकि मुझे पेज हेल्पर तक पहुंच मिल सके।

public static HtmlHelper GetPageHelper(this System.Web.WebPages.Html.HtmlHelper html)
{
 return ((System.Web.Mvc.WebViewPage) WebPageContext.Current.Page).Html;
}

4
उपयोग:@Html.GetPageHelper().ActionLink("actioname")
deerchao

यह मेरे लिए काम करता है, लेकिन मुझे App_Code के अंदर cshtml हेल्पर्स फ़ाइल को जोड़ना @using System.Web.Mvcऔर जोड़ना था@using System.Web.Mvc.Html
Tomino

1
अलग-अलग HtmlHelper क्लास क्यों हैं? यह वैसा ही होना चाहिए जैसा कि App_Code या व्यूज में है। महाकाव्य आधा-कार्यान्वित डिज़ाइन विफल।
त्रिनको

समझे गए वेबलॉग .asp.net/scottgu/… के द्वारा यहां दिया गया है, जो "वैश्विक" रेजर सहायकों का निर्माण करने का तरीका बताता है। तो फिर, अगर आपको HtmlHelperएन्कोडिंग प्रयोजनों के लिए केवल कक्षा की आवश्यकता है, तो मुझे ऐसा करने का एक और तेज़ तरीका मिल गया है कि यह स्थिर वर्ग के माध्यम से Microsoft.Security.Application.Encoderहै:Encoder.HtmlAttributeEncode(value)
मैट बोरजा

11

उमर को यहां सही जवाब मिला, लेकिन मैं कुछ जोड़ना चाहता था (जवाब के रूप में उमर की प्रतिक्रिया को चिह्नित करने के लिए स्वतंत्र महसूस करता हूं)।

हम v1 में इसके बारे में जानते थे और उत्पाद में शानदार सुधार नहीं कर पाए थे, लेकिन डेविड एबो (एएसपी.नेट टीम के एक वास्तुकार) ने विजुअल स्टूडियो कोड जेनरेटर का एक नमूना पोस्ट किया जो मूल रूप से उपयोग का पहला अन्वेषण था इस काम को ठीक से करने के लिए हम जिस तरह के विचार देख रहे हैं: http://blogs.msdn.com/b/davidebb/archive/2010/10/10/27/turn-your-razor-helpers-into-reusable-lbooks .aspx

इसे आज़माएं और देखें कि आप क्या सोचते हैं! डेविड को बताएं कि क्या आपके ब्लॉग पर पोस्ट करके टिप्पणी है।


2
क्या रेजर के अगले संस्करण में इसे ठीक करने की योजना है? मैंने देखा कि यह अभी भी वीएस 11 बीटा में एक मुद्दा है।
उमर

9

@ जेक जवाब के समान:

public static class MvcIntrinsics {
    public static System.Web.Mvc.HtmlHelper Html {
        get { return ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Html; }
    }

    public static System.Web.Mvc.AjaxHelper Ajax {
        get { return ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Ajax; }
    }

    public static System.Web.Mvc.UrlHelper Url {
        get { return ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Url; }
    }

}

उपयोग:

@MvcIntrinsics.Html.Raw("test")

स्रोत: डिनो एस्पोसिटो - Microsoft ASP.NET MVC प्रोग्रामिंग


1
यह हास्यास्पद है कि यह और भी आवश्यक है, और ये App_Code में विचारों के लिए आधार वर्ग का हिस्सा नहीं हैं।
त्रिनको

7

एक वैकल्पिक समाधान:

इसे अपने रेजर-हेल्पर फ़ाइल के शीर्ष पर जोड़ें:

@functions {
    public static System.Web.Mvc.HtmlHelper<object> HHtml = ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Html;
}

तो इसे इस तरह से कॉल करें:

@HHtml.ActionLink("actionname")

ऐसा लग रहा था कि इसने शुरू में मेरे लिए काम किया था, लेकिन जब हेल्पर को फिर से फोन किया गया तो मुझे 'मान अपेक्षित सीमा के भीतर नहीं गिरता' मिला।
d219

3

मेरा दृष्टिकोण केवल सहायक विधि के लिए एक पैरामीटर के रूप में पृष्ठ को पास करना है। तो आपके उदाहरण में यह होगा:

@helper DoSomething(WebViewPage page)
{
    @page.Html.ActionLink("Index", "Home")
}

फिर अपने रेज़र दृश्य में, जहाँ आपको इसकी आवश्यकता है, इसे इस तरह से कॉल करें:

@YourHelperFilename.DoSomething(this)

ऐसा करने से आपको पेज प्रॉपर्टीज तक पहुँच प्राप्त होती है जैसे कि Htmlया Urlआपके पास आमतौर पर (और उस HtmlHelperएक्सटेंशन के माध्यम से )।

एक अतिरिक्त लाभ के रूप में (यदि आपको इसकी आवश्यकता है), तो आपको पेज की जैसे इंस्टेंस प्रॉपर्टीज की भी सुविधा मिलती है ViewData


3

खोजकर्ताओं के लाभ के लिए, मुझे एक कक्षा पुस्तकालय के भाग के रूप में एमवीसी विचार बनाते समय एक ही त्रुटि मिली (घटक पुन: उपयोग के लिए)। आंशिक रूप से ऊपर दिया गया समाधान, .cshtml फ़ाइल के शीर्ष पर निम्नलिखित कथनों का उपयोग करना था।

@using System.Web.Mvc
@using System.Web.Mvc.Html

कोई और जरूरी काम नहीं।


App_Code के तहत मेरे .cshml में मेरे सहायकों को Intellisense में मान्यता नहीं दी गई थी। @Use System.Web.Mvc.Html को मेरे शीर्ष पर जोड़कर .cshtml के तहत App_code ने काम किया।

जब मैं ऐसा करता हूं, तो मैं "Could not load type 'System.Web.WebPages.Instrumentation.InstrumentationService' from assembly 'System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'."मंडराता हूं @using System.Web.Mvc। कोई विचार?
जोबोरचौस

इससे मेरे लिए कोई फर्क नहीं पड़ता
मेमों

0

मुझे पता है कि MVC 3 के साथ कुछ अंतर्मुखी मुद्दे हैं। मुझे लगता है कि मददगार तब भी काम करेंगे जब आपके पास web.config में नेमस्पेस सेट होगा।

MVC 3 RTM अभी हाल ही में छोड़ा गया है क्या आप इसे या बीटा का उपयोग कर रहे हैं?


0

ऐसा लगता है कि ASP.NET MVC ने वीएस 2013 में इस मुद्दे को ठीक कर दिया है। इस पोस्ट को देखें। http://aspnet.uservoice.com/forums/41201-asp-net-mvc/suggestions/3670180-support-helper-extensionmethod-this- HtmlHelper-HT


नहीं बिल्कुल नहीं। Intellisense एक्सटेंशन के तरीकों को नहीं उठा रहा है, और मेरे पास VS2013 अपडेट है। 5. मेरे पास @using System.Web.Mvc.HtmlApp_Code में cshtml फाइल में सबसे ऊपर है, लेकिन @Html लिखना .... से कोई भी विस्तार विधि नहीं पता चलता है EditorFor। यह हास्यास्पद है कि यह 2 प्रमुख रिलीज़ और ब्लॉग पोस्ट के बाद काम नहीं कर रहा है, यह दावा करता है कि इसे लागू किया गया था। यह। वास्तव में, एक्स्टेंशन के तरीके काम नहीं कर सकते, क्योंकि वे System.Web.Mvc.HtmlHelper क्लास को टारगेट करते हैं, न कि System.Web.WebPages.HtmlHelper क्लास को, जो System.Web.WebPages.elperPage क्लास द्वारा एक्सपोज़ किया जाता है।
त्रिनको
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.