ASP.NET MVC中加載WebForms用戶控件(.ascx)


問題背景

博客園博客中的日歷用的是ASP.NET WebForms的日歷控件(System.Web.UI.WebControls.Calendar),它會為“上一月”、“下一月”的鏈接生成"__doPostBack()"的js調用,如下圖:

目前發現它會帶來兩個問題:

1. 不支持IE10;

2. 某些電腦不允許執行__doPostBack。

問題提煉

前提:

  1. 我們想以最低的成本解決這個問題,也就是對當前代碼盡可能少的改動。所以要盡可能重用現有的日歷控件代碼。
  2. 日歷改為Ajax加載,點擊“上一月”、“下一月”時Ajax更新日歷內容。
  3. 用ASP.NET MVC處理Ajax請求。

要解決的問題:

如何在ASP.NET MVC Controller中加載包含WebForms日歷控件的用戶控件(.ascx),並得到其輸出的字符串,然后將__doPostBack的代碼替換為ajax調用代碼。

核心問題:

如何在ASP.NET MVC Controller中得到用戶控件(.ascx)輸出的字符串。

解決方法

先看代碼

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

代碼很簡單,但得到這個代碼花了今天一上午時間。

代碼說明:

  • 必須要new Page(),只有Page才能LoadControl。
  • 必須要new HtmlForm(),因為日歷控件必要要放在<form runat="server">之間。
  • 關鍵功臣是HttpContext.Current.Server.Execute,動態加載控件並輸出字符串全靠它。這個功臣是在這篇文章中找到的(感謝Sam Mueller)。之前我用過的方法(繼續不走尋常路:ASP.NET MVC中使用Web Forms用戶控件)不僅麻煩,而且在這個場景下會有問題。

代碼運行結果:

完整代碼下載:

http://files.cnblogs.com/dudu/CNBlogsDemoMvcAscx.rar 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM