我想使用 ASP.NET MVC 构建一个具有“单页界面”的 Web 应用程序。
我已经搜索了这是否至少是可能的,我认为答案是:不是通过简单的方式(阅读http://msdn.microsoft.com/en-us/magazine/cc507641.aspx#S2 second-last paragraph;那篇文章不过是从 2008 年 5 月开始的)。
我发现了其他通过使用 jQuery 进行编码/黑客攻击来实现这一点的示例。但是,如果可能的话,我正在寻找一个干净的解决方案,使用标准的 .NET 方法。
当您创建一个新的“MVC Web 应用程序”时,我想要的是完全相同的功能。但是,我想要链接到“ # Home/About”的链接,而不是重新加载整个页面的“/Home/About”链接,它只通过 AJAX 加载新部分。
使用 Html.RenderPartial 调用模板(部分视图)的标准方法正是我想要的,然后才通过 AJAX 请求加载它们。
当然,可能由于某种原因,我不能使用母版页呈现的这些模板(也许它总是希望在某个上下文中从某个地方或某个地方调用)。但是,对于如何构建模板页面并从母版页面获取它们,也许还有另一种干净的解决方案。
谁有一个很好的解决方案来实现这样的事情,单页界面?
PS:我正在使用 C# 安装 MVC 1.0 的 Visual Web Developer 2008 Express Edition 进行开发
[编辑] 下面我读到使用模板是可能的,而且 jQuery 看起来确实是不可避免的,所以我对其进行了测试。以下代码将 Html.ActionLink 创建的常规链接转换为锚链接(带 #)以包含历史记录,然后通过 AJAX 获取页面并仅注入我感兴趣的 html 部分(即 div 中的部分页面#部分视图):
$("a").each(function() {
$(this).click(function() {
$("div#partialView").load($(this).attr("href") + " div#partialView");
location.hash = $(this).attr("href");
return false;
});
});
这些链接还允许优雅的降级。
但是我现在剩下的仍然是获取整个页面而不是仅获取部分页面。改变控制器没有帮助。它仍然为我提供了整个页面的 html,以及所有这些语句:
public ActionResult About()
{
return View();
return View("About");
return PartialView();
return PartialView("About");
}
我怎样才能只返回我感兴趣的部分的内容(即 Home/About.aspx 的内容)?我想要的是使用 AJAX 发布一个值(例如“requesttype=ajax”),以便我的控制器知道该页面是通过 AJAX 获取的,并且只返回部分页面;否则它将返回整个页面(即当您访问/Home/About 而不是#Home/About 时)。
更改 Global.asax.cs 是否为 AJAX 调用创建一个新的路由模式是一个好习惯,它只会返回部分页面?(我还没有研究这么多。)
[edit2]
Robert Koritnik 是对的:我还需要一个 About.ascx 页面 (UserControl),其中只有该页面的小 HTML 内容。About.aspx 的第一行与母版页链接,MasterPageFile="~/..../Site.master"
从而导致所有 HTML 都被打印出来。
但是为了能够在我的控制器中执行以下操作:
public ActionResult About()
{
return Request.IsAjaxRequest() ? (ActionResult)PartialView() : View();
}
我需要更改找到PartialView
(.ascx 文件) 和View
(.aspx) 文件的方式,否则这两种方法将返回相同的页面 ( About.aspx
,最终导致无限循环)。将以下内容放入 后Global.asax.cs
,将返回正确的页面PartialView()
和View()
:
protected void Application_Start()
{
foreach (WebFormViewEngine engine in ViewEngines.Engines.Where(c => c is WebFormViewEngine))
{
/* Normal search order:
new string[] { "~/Views/{1}/{0}.aspx",
"~/Views/{1}/{0}.ascx",
"~/Views/Shared/{0}.aspx"
"~/Views/Shared/{0}.ascx"
};
*/
// PartialViews match with .ascx files
engine.PartialViewLocationFormats = new string[] { "~/Views/{1}/{0}.ascx", "~/Views/Shared/{0}.ascx" };
// Views match with .aspx files
engine.ViewLocationFormats = new string[] { "~/Views/{1}/{0}.aspx", "~/Views/Shared/{0}.aspx" };
}
RegisterRoutes(RouteTable.Routes);
}