我怎样才能避免在asp.net mvc视图中使用无法编写的代码

leo*_*ora 6 asp.net asp.net-mvc views

我发现越来越多的我的asp.net mvc视图开始看起来像我的旧的糟糕的asp代码,我永远无法维护或保持清洁与集成的<%%>和html放在一起.下面我有一个我正在谈论的代码sammple.是否有任何最佳实践或建议的方法来避免这种情况并保持视图更易于维护和可读.

            <td>
                <%
                    bool userRequiresApproval = false;
                    if (!string.IsNullOrEmpty(item.loginName))
                    {
                        MembershipUserCollection membership = (MembershipUserCollection)ViewData["UnapprovedUsers"];
                        if (membership != null && membership[item.loginName] != null)
                        {
                            userRequiresApproval = true;
                        }
                    }
                    bool isLoggedInUserAdmin = false;
                    if (ViewData.ContainsKey("isAdmin"))
                    {
                        isLoggedInUserAdmin = (bool)ViewData["isAdmin"];
                    }
                    if (isLoggedInUserAdmin && userRequiresApproval)
                    {%>
                        <%= Html.ActionLink("View", "Details", new { id=item.Mail_ID })%>, <%= Html.ActionLink("Delete", "GotoDeleteConfirmPage", new { id = item.Mail_ID })%>, <%= Html.ActionLink("Approve", "Approve", new { id = item.Mail_ID })%>
                    <%}
                    else if (isLoggedInUserAdmin)
                    {%>
                        <%= Html.ActionLink("View", "Details", new { id = item.Mail_ID })%>, <%= Html.ActionLink("Delete", "GotoDeleteConfirmPage", new { id = item.Mail_ID })%>
                    <%}
                    else
                    {%>
                        <%= Html.ActionLink("View", "Details", new { id = item.Mail_ID })%>
                    <%}%>
        </tr>
        <% } %>
Run Code Online (Sandbox Code Playgroud)

Rex*_*x M 14

我将首先解决具体问题,然后是摘要:

具体

一种可能的途径可能是创建一套Html帮助程序或用户控件,它们具有一些基本逻辑来确定它们是否应该可见.例如,您的用法可能是:

<td>
    Html.LinkList(", "
        ActionLinks.ViewDetails(item),
        ActionLinks.DeleteAndConfirm(item),
        ActionLinks.Approve(item))
</td>
Run Code Online (Sandbox Code Playgroud)

每个操作都包含自己的逻辑,用于确定是否应该使用它(例如"我需要管理员权限"),如果该操作确定不符合自己的标准,则返回string.Empty:

class ActionLinks
{
    public static string Approve(Item item)
    {
        if(ItemRequiresApproval(item) && CurrentUserIsAdmin())
        {
            return Html.ActionLink("Approve", "Approve", new { id = item.Mail_ID });
        }
        else
        {
            return string.Empty;
        }
    }

    private static bool ItemRequiresApproval(Item item)
    {
        //determine whether item requires approval
        //this could be further broken into a separate utilities class
    }

    private static bool CurrentUserIsAdmin()
    {
        //this should definitely go in a separate class dedicated to
        //handling membership and authorization
        //as well as figuring out who the current user is
    }
}
Run Code Online (Sandbox Code Playgroud)

LinkList看起来像这样:

string LinkList(string delimiter, params string[] links)
{
    StringBuilder sb = new StringBuilder();
    foreach(string link in links)
    {
        if(!string.IsNullOrEmpty(link))
        {
            sb.Append(delimiter);
            sb.Append(link);
        }
    }
    return sb.ToString().Substring(delimiter.Length);
}
Run Code Online (Sandbox Code Playgroud)

抽象

您的问题的解决方案在于记住SRP(单一责任原则)SOC(关注点分离).在您当前的示例中,您的View是一个类.您已使该类不仅对标记的整体结构负责,而且对几乎整个应用程序的每一分钟细节负责!您的视图不应该知道或关心管理员权限或批准.只有批准按钮才能知道批准.只有管​​理员特定的元素才应该知道管理员权限.如果您发现自己重复某些类型的检查(例如,"如果管理员显示x,否则显示y"),请创建一些通用包装器,如AdminPanel,它将自动打开或关闭.对于所有其他参与者来说,一个给定的元素仅仅是或者不是 - 并且该元素是做出该决定的责任.