MVC 登录页面的无样式(CSS)和 JavaScript 解决方案
如何解决 MVC 登录页面样式缺失或 JavaScript 功能不足的问题。
引言
一个需要严格限制除特定用户外任何人无法访问的 Web 应用程序让我很头疼,因为它无法正确显示样式或接受 JavaScript。这是我解决问题的方法,让页面看起来更好,用户也更满意。
背景
在开发一个 Web 应用程序时,我遇到了两个问题。
- 登录页面的格式没有正确显示。
- 我想让用户首次访问页面时,光标聚焦在用户名输入框。
我明白至少有一个问题与访问权限有关;然而,直到研究了问题 1,我才意识到问题 2 与此类似。这听起来可能很简单,但却难住了我,而且在网上搜索也未能明确指出问题所在。因此,我创建这篇文章,希望成为一个一站式解决方案。
我使用的是 Razor 视图,如果您使用的是 ASP.NET,则需要对语法进行必要的调整。但核心概念应该是一样的。
我使用 Visual Studio 2010 进行开发,我的分步说明假定您使用相同的环境;然而,这些步骤应该很容易迁移到其他开发环境。
使用代码
我们将处理两个标准文件:
- Web.Config
- LogOn.cshtml
我创建了一个自定义文件:
- setfocus.js
我使用的文件夹和文件名如下。(我相信这是默认设置)
- 视图
- Account
- LogOn.cshtml
- 脚本
- setfocus.js
- Content
- Site.css
让我们从 setfocus.js 文件开始。
我们将在 Scripts 文件夹中创建这个文件。说明如下。
- 在解决方案资源管理器中,将鼠标指针悬停在 Scripts 文件夹上。
- 按鼠标右键或右键单击。
- 会出现一个弹出屏幕。
- 将鼠标指针悬停在“添加”上。
- 会出现另一个弹出菜单。
- 在该屏幕中选择“新建 JavaScript 文件....”。
- 将创建一个新文件。
- 选择文件,它会是一串数字,将其重命名为 setfocus(文件的完整名称应为 setfocus.js)。
setfocus.js 内容
/* simple function to set focus on an MVC controller */
/* ready the document and create a function*/
$(document).ready(function(){
/* a class named username will receive the focus */
$('.username').first().focus();
});
现在是 LogOn.cshtml 文件。
我对这个文件做了一些小的调整,因为我不想让用户拥有注册或找回密码的功能。如果您想包含这些选项,请不要完全复制粘贴此代码。我将指出哪些代码段是重要的。
@model MemberTracker.Models.LogOnModel
@{
ViewBag.Title = "Log On";
}
<h2>Log On</h2>
<p>
Please enter your user name and password.
</p>
<!--Add this line to run the javascript that will set the focus on the control.-->
<script type="text/javascript" src="@Url.Content("~/Scripts/setfocus.js")"></script>
@Html.ValidationSummary(true, "Login was unsuccessful. Please correct the errors and try again.")
@using (Html.BeginForm()) {
<div>
<fieldset>
<legend>Account Information</legend>
<div class="editor-label">
@Html.LabelFor(m => m.UserName)
</div>
<div class="editor-field">
<!--You will need to add a class to the control so that it knows which one to focus on as you
can see from the line below we added new { @class = "username"} to the Html tag. You need to
add the @ to the class so the Razor does not pic up class code. -->
@Html.TextBoxFor(m => m.UserName, new { @class = "username" })
@Html.ValidationMessageFor(m => m.UserName)
</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.CheckBoxFor(m => m.RememberMe)
@Html.LabelFor(m => m.RememberMe)
</div>
<p>
<input type="submit" value="Log On" />
</p>
</fieldset>
</div>
}
web.config 文件
这就是所有魔法发生的地方。正如我之前提到的,问题在于,当您锁定站点强制登录时,您实际上并没有允许任何人访问站点上的文件夹/文件。这包括 Content 或 Scripts 等路径文件夹!基本上,您阻止了用户查看这些信息。好了,现在是魔法。我们需要向 Web.Config 文件添加一些代码块,以允许用户访问文件。
首先是为 Content 文件夹和部分样式提供权限。
我们将以下内容添加到**主** web.config 文件中。(也就是位于根目录下的那个),**而不是** View 文件夹中的那个。
您应该在 web.config 文件中有一个 <system.web> 部分。既然您在阅读本文,我将假定您已经阻止了用户访问,并将身份验证方法设置为 Forms。
这是您应该看到的片段。
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
<authorization>
<deny users="?"/>
</authorization>
现在,让我们通过使用一个鲜为人知的标记 location 来添加代码,以允许用户查看样式。
此代码块将添加到上面显示的 <system.web> 标记之上。注释已包含在代码中。
<!--Added above the prior system.web and path is equal to the folder or file that you want to permission-->
<location path="Content/Site.css">
<system.web>
<!--authorize the users and set users to * implying all users can access the path or file-->
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
将所有内容放在一起后,看起来会像这样。
<!--Added above the prior system.web and path is equal to the folder or file that you want to permission-->
<location path="Content/Site.css">
<system.web>
<!--authorize the users and set users to * implying all users can access the path or file-->
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
<authorization>
<deny users="?"/>
</authorization>
现在授予 JavaScript 文件访问权限。
我不想重复,但这有点啰嗦。我们将创建另一个 location 标记,这次的路径将是 Scripts,我们将把它放在 web.config 文件中其他 <location> 标记的上方。
代码:需要注意的是,在此代码和路径中,我们没有为特定文件设置权限,这没关系,我们将其设置为文件夹。
<location path="Scripts">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
我将为您节省另一个代码块,只需将其放在 web.config 中其他 <location> 标记的上方,保存它,您应该就搞定了。
您的站点在登录时应该看起来正常,或者至少看起来是您想要的样子,并且为了不让用户沮丧,光标会直接定位在他们想要的位置,而无需他们点击或使用鼠标。
关注点
您的站点现在应该看起来正常,或者至少看起来是您想要的样子,在登录时,为了不让用户沮丧,光标会直接定位在他们想要的位置,而无需他们点击。正如我在开头所说,这不是很明显,我不得不进行一些搜索。我有一个引用,那就是 Scott Gu 的博客,其中提供了关于 <location> 标记的信息。
历史
版本 1