2012-04-04 12 views
8

में लिपटे सामग्री को कैप्चर करें मैं एक स्टार्टफॉर्म स्टाइल एचटीएमएल हेल्पर लिखने की कोशिश कर रहा हूं जो अन्य कोड को लपेटने के लिए आईडीस्पोजेबल का उपयोग करता है। मैं चाहता हूं कि हेल्पर केवल एक निश्चित स्थिति को पूरा करने के लिए लिपटे कोड को प्रस्तुत करे (उदा। उपयोगकर्ता एक निश्चित भूमिका में है)।BeginForm शैली डिस्पोजेबल एचटीएमएल हेल्पर

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

public static IDisposable BeginSecure(this HtmlHelper html, ...) 
    { 
     return new SecureSection(html.ViewContext, ...); 
    } 

    private class SecureSection : IDisposable 
    { 
     private readonly ViewContext _context; 
     private readonly TextWriter _writer; 

     public SecureSection(ViewContext context, ...) 
     { 
      _context = context; 
      _writer = context.Writer; 
      context.Writer = new StringWriter(); 
     } 

     public void Dispose() 
     { 
      if (condition here) 
      { 
       _writer.Write(_context.Writer); 
      } 

      _context.Writer = _writer; 
     } 
    } 

क्या मैं HTML मददगार के साथ संभव करने की कोशिश कर रहा हूं?

मुझे पता है कि रेज़र में घोषणात्मक एचटीएमएल हेल्पर्स शायद काम करेंगे, लेकिन यदि संभव हो तो मानक एचटीएमएल सहायक दृष्टिकोण पसंद करेंगे, एमवीसी 3 में रेज़र हेल्पर्स की एपकोड सीमा को देखते हुए।

उत्तर

6

आप IDisposable लौटने वाले एक सहायक विधि की बॉडी सामग्री को सशर्त रूप से प्रस्तुत नहीं कर सकते हैं। यह हमेशा प्रस्तुत करेगा। सहायक <form> तत्व के साथ BeginForm सहायक जैसे कुछ कस्टम मार्कअप के साथ using ब्लॉक के शरीर को लपेटना चाहते हैं, तो आप हेल्पर्स की इस शैली का उपयोग कर सकते हैं।

आप एक templated Razor delegate बजाय इस्तेमाल कर सकते हैं:

public static class HtmlExtensions 
{ 
    public static HelperResult Secure(this HtmlHelper html, Func<object, HelperResult> template) 
    { 
     return new HelperResult(writer => 
     { 
      if (condition here) 
      { 
       template(null).WriteTo(writer); 
      } 
     }); 
    } 
} 

और उसके बाद:

@Html.Secure(
    @<div> 
     You will see this text only if some condition is met 
    </div> 
) 
9

असल आप सशर्त एक BeginForm की तरह संरचना के साथ सामग्री छुपा सकते हैं। यह केवल आंतरिक StringBuilder साथ थोड़ा खिलवाड़ करना शामिल है:

public class Restricted: IDisposable 
{ 
    public bool Allow { get; set; } 

    private StringBuilder _stringBuilderBackup; 
    private StringBuilder _stringBuilder; 
    private readonly HtmlHelper _htmlHelper; 

    /// <summary> 
    /// Initializes a new instance of the <see cref="Restricted"/> class. 
    /// </summary> 
    public Restricted(HtmlHelper htmlHelper, bool allow) 
    { 
     Allow = allow; 
     _htmlHelper = htmlHelper; 
     if(!allow) BackupCurrentContent(); 
    } 

    private void BackupCurrentContent() 
    { 
     // make backup of current buffered content 
     _stringBuilder = ((StringWriter)_htmlHelper.ViewContext.Writer).GetStringBuilder(); 
     _stringBuilderBackup = new StringBuilder().Append(_stringBuilder); 
    } 

    private void DenyContent() 
    { 
     // restore buffered content backup (destroying any buffered content since Restricted object initialization) 
     _stringBuilder.Length = 0; 
     _stringBuilder.Append(_stringBuilderBackup); 
    } 

    /// <summary> 
    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. 
    /// </summary> 
    public void Dispose() 
    { 
     if(!Allow) 
      DenyContent(); 
    } 
} 

तो फिर तुम सिर्फ एक HtmlHelper कि ऊपर वस्तु का एक उदाहरण बना देता है बनाने की जरूरत है

public static class RestrictedHelper 
{ 
    public static Restricted RestrictedContent(this HtmlHelper htmlHelper, bool allow) 
    { 
     return new Restricted(htmlHelper, allow); 
    } 
} 

प्रयोग इस प्रकार है:

@using (var restricted = Html.Restricted(true)) 
{ 
    <p>This will show up</p> 
} 
@using (var restricted = Html.Restricted(false)) 
{ 
    <p>This won't</p> 
} 

लाभ:

  • अपनी सामग्री को दिखाने/छिपाने के लिए कस्टम तर्क लिखें और इसे प्रतिबंधित कन्स्ट्रक्टर को पास करें।
  • आपके प्रतिबंधित ऑब्जेक्ट में सार्वजनिक गुण आपके दृश्य में कोड के ब्लॉक में पहुंच योग्य हैं, इसलिए आप वहां गणना किए गए मानों का पुन: उपयोग कर सकते हैं।

ASP.Net MVC के साथ परीक्षण किया गया 4

+0

आप टिप्पणी से बाहर कर देना चाहिए "allowcontent" कोड, बस वहाँ कुछ भी नहीं है। अन्यथा मुझे नेस्टेड सामग्री मिलती है। साथ ही, बैक-अप केवल तभी जरूरी है जब अनुमत 'झूठा ' – Alex

+0

धन्यवाद @jitbit, मैंने अपनी पोस्ट अपडेट की है। जिस तरह से एक विचारधारा: इस सुरक्षित वर्ग ने बयान में अंतर्निहित सरल अंतर्निहित मूल्य पर बहुत कम मूल्य जोड़ा है ... यदि आपको HTML में हेरफेर करने की आवश्यकता है, तो मैं केवल यह मार्ग लेता हूं, और अन्य सभी विकल्पों का प्रयास करता हूं। मैंने इस पोस्ट को बनाने के बाद से रेजर के साथ बहुत कुछ काम किया है, और रेज़र में "उपयोग" वाक्यविन्यास को वाक्यविन्यास चीनी के बजाय भाषा दुर्व्यवहार के रूप में देखता है। – Moeri

संबंधित मुद्दे