Skip to content Skip to sidebar Skip to footer

Capture Wrapped Content In Beginform Style Disposable Html Helper

I am trying to write a BeginForm style html helper that uses IDisposable to wrap other code. I want the helper to only render the wrapped code if a certain condition is met (e.g. u

Solution 1:

Actually you can conditionally hide content with a BeginForm-like structure. It only involves messing with the internal StringBuilder a bit:

publicclassRestricted: IDisposable
{
    publicbool Allow { get; set; }

    private StringBuilder _stringBuilderBackup;
    private StringBuilder _stringBuilder;
    privatereadonly HtmlHelper _htmlHelper;

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

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

    privatevoidDenyContent()
    {
        // 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>publicvoidDispose()
    {
        if(!Allow)
            DenyContent();
    }
}

Then you just need to make an HtmlHelper that makes an instance of the above object

publicstaticclassRestrictedHelper
{
    publicstatic Restricted RestrictedContent(this HtmlHelper htmlHelper, bool allow){
        returnnewRestricted(htmlHelper, allow);
    }
}

Usage is as follows:

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

Advantages:

  • Write custom logic to show/hide your content and pass it to the Restricted constructor.
  • public properties in your Restricted object are accessible in the block of code in your view, so you can reuse calculated values there.

Tested with ASP.Net MVC 4

Solution 2:

You can't conditionally render the body contents of a helper method returning IDisposable. It will always render. You could use this style of helpers when you want to wrap the body of the using block with some custom markup such as the BeginForm helper does with the <form> element.

You could use a templated Razor delegate instead:

publicstaticclassHtmlExtensions
{
    publicstatic HelperResult Secure(this HtmlHelper html, Func<object, HelperResult> template)
    {
        returnnew HelperResult(writer =>
        {
            if (condition here)
            {
                template(null).WriteTo(writer);
            }
        });
    }
}

and then:

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

Post a Comment for "Capture Wrapped Content In Beginform Style Disposable Html Helper"