代码改变世界

Asp.NET MVC Widget开发 - ViewEngine

2011-03-02 14:02  Creative dream  阅读(3369)  评论(6编辑  收藏  举报

在Asp.NET开发博客类系统,我们经常都会用到Widget,像在线好友、最近访问好友、最新留言等,关于Asp.NET MVC与Asp.NET视图的差异,这里不再说了,大家可去查一下,接下来我以“我的好友”列表来要介绍在Asp.NET MVC实现这一功能以及结构设计。

  • 开发工具:VS 2010 EN
  • 开发语言:Visual C#
  • ASP.NET MVC 3
  1. Asp.NET MVC Widget - 设计
  2. Asp.NET MVC Widget - Controller控制器
  3. Asp.NET MVC Widget - ViewEngine
  4. Asp.NET MVC Widget - Mobile支持
  5. Asp.NET MVC Widget - Html.Widget扩展方法

关于ViewEngine这篇是Widgets实现的核心,这里需要自定义Asp.NET MVC的视图引擎,也就是让Asp.NET MVC视图引擎可以找到widgets中的文件。

直接访问会出现以下错误,提示找不到显示文件

由错误中也可以看到 Asp.NET MVC默认引擎搜索文件的目录

/Views/Widget/

/Views/Shared/

要寻找到"widgets"中的文件就必须要让视图引擎去"widgets"中搜索文件

如Friends: /widgets/Friends/

添加自定义视图引擎

1. 添加 "WidgetViewEngine.cs",继承自BuildManagerViewEngine

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Widgets
{
public class WidgetViewEngine : BuildManagerViewEngine
{
internal static readonly string ViewStartFileName = "_ViewStart";

public WidgetViewEngine()
:
this(null)
{
}

public WidgetViewEngine(IViewPageActivator viewPageActivator)
:
base(viewPageActivator)
{
AreaViewLocationFormats
= new[] {
"~/Areas/{2}/Views/{1}/{0}.cshtml",
"~/Areas/{2}/Views/Shared/{0}.cshtml"
};
AreaMasterLocationFormats
= new[] {
"~/Areas/{2}/Views/{1}/{0}.cshtml",
"~/Areas/{2}/Views/Shared/{0}.cshtml"
};
AreaPartialViewLocationFormats
= new[] {
"~/Areas/{2}/Views/{1}/{0}.cshtml",
"~/Areas/{2}/Views/Shared/{0}.cshtml"
};

ViewLocationFormats
= new[] {
"~/Views/{1}/{0}.cshtml",
"~/Views/Shared/{0}.cshtml"

};
MasterLocationFormats
= new[] {
"~/Views/{1}/{0}.cshtml",
"~/Views/Shared/{0}.cshtml"
};
PartialViewLocationFormats
= new[] {
"~/{1}s/{0}/Widget.cshtml",
"~/Views/{1}/{0}.cshtml",
"~/Views/Shared/{0}.cshtml"
};

FileExtensions
= new[] {
"cshtml"
};
}

protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
{
return new RazorView(controllerContext, partialPath,
layoutPath:
null, runViewStartPages: false, viewStartFileExtensions: FileExtensions, viewPageActivator: ViewPageActivator);
}

protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
{
var view
= new RazorView(controllerContext, viewPath,
layoutPath: masterPath, runViewStartPages:
true, viewStartFileExtensions: FileExtensions, viewPageActivator: ViewPageActivator);
return view;
}
}
}

2. 添加AppStart_Widgets.cs,修改默认视图引擎

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Widgets;

[assembly: PreApplicationStartMethod(
typeof(AppStart_Widgets), "Start")]

namespace Widgets
{
public class AppStart_Widgets
{
public static void Start()
{
// Clear system default view engines
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(
new WidgetViewEngine());
}
}
}

3. 添加Friend实体及测试数据

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Widgets.Models
{
public class Friend
{
public int Id { get; set; }
public string Name { get; set; }
}

public class FriendsContext
{
public FriendsContext()
{
Friends
= new List<Friend>() {
new Friend{Id=1,Name="zhang san"},
new Friend{Id=2,Name="li si"},
new Friend{Id=3,Name="wang wu"}
};
}

public IEnumerable<Friend> Friends { get; private set; }
}
}

4. 更改widgets/Friends/Widget.cshtml

@model IEnumerable<Widgets.Models.Friend>
@{
Layout = "~/widgets/_Layout.cshtml";
ViewBag.Title = "My friends";
}
<div class="newsletter">
<ul>
@foreach (var item in Model)
{
<li>@item.Name</li>
}
</ul>
</div>

项目结构

其它代码详见源码中。

再次访问,便出现要的结果。

源码下载