Q: How to conditionally output part of a view using a helper method So, let's say I have the following part of a view:
<td>
    @Html.ActionLink("Delete")
</td>

I only want this to be available to a user if they have a certain permission - DeleteItems.  A couple ways to do this would be to wrap the link with an if statement or to make an overload for the ActionLink helper that takes in a set of permissions.
If version:
@if (User.HasPermission(Permissions.DeleteItems))
{
<td>
    @Html.ActionLink("Delete", "Delete")
</td>
}

Overload version:
<td>
    @Html.ActionLink("Delete", "Delete", Permissions.DeleteItems)
</td>

Cool - I think the obvious winner here is the overload.
However, what if the area I want to block off is larger?
<div class="deleteWrapper">
    <table>
        <tr>
            <td>Id</td>
            <td></td>
        </tr>
        @foreach (var item in items)
        {
            <tr>
                <td>@item.Id</td>
                <td>@Html.ActionLink("Delete", "Delete", new { id = @item.Id })
            </tr>
        }
    </table>
</div>

The If version still works, of course, but I don't want to have @if (User.Has...(...)) everywhere in my views.  What I like is the syntax of Html.BeginForm:
@using(Html.BeginForm(...))
{
    ...
}

However, BeginForm only adds to the response - it doesn't actually do anything with the piece of the view in between the brackets.  Is there a way to remove the markup inside the brackets using a helper?
@using(Html.ShowIf(...))
{
    ...
}


A: Yes, you can. Here is an example that works only for Razor:
@using (this.BeginPermissionScope(Permissions.DeleteItems))
{
    using (Html.BeginForm("Delete", "Home"))
    {
        <input type="submit" value="Submit" />
    }
}

C# Code:
public static class HtmlHelperPermissionScopeExtensions
{
    /// <summary>
    /// Begin new rendering scope based on current user permissions
    /// </summary>
    public static IDisposable BeginPermissionScope(this WebViewPage webViewPage, Permissions permission)
    {
        var currentIdentity = webViewPage.User.Identity;
        bool userHasPermission = currentIdentity.HasPermission(permission);
        return new PermissionScopeHelper(webViewPage, !userHasPermission);
    }

    /// <summary>
    /// Helper class that replaces current output stream with its own
    /// </summary>
    private sealed class PermissionScopeHelper : IDisposable
    {
        WebViewPage webViewPage;
        TextWriter oldWriter;
        TextWriter newWriter;

        /// <summary>
        /// Initializes helper class instance. If ignoreMarkupUntilDispose is set to true, then 
        /// all markup writen to response will be ignored
        /// </summary>
        public PermissionScopeHelper(WebViewPage page, bool ignoreMarkupUntilDispose)
        {
            if (ignoreMarkupUntilDispose)
            {
                webViewPage = page;
                newWriter = new StringWriter();

                // Replace output TextWriter for Write() and WriteLiteral() methods
                webViewPage.OutputStack.Push(newWriter);

                // Replace output TextWriter for all HtmlHelper and AjaxHelper extensions
                oldWriter = webViewPage.ViewContext.Writer;
                webViewPage.ViewContext.Writer = newWriter;
            }
        }

        /// <summary>
        /// Restore output TextWriters
        /// </summary>
        public void Dispose()
        {
            if (webViewPage != null)
            {
                webViewPage.ViewContext.Writer = oldWriter;
                webViewPage.OutputStack.Pop();
                newWriter.Dispose();
            }
        }
    }

}

