ASP.Net MVC 服务器资源管理器(第一部分)





5.00/5 (9投票s)
服务器资源管理器是一个应用程序,它介绍并说明了如何使用 ASP.NET MVC 和 Visual Studio 2010 进行 Web 开发。
概述
我们正在构建的应用程序简单地将服务器文件显示为窗口资源管理器,您可以选择要下载的文件夹或文件。
双击一个文件夹,将列出所有子文件夹和文件。
您可以勾选复选框以下载您想要的文件夹和文件。
1. 创建 ASP.Net MVC 项目
这不是本文的重点。我们会很快地过一遍。我们将从在 Visual Web Developer 的“文件”菜单中选择“新建项目”开始。这将打开“新建项目”对话框。我们将在左侧选择“Visual C# -> Web 模板”组,然后选择“ASP.NET MVC 3 空 Web 应用程序”模板。将您的项目命名为 ServerExplorer,然后按“确定”按钮。
这将创建我们的项目。项目包括文件夹:Content、Models、Controllers 和 Views。
ASP.NET MVC 使用一些基本的文件夹命名约定。
/Controllers
Controllers 响应来自浏览器的输入,决定如何处理它,并向用户返回响应。
/Views
Views 包含我们的 UI 模板。
/Models
Models 存储和操作数据。
/Content
此文件夹包含我们的图像、CSS 和任何其他静态内容。
/Scripts
此文件夹包含我们的 JavaScript 文件。
/App_Data
此文件夹包含我们的数据库文件。
2. Models、Views 和 Controllers
基于 Web 的 MVC 框架以略有不同的方式将 URL 映射到服务器代码。它们不是将传入的 URL 映射到文件,而是将 URL 映射到类中的方法。这些类称为“Controllers”,它们负责处理传入的 HTTP 请求、处理用户输入、检索和保存数据以及确定要发送回客户端的响应(显示 HTML、下载文件、重定向到其他 URL 等)。
添加 Model
在创建控制器和视图之前,我们先考虑一下您需要的模型。对于 ServerExploer,我们需要一个具有基本文件信息的模型类,例如文件名、完整路径、最后修改时间、创建时间等。
右键单击“解决方案资源管理器”中的“Models”文件夹,然后选择“添加”,然后选择“类…”命令。这将打开“添加新项”对话框。选择类模板。将类命名为“FileModel”,然后按“添加”按钮。这将创建一个新文件 FileModel.cs。将以下代码添加到 FileModel.cs。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
namespace ServerExplorer.Models
{
public enum FileType
{
Folder,
File,
Zip,
Exe,
Music,
Video,
Xml,
Picture,
Dll,
Config,
FixedRoot,
NetworkRoot,
RemovableRoot,
DiscRoot,
SysRoot
}
public class Category
{
FileType value;
public Category(FileType type)
{
value = type;
}
public FileType Value
{
get { return value; }
}
public override bool Equals(object obj)
{
if (obj is Category)
return value.Equals((obj as Category).value);
return base.Equals(obj);
}
public override string ToString()
{
switch (value)
{
case FileType.Folder:
return "Folder";
case FileType.File:
return "File";
case FileType.Zip:
return "Zip";
case FileType.Config:
return "Config";
case FileType.Dll:
return "Dll";
case FileType.Exe:
return "Exe";
case FileType.Music:
return "Music";
case FileType.Picture:
return "Picture";
case FileType.Video:
return "Video";
case FileType.Xml:
return "Xml";
case FileType.FixedRoot:
return "FixedRoot";
case FileType.SysRoot:
return "SysRoot";
case FileType.NetworkRoot:
return "NetworkRoot";
case FileType.DiscRoot:
return "DiscRoot";
case FileType.RemovableRoot:
return "RemovableRoot";
default:
return "File";
}
}
}
public class FileModel
{
public string Extension { get; set; }
public string Name { get; set; }
public string Location { get; set; }
public DateTime Created { get; set; }
public DateTime Modified { get; set; }
public DateTime Accessed { get; set; }
public string FullPath { get; set; }
public Category Category { get; set; }
public FileModel(FileInfo fi)
{
Name = fi.Name;
Modified = fi.LastWriteTime;
Created = fi.CreationTime;
Accessed = fi.LastAccessTime;
Extension = fi.Extension.ToLower();
Location = fi.DirectoryName;
FullPath = Encode(fi.FullName);
switch (Extension)
{
case ".exe":
Category = new Category(FileType.Exe);
break;
case ".config":
Category = new Category(FileType.Config);
break;
case ".dll":
Category = new Category(FileType.Dll);
break;
case ".zip":
Category = new Category(FileType.Zip);
break;
case ".xml":
Category = new Category(FileType.Xml);
break;
case ".mp3":
Category = new Category(FileType.Music);
break;
case ".wmv":
Category = new Category(FileType.Video);
break;
case ".bmp":
case ".jpg":
case ".jpeg":
case ".png":
case ".gif":
case ".cur":
case ".jp2":
case ".ami":
case ".ico":
Category = new Category(FileType.Picture);
break;
default:
Category = new Category(FileType.File);
break;
}
}
public FileModel(DirectoryInfo di)
{
Name = di.Name;
FullPath = Encode(di.FullName);
Location = di.Parent != null ? di.Parent.FullName : "";
Modified = di.LastWriteTime;
Created = di.CreationTime;
Accessed = di.LastAccessTime;
Category = new Category(FileType.Folder);
}
public static string Encode(string filepath)
{
return filepath.Replace("\\", "/");
}
public static string Decode(string filepath)
{
return filepath.Replace("/", "\\");
}
public static IList<FileModel> GetRootDirectories()
{
List<FileModel> result = new List<FileModel>();
DriveInfo[] drives = DriveInfo.GetDrives();
string winPath = Environment.GetEnvironmentVariable("windir");
string winRoot = Path.GetPathRoot(winPath);
foreach (DriveInfo di in drives)
{
if (!di.IsReady)
continue;
if (di.RootDirectory == null)
continue;
if (di.RootDirectory.FullName == winRoot)
{
result.Add(new FileModel(di.RootDirectory) {
Category = new Category(FileType.SysRoot) });
continue;
}
switch (di.DriveType)
{
case DriveType.CDRom:
result.Add(new FileModel(di.RootDirectory) {
Category = new Category(FileType.DiscRoot) });
break;
case DriveType.Fixed:
result.Add(new FileModel(di.RootDirectory) {
Category = new Category(FileType.FixedRoot) });
break;
case DriveType.Network:
result.Add(new FileModel(di.RootDirectory) {
Category = new Category(FileType.NetworkRoot) });
break;
case DriveType.Removable:
result.Add(new FileModel(di.RootDirectory) {
Category = new Category(FileType.RemovableRoot) });
break;
default:
result.Add(new FileModel(di.RootDirectory));
break;
}
}
return result;
}
public static IList<FileModel> GetFiles(string path)
{
List<FileModel> result = new List<FileModel>();
if (string.IsNullOrEmpty(path))
{
return GetRootDirectories();
}
else
path = Decode(path);
try
{
string[] dirs = Directory.GetDirectories(path, "*.*",
SearchOption.TopDirectoryOnly);
foreach (string dir in dirs)
{
DirectoryInfo di = new DirectoryInfo(dir);
result.Add(new FileModel(di));
}
string[] files = Directory.GetFiles(path, "*.*",
SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
FileInfo fi = new FileInfo(file);
result.Add(new FileModel(fi));
}
result.Sort((a, b) =>
{
var name1 = a.Name;
var name2 = b.Name;
if (a.Category.Value == FileType.Folder)
name1 = " " + name1;
if (b.Category.Value == FileType.Folder)
name2 = " " + name2;
return name1.CompareTo(name2);
});
return result;
}
catch (Exception)
{
}
return result;
}
}
}
添加 Explorer Controller
右键单击“解决方案资源管理器”中的“Controllers”文件夹,然后选择“添加”,然后选择“Controller…”命令。这将打开“添加 Controller”对话框。将 Controller 命名为“ExplorerController”,然后按“添加”按钮。
这将创建一个新文件 ExplorerController.cs。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ServerExplorer.Models;
namespace ServerExplorer.Controllers
{
public class ExplorerController : Controller
{
//
// GET: /Explorer/
public ActionResult Index()
{
IList<FileModel> files = FileModel.GetFiles(null);
return View(files);
}
public ActionResult LoadActionLinks(string path, List<string> list)
{
ViewData["CheckedList"] = list;
return PartialView("ActionLinks", path);
}
public ActionResult GetFiles(string path)
{
IList<FileModel> files = FileModel.GetFiles(path);
ViewData["Parent"] = path;
return PartialView("FileList", files);
}
public ActionResult Download(string jlist)
{
System.Web.Script.Serialization.JavaScriptSerializer serializer =
new System.Web.Script.Serialization.JavaScriptSerializer();
List<string> list = serializer.Deserialize<List<string>>(jlist);
ZipResult result = new ZipResult();
foreach (string path in list)
{
result.AddFile(FileModel.Decode(path));
}
return result;
}
public ActionResult GoUpper(string path)
{
string filePath = FileModel.Decode(path);
IList<FileModel> files = new List<FileModel>();
if (filePath == "root")
files = FileModel.GetRootDirectories();
else
if (Directory.Exists(filePath))
{
DirectoryInfo di = new DirectoryInfo(filePath);
if (di.Parent != null)
{
files = FileModel.GetFiles(di.Parent.FullName);
if (di.Parent.Parent != null)
ViewData["Parent"] = FileModel.Encode(
di.Parent.Parent.FullName);
else
ViewData["Parent"] = "root";
}
else
{
files = FileModel.GetRootDirectories();
}
}
return PartialView("FileList", files);
}
public ActionResult GoTop()
{
var files = FileModel.GetRootDirectories();
return PartialView("FileList", files);
}
}
}
添加视图
将文本光标定位在 Index 操作方法内,然后右键单击并选择“添加视图”。这将打开“添加视图”对话框。
当我们单击“添加”按钮时,Visual Studio 将在 \Views\Explorer 目录中为我们创建一个新的 Index.aspx 视图模板,如果该文件夹尚不存在,则会创建它。
以下是 index.aspx 的代码。
<%@ Page Title="" Language="C#" MasterPageFile="Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %> <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> ServerExplorer </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <div id="listpane"> <% Html.RenderPartial("FileList");%> </div> </asp:Content>%>
因为我们希望动态更新文件列表内容而不是整个页面,所以它使用 Html.RenderPatial 来渲染一个视图模板 FileList。
添加部分视图
ASP.NET MVC 支持定义部分视图模板,这些模板可用于封装页面子部分的视图渲染逻辑。部分视图提供了一种在应用程序中的多个位置定义一次视图渲染逻辑并重用它的有用方法。
右键单击“解决方案资源管理器”中的“\Views\Shared”文件夹,然后选择“添加”,然后选择“View…”命令。这将显示“添加视图”对话框。我们将要创建的新视图命名为 FileList,在对话框中选择“创建部分视图”复选框,并指示我们将向其传递一个 FileModel 类。
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<ServerExplorer.Models.FileModel>>" %> <script src="<%= Url.Content("~/Scripts/jQuery-1.4.4.js") %>" type="text/javascript"></script> <div id="commands"> <% Html.RenderPartial("ActionLinks", ViewData["Parent"]);%> </div> <table id="listview"> <tr class="noselect"> <th id="one"/> <th id="two"> Name </th> <th id="three"> Date modified </th> </tr> <% foreach (var item in Model) { %> <tr class="t-row noselect""> <td class="one"> <%: Html.CheckBox("fileCheck", new {value = item.FullPath })%> </td> <td class="two"> <img width="24" height="24" alt="<%= item.Category.ToString() %>" src="<%= Url.Content("~/Content/Images/" + item.Category.ToString() + ".png") %>" style="vertical-align: middle;" /> <span style="padding-left: 2px;"> <%= item.Name %></span> </td> <td class="three"> <%: String.Format("{0:g}", item.Modified) %> </td> <td> <%= Html.Hidden("fullPath", item.FullPath) %> </td> </tr> <% } %> </table> <script type="text/javascript"> $(function () { $.extend($.fn.disableTextSelect = function () { return this.each(function () { if ($.browser.mozilla) {//Firefox $(this).css('MozUserSelect', 'none'); } else if ($.browser.msie) {//IE $(this).bind('selectstart', function () { return false; }); } else {//Opera, etc. $(this).mousedown(function () { return false; }); } }); }); }); $(document).ready(function () { $("#listview .t-row").click(function () { $("#listview tr").removeClass("t-state-selected"); $(this).toggleClass("t-state-selected"); }); $("#listview .t-row").dblclick(function () { var path = getApplicationPath(); var filename = jQuery("input[name=fullPath]", this).val(); $.ajax({ type: "POST", url: path + "Explorer/GetFiles", data: { path: filename }, cache: false, dataType: "html", success: function (data) { $('#listpane').html(data); } }) }); $(':checkbox').click(function () { var list = new Object; var i = 0; var filename = '<%= ViewData["Parent"] %>'; var path = getApplicationPath(); $("input:checkbox:checked").each(function () { list[i++] = $(this).val(); }); $.ajax({ type: "POST", url: path + "Explorer/LoadActionLinks", data: { path: filename, list: list }, cache: false, dataType: "html", success: function (data) { $('#commands').html(data); } }) }); //No text selection on elements with a class of 'noSelect' $('.noselect').disableTextSelect(); $("#listview .t-row:first").click(); }); function getApplicationPath() { var path = location.pathname; var index = path.indexOf("/Explorer"); if (index > -1) return path.substr(0, index + 1); if (path.charAt(path.length - 1) != '/') path += '/'; return path; } </script>
我们在 FileList.ascx 中调用另一个部分视图模板“ActionLinks”。因为我们也需要动态地部分更新“ActionLinks”。
右键单击“解决方案资源管理器”中的“\Views\Shared”文件夹,然后选择“添加”,然后选择“View…”命令。这将显示“添加视图”对话框。我们将要创建的新视图命名为 ActionLinks,在对话框中选择“创建部分视图”复选框。以下代码是 ActionLinks.ascx。
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<dynamic>" %> <% bool upperEnabled = !string.IsNullOrEmpty(Model as string); List<string> list = ViewData["CheckedList"] as List<string>; string jList = ""; if (list != null && list.Count > 0) { System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); jList = serializer.Serialize(list); } { %> <p> <a id="top" <% if (upperEnabled) { %> href='javascript:goTop();' <% } %> style="padding-left: .4em;"><span>Top</span></a> | <a id="upper" <% if (upperEnabled) { %> href='javascript:goUpper("<%= Model %>");' <% } %> style="padding-left: .4em;"><span>Upper</span></a> | <a id="download" <% if (jList != "") { %> href='javascript:download();' <% } %> style="padding-left: .4em;"><span>Download</span></a> </p> <%} %> <script type="text/javascript"> function goUpper(path) { $.ajax({ type: "POST", url: getApplicationPath() + "Explorer/GoUpper", data: { path: path }, cache: false, dataType: "html", success: function (data) { $('#listpane').html(data); } }) } function goTop() { $.ajax({ type: "POST", url: getApplicationPath() + "Explorer/GoTop", data: {}, cache: false, dataType: "html", success: function (data) { $('#listpane').html(data); } }) } function download() { var list = '<%= jList %>'; var path = getApplicationPath() + "Explorer/Download/?jlist=" + list; window.location.href = path; } </script>
在 ActionLinks.ascx 中,它渲染两个链接,一个是“上级”(返回上一级文件夹),另一个是“下载”。
禁用锚点标签
IE 支持对锚点标签上的非标准属性 'disabled' 提供半成品实现(它会改变颜色——尽管它实际上并没有禁用锚点(如果它有 href 值)。Firefox、Chrome 不提供任何支持。当当前文件夹是顶级文件夹时,“上级”链接需要被禁用。“下载”链接仅在至少勾选一个复选框时才启用。
所有浏览器启用/禁用锚点的唯一方法是添加或删除 href 属性。
查看上面的代码,我们有条件地为两个链接添加了 href 属性。使用魔术标签“<% .. %>”,我们甚至可以在 HTML 元素内嵌入 C# 代码。
<a id="upper" <% if (upperEnabled) { %> href='javascript:goUpper("<%= Model %>");' <% } %> style="padding-left: .4em;"><span>Upper</span></a>
在 JavaScript 和服务器 C# 方法之间传递 .NET 字符串列表
服务器资源管理器支持多个文件(文件夹)下载。这意味着您需要先将文件完整路径字符串列表传递给 JavaScript 下载函数,然后客户端函数通过 ajax 将列表传递给 C# 服务器函数。
但是在 JavaScript 中没有 IEnumerable,就像你在 .NET 中使用它一样。有一些相似的东西,但它的实现方式完全不同。在 .NET 中,IEnumerable 仅仅意味着类提供了一个 GetEnumerator() 方法,该方法返回一个 IEnumerator(它本身只包含 Current、MoveNext 和 Reset 方法)。在 JavaScript 中,当您遍历一个项目时,您正在遍历其属性的名称。
您需要做的是将您的数据转换为 JavaScript 可以使用的一种格式。最可能的情况是将它转换为称为 JSON 的东西。将 .NET 数据转换为 JSON 的最简单方法是使用内置库,例如 JavaScriptSerializer。
在 ActionLinks.ascx 中,我们将 ViewData[“CheckedList”](这是一个 .Net 字符串列表)序列化为使用 JavaScriptSerializer 的字符串。
System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); jList = serializer.Serialize(list);
现在我们需要从 JavaScript 下载函数访问“jList”服务器全局变量。
如何在 ASP.net MVC 中从 JavaScript 函数访问服务器端变量
您可以像这样访问 Model、ViewData 或其他变量。
var list = '<%= jList %>'; var model = '<%= Model %>'; var data = '<%= ViewData[“blah”] %>';
以下代码是下载 JavaScript 函数。
function download() { var list = '<%= jList %>'; var path = getApplicationPath() + "Explorer/Download/?jlist=" + list; window.location.href = path; }
我们知道 ASP.net MVC 中的任何路径都将被映射到 Controller 类。上面的代码将被映射到 Explorer 控制器的 Download 方法。我们使用 URL 查询字符串格式为该方法传递参数。您还注意到我们使用设置 window.location.href 来加载视图或部分视图。这将使 JavaScript 函数完全像 Html.ActionLink 一样工作。
3. 使用 JQuery 进行部分页面更新
在服务器资源管理器中,当我们双击一个文件夹时,该文件夹中的子文件夹和文件会弹出到列表中。类似地,当我们勾选或取消勾选复选框时,操作链接也需要更新(将新的视图模型传递给操作链接部分视图)。
$("#listview .t-row").dblclick(function () { var path = getApplicationPath(); var filename = jQuery("input[name=fullPath]", this).val(); $.ajax({ type: "POST", url: path + "Explorer/GetFiles", data: { path: filename }, cache: false, dataType: "html", success: function (data) { $('#listpane').html(data); } }) });
Controller 方法是
public ActionResult GetFiles(string path) { IList<FileModel> files = FileModel.GetFiles(path); ViewData["Parent"] = path; return PartialView("FileList", files); }
客户端双击事件处理程序通过 JQuery .ajax 方法调用 Explorer 控制器中的 GetFiles 方法。GetFiles 返回一个 PartialView action result。当客户端收到结果时,它将更新 listpane div。
以下代码将在勾选或取消勾选复选框时部分更新操作链接。
$(':checkbox').click(function () { var list = new Object; var i = 0; var filename = '<%= ViewData["Parent"] %>'; var path = getApplicationPath(); $("input:checkbox:checked").each(function () { list[i++] = $(this).val(); }); $.ajax({ type: "POST", url: path + "Explorer/LoadActionLinks", data: { path: filename, list: list }, cache: false, dataType: "html", success: function (data) { $('#commands').html(data); } }) }); //No text selection on elements with a class of 'noSelect' $('.noselect').disableTextSelect(); $("#listview .t-row:first").click(); });
Controller 方法是
public ActionResult LoadActionLinks(string path, List<string> list) { ViewData["CheckedList"] = list; return PartialView("ActionLinks", path); }
可能需要提及的一点是,我们不必在 html 中声明事件处理程序。我们使用 JQuery 将匿名事件处理程序绑定到 html 元素。
4. ASP.Net 自定义 Action Result
ASP.Net MVC 的一个好处是创建自定义 action result 的简便性。虽然 MVC 中已经有一个 FileResult,但在服务器资源管理器下载中我们需要做更多的事情。因为我们支持多个文件夹和文件下载,一个想法是将这些选定的文件或文件夹添加到 zip 存档中。如果我们只选择一个文件,并且该文件已经是 zip 文件,则不要进行多余的 zip 操作。
所有这些都可以通过自定义 action result 来完成。
在 Controller 文件夹中添加一个类,并将其命名为 ZipResult。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace ServerExplorer.Controllers
{
public class ZipResult : ActionResult
{
List<string> archives = new List<string>();
public override void ExecuteResult(ControllerContext context)
{
if (archives.Count == 0)
return;
string zipName;
bool zipped = false;
if (archives.Count == 1)
{
if (Path.GetExtension(archives[0]) == ".zip")
zipped = true;
zipName = Path.GetFileNameWithoutExtension(archives[0]) + ".zip";
}
else
zipName = String.Format("archive-{0}.zip",
DateTime.Now.ToString("yyyy-MMM-dd-HHmmss"));
context.HttpContext.Response.Buffer = true;
context.HttpContext.Response.Clear();
context.HttpContext.Response.AddHeader("content-disposition",
"attachment; filename=" + zipName);
context.HttpContext.Response.ContentType = "application/zip";
if (zipped)
context.HttpContext.Response.WriteFile(archives[0]);
else
{
using (Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile())
{
foreach (string path in archives)
{
try
{
FileAttributes attr = System.IO.File.GetAttributes(path);
if ((attr & FileAttributes.Directory) ==
FileAttributes.Directory)
zip.AddDirectory(path,
Path.GetFileNameWithoutExtension(path));
else
zip.AddFile(path, "");
}
catch (Exception)
{
}
}
zip.Save(context.HttpContext.Response.OutputStream);
}
}
}
public void AddFile(string filepath)
{
archives.Add(filepath);
}
}
}
您可以找到许多免费和开源的 Zip 工具。我们在这里使用 Ionic Zip。
以下代码是 Explorer 控制器中的 Download 方法。
public ActionResult Download(string jlist)
{
System.Web.Script.Serialization.JavaScriptSerializer serializer =
new System.Web.Script.Serialization.JavaScriptSerializer();
List<string> list = serializer.Deserialize<List<string>>(jlist);
ZipResult result = new ZipResult();
foreach (string path in list)
{
result.AddFile(FileModel.Decode(path));
}
return result;
}
5. 将 ASP .Net MVC3 部署到 IIS7
首先,ASP .Net MVC3 使用 .Net Framework 4。所以请确保 .Net Framework 4 已安装在部署的目标计算机上。
如果将依赖程序集引用的属性“复制本地”设置为 true,则不必在目标计算机上安装 ASP.net MVC3。
以下列出了 ASP .net MVC3 的依赖程序集。
System.Web.Abstractions
System.Web.Extensions
System.Web.Helpers
System.Web.Mvc
System.Web.Razor
System.Web.Routing
Microsoft.Web.Infrastructure
System.Web.WebPages
System.Web.WebPages.Razor
创建一个使用 .Net Framework 4 的应用程序池
打开 IIS 管理器,右键单击“应用程序池”,选择“添加应用程序池”命令。这将打开“添加应用程序池”对话框,在“.NET Framework 版本”下拉列表中选择“.NET Framework v4.0”。
在目标网站中添加应用程序
右键单击目标网站,选择“添加应用程序”命令。这将打开“添加应用程序”对话框。选择为此应用程序创建的应用程序池。
从 Visual Studio 2010 将 ASP .net MVC3 应用程序部署到 IIS 7
有几种方法可以将 Web 应用程序部署到 IIS 7。但我更喜欢通过 ftp 发布从 VS2010 进行部署。首先,您需要在 IIS 7 中为目标站点启用 ftp 发布。右键单击项目,选择“发布”命令。这将打开“发布 Web”对话框。
选择“FTP”作为发布方法,然后键入目标位置。
重新安装 .Net Framework 4 for IIS7
出于某些原因(主要发生在 IIS 7 在 .Net 4 之前安装的情况下),将 ASP.Net MVC3 Web 应用程序发布到目标网站后,它根本不起作用。当您在浏览器中浏览您的应用程序时,您会收到一个错误,例如“目录浏览未启用”。然后,如果您启用“目录浏览”,您的应用程序仍然无法运行,而是显示浏览器中的目录内容列表。
如果发生这种情况,则意味着 .Net Framework 4.0 未在您的 IIS 7 上正确安装。您需要重新安装它。
打开命令提示符。
转到 Windows\Microsoft.NET\Framework\v4.0.30319 或 Windows\Microsoft.NET\Framework64\v4.0.30319 文件夹。
键入以下命令
aspnet_regiis –i
重新安装后,您的应用程序将按预期工作。
结论
我们已经看到 ASP.NET MVC 可以轻松快速地创建网站。希望本文能为您开始构建自己的 ASP.NET MVC 应用程序提供一些技巧!