代码改变世界

ASP.NET MVC 中使用 IView.Render 来呈现 WebFormView 、RazorView 中的内容

2012-04-11 11:33  音乐让我说  阅读(1050)  评论(0编辑  收藏  举报

直接贴代码了:

        public ActionResult GetWord(int? viewType)
        {
            TextWriter writer = new StringWriter();

            int viewTypeId = viewType.HasValue ? viewType.Value : 1;

            IView viewInstance;
            switch (viewTypeId)
            {
                case 1:
                    viewInstance = new WebFormView(ControllerContext, "~/Views/Home/UserNamePartial.ascx");
                    break;
                case 2:
                    viewInstance = new RazorView(ControllerContext, "~/Views/Home/UserNamePartial.cshtml", null, false, null);
                    break;
                default:
                    return new EmptyResult();
            }

            ViewData["UserName"] = "Bruce";
            var viewContext = new ViewContext(this.ControllerContext, viewInstance, ViewData, TempData, writer);
            viewInstance.Render(viewContext, writer);
            string resultHtml = writer.ToString(); // 这里就已经得到了模板引擎呈现出的 Html 代码了
            return Content(resultHtml, "text/html", Encoding.UTF8);
        }

 

UserNamePartial.ascx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<dynamic>" %>

<h1>这里是 WebForm 视图模板</h1>
<br />
你的姓名叫:<%= ViewData["UserName"] %>

 

UserNamePartial.cshtml

<h1>这里是 Razor 视图模板</h1>
<br />
你的姓名叫:@ViewData["UserName"]

 

效果图:

 

ASP.NET MVC 中最大程度地共用 ASP.NET WebForm 中的控件,方式如下:

 

假如有一个日历控件:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="CNBlogsCalendar.ascx.cs" Inherits="CNBlogs.Demo.MvcAscx.Controls.CNBlogsCalendar" %>
<asp:Calendar id="entryCal" runat="server" SelectionMode="None" CellPadding="0" CellSpacing="0" CssClass="Cal" DayNameFormat="Full">
    <TodayDayStyle CssClass="CalTodayDay"></TodayDayStyle>
    <SelectorStyle CssClass="CalSelector"></SelectorStyle>
    <NextPrevStyle CssClass="CalNextPrev"></NextPrevStyle>
    <DayHeaderStyle CssClass="CalDayHeader"></DayHeaderStyle>
    <SelectedDayStyle CssClass="CalSelectedDay"></SelectedDayStyle>
    <TitleStyle CssClass="CalTitle"></TitleStyle>
    <WeekendDayStyle CssClass="CalWeekendDay"></WeekendDayStyle>
    <OtherMonthDayStyle CssClass="CalOtherMonthDay"></OtherMonthDayStyle>
</asp:Calendar>


 

ASP.NET MVC 中这样使用:

    public class HomeController : Controller
    {
        public ActionResult Calendar()
        {
            var page = new Page();
            var form = new HtmlForm();
            var calendar = page.LoadControl("~/Controls/Calendar.ascx");
            form.Controls.Add(calendar);
            page.Controls.Add(form);
            var sw = new StringWriter();
            System.Web.HttpContext.Current.Server.Execute(page, sw, true);
            return Content(sw.ToString());
        }
    }

 

 另外一种 RenderView 的方式(推荐):

/// <summary>
/// 立即呈现视图,返回解析后的字符串
/// </summary>
/// <param name="controller">控制器</param>
/// <param name="viewName">视图的名称</param>
/// <param name="model">模型</param>
/// <param name="master">母版页</param>
/// <returns>解析后的字符串</returns>
public static string RenderView(this ControllerBase controller, string viewName, object model = null, string master = null)
{
    ViewDataDictionary viewData = new ViewDataDictionary();
    foreach (string str in controller.ViewData.Keys)
    {
        viewData.Add(str, controller.ViewData[str]);
    }
    viewData.Model = model;
    using (StringWriter writer = new StringWriter())
    {
        ViewEngineResult result = ViewEngines.Engines.FindView(controller.ControllerContext, viewName, master);
        if (result.View == null) 
            throw new InvalidOperationException("The view '" + viewName + "' or its master was not found or no view engine supports the searched locations. The following locations were searched: " + string.Join("\n", result.SearchedLocations));
        ViewContext viewContext = new ViewContext(controller.ControllerContext, result.View, viewData, controller.TempData, writer);
        result.View.Render(viewContext, writer);
        return writer.GetStringBuilder().ToString();
    }
}

 

 

 

谢谢浏览!