asp.net-mvc-4 - 如何使用辅助方法有条件地输出 View 的一部分

标签 asp.net-mvc-4 razor

所以,假设我有 View 的以下部分:

<td>
    @Html.ActionLink("Delete")
</td>

我只希望用户拥有特定权限 - DeleteItems 才能使用此功能。执行此操作的几种方法是使用 if 语句包装链接,或者对接受一组权限的 ActionLink 帮助程序进行重载。

如果版本:

@if (User.HasPermission(Permissions.DeleteItems))
{
<td>
    @Html.ActionLink("Delete", "Delete")
</td>
}

重载版本:

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

酷 - 我认为这里明显的赢家是过载。

但是,如果我要遮挡的区域更大怎么办?

<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>

当然,If 版本仍然有效,但我不想到处都有 @if (User.Has...(...))在我看来。我喜欢的是 Html.BeginForm 的语法:

@using(Html.BeginForm(...))
{
    ...
}

但是,BeginForm only adds to the response - 它实际上并没有对括号之间的 View 片段做任何事情。有没有办法使用助手删除括号内的标记?

@using(Html.ShowIf(...))
{
    ...
}

最佳答案

是的,可以。以下是仅适用于 Razor 的示例:

@using (this.BeginPermissionScope(Permissions.DeleteItems))
{
    using (Html.BeginForm("Delete", "Home"))
    {
        <input type="submit" value="Submit" />
    }
}

C# 代码:

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();
            }
        }
    }

}

关于asp.net-mvc-4 - 如何使用辅助方法有条件地输出 View 的一部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19028905/

相关文章:

asp.net-mvc-4 - Lightbox 2 将我重定向到图像文件

ajax - 在 AJAX 调用后将新的 DOM 元素绑定(bind)到 View 模型

c# - 显示进度条,直到 Webgrid 完全加载并分页到 MVC 中 Webgrid 中的下一页或上一页

c# - ASP.NET MVC4 显示所有注册用户名

c# - ASP.NET MVC 4 : Changing the Value of a Hidden field in Javascript

asp.net-mvc - MVC 3 从 web.config 中的 AppSettings 获取值

javascript - 在 KNockout 中绑定(bind)文本框

asp.net-mvc-3 - 自定义 RazorViewEngine 出现页面错误

asp.net-mvc-4 - 使用 Bootstrap 日期时间选择器、Asp.Net MVC4 应用程序中的 Jquery 验证插件验证日期和日期时间

css - 如果 cshtml 中没有头部,则将 css 放在哪里