繁体   English   中英

主页中的ASP.NET MVC2登录表单

[英]ASP.NET MVC2 Login form in master page

我试图在母版页中找到一种优雅的登录表单方式。 这意味着除非用户登录,否则登录表单应出现在每个页面上。 (这几天很常见)

以Visual Studio中MVC2应用程序随附的示例为例,我创建了以下代码:

public class MasterViewModel
{
    public string User { get; set; } // omitted validation attributes
    public string Pass{ get; set; }
    public bool RememberMe { get; set; }
}

每个视图模型都继承自MasterViewModel

public class RegisterViewModel : MasterViewModel
{
    public string UserName { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }
    public string ConfirmPassword { get; set; }
}

我的母版页呈现部分视图

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage<MyLogon.ViewModels.MasterViewModel>" %>
.....
            <div id="logindisplay">
                <% Html.RenderPartial("LogOn"); %>
            </div> 
......

强类型的局部视图:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MyLogon.ViewModels.MasterViewModel>" %>
    <%
        if (Request.IsAuthenticated) {
    %>
            Welcome <b><%= Html.Encode(Page.User.Identity.Name) %></b>!
            <div>[ <%= Html.ActionLink("Change Password", "ChangePassword", "Account") %> ]</div>        
            <div>[ <%= Html.ActionLink("Log Off", "LogOff", "Account") %> ]</div>
    <%
        }
        else {
    %> 
        <%= Html.ValidationSummary(true, "Login was unsuccessful. Please correct the errors and try again.") %>

        <% using (Html.BeginForm("LogOn", "Account",FormMethod.Post)) { %>
            <div>
                <fieldset>
                    <legend>Account Information</legend>

                    <div class="editor-label">
                        <%= Html.LabelFor(m => m.User) %>
                    </div>
                    <div class="editor-field">
                        <%= Html.TextBoxFor(m => m.User) %>
                        <%= Html.ValidationMessageFor(m => m.User) %>
                    </div>

                    <div class="editor-label">
                        <%= Html.LabelFor(m => m.Pass) %>
                    </div>
                    <div class="editor-field">
                        <%= Html.PasswordFor(m => m.Pass) %>
                        <%= Html.ValidationMessageFor(m => m.Pass) %>
                    </div>

                    <div class="editor-label">
                        <%= Html.CheckBoxFor(m => m.RememberMe) %>
                        <%= Html.LabelFor(m => m.RememberMe) %>
                    </div>              
                    <p>
                        <input type="submit" value="Log On" />
                    </p>
                </fieldset>
            </div>
        <% } %>
    <%
        }
    %>

注册页面:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MyLogon.Models.RegisterViewModel>" %>
...
    <h2>Create a New Account</h2>
    <p>
        Use the form below to create a new account. 
    </p>
    <p>
        Passwords are required to be a minimum of <%= Html.Encode(ViewData["PasswordLength"]) %> characters in length.
    </p>

    <% using (Html.BeginForm("Register", "Account" ,FormMethod.Post))
       { %>
        <%= Html.ValidationSummary(true, "Account creation was unsuccessful. Please correct the errors and try again.") %>
        <div>
            <fieldset>
                <legend>Account Information</legend>

                <div class="editor-label">
                    <%= Html.LabelFor(m => m.UserName) %>
                </div>
                <div class="editor-field">
                    <%= Html.TextBoxFor(m => m.UserName) %>
                    <%= Html.ValidationMessageFor(m => m.UserName) %>
                </div>

                <div class="editor-label">
                    <%= Html.LabelFor(m => m.Email) %>
                </div>
                <div class="editor-field">
                    <%= Html.TextBoxFor(m => m.Email) %>
                    <%= Html.ValidationMessageFor(m => m.Email) %>
                </div>

                <div class="editor-label">
                    <%= Html.LabelFor(m => m.Password) %>
                </div>
                <div class="editor-field">
                    <%= Html.PasswordFor(m => m.Password) %>
                    <%= Html.ValidationMessageFor(m => m.Password) %>
                </div>

                <div class="editor-label">
                    <%= Html.LabelFor(m => m.ConfirmPassword) %>
                </div>
                <div class="editor-field">
                    <%= Html.PasswordFor(m => m.ConfirmPassword) %>
                    <%= Html.ValidationMessageFor(m => m.ConfirmPassword) %>
                </div>

                <p>
                    <input type="submit" value="Register" />
                </p>
            </fieldset>
        </div>
    <% } %>
</asp:Content>

由于所有视图模型都继承自MasterViewModel LogOn,因此始终可以满足部分视图的需求,但是我发现这种解决方案非常精致。 还有其他方法可以做到这一点吗?

您可以按原样使用部分视图,但是根据登录状态可以使用不同的视图。 将具有登录表单/登录名的匿名用户的一个视图返回到注册页面,并为登录用户返回另一个视图。

局部视图可以具有自己的模型,这些模型不需要从主视图模型继承。

继承模型可能会在以后引起问题(使用html.EditForModel().DisplayForModel()棘手,因为它们也会呈现通用的主视图字段)。

哦,总的来说,视图依赖模型之外的任何东西都是不好的做法-您对Request.IsAuthenticated的测试目前可能还不错,但是如果您想绝对正确,则应该设置一个model.IsAuthenticated属性通过行动。 也就是说,切换视图将完全消除此问题。

编辑:最后一项改进。 在这样的行上:

Welcome <b><%= Html.Encode(Page.User.Identity.Name) %></b>!

而是:

Welcome <b><%: Page.User.Identity.Name %></b>!

实际上,更好的方法是只打模型:

Welcome <b><%: model.Username %></b>!

(请注意<%: not <%= )。 这种形式的标签指示内容应为HTML编码。 更好的是,如果遇到string ,它将对其进行编码。 如果遇到HTMLString ,则不会。 所有.Net MVC函数都返回适当的字符串或HTML字符串,因此您可以执行以下操作:

<%: html.EditFor(x => x.fieldname) %>
<%: model.somefield %>

第一个将不会进行html编码,因为EditFor()返回HTMLString 第二个将被编码(如果somefield是标准字符串)

这将使您的代码既整洁又健壮。 您也可以使用它来动态生成HTML(如果必须进行编码/不适当编码)。 例如,我们有一些辅助功能要处理,包括CSS / JS。 他们返回HTMLStrings ...

<%: Helper.IncludeCSS("SomeCSS.css") %>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM