YbSoftwareFactory 代碼生成插件【二十五】:Razor視圖中以全局方式調用後臺方法輸出頁面代碼的三種方法

  上一篇介紹了 MVC中實現動態自定義路由 的實現,本篇將介紹Razor視圖中以全局方式調用後臺方法輸出頁面代碼的三種方法。html

  框架最新的升級實現了一個頁面部件功能,其實就是經過後臺方法查詢數據庫內容,把查詢結果的 HTML 代碼呈現到 Razor 視圖中,考慮到靈活性,須要能在任意 Razor 視圖中調用該方法,這樣任意 Razor 頁面都能以統一的方式方便地共享該頁面部件的 HTML 內容,這對於代碼的重用性和可維護性都是很是有必要的。web

  爲實現上述要求,本文介紹以下可供選擇的三種方式。數據庫

  一、擴展靜態類 Helper 方法,返回 HtmlStringapi

  1)可參考以下代碼:框架

public static class ImageHelper
{
  public static HtmlString Image(this HtmlHelper helper, string id, string url, string alternateText)
    {
        return Image(helper, id, url, alternateText, null);
    }

    public static HtmlString Image(this HtmlHelper helper, string id, string url, string alternateText, object htmlAttributes)
    {
        // Instantiate a UrlHelper 
        var urlHelper = new UrlHelper(helper.ViewContext.RequestContext);

        // Create tag builder
        var builder = new TagBuilder("img");

        // Create valid id
        builder.GenerateId(id);

        // Add attributes
        builder.MergeAttribute("src", urlHelper.Content(url));
        builder.MergeAttribute("alt", alternateText);
        builder.MergeAttributes(new RouteValueDictionary(htmlAttributes));

        // Render tag
        var ret = new MvcHtmlString(builder.ToString(TagRenderMode.SelfClosing));

        return ret;
    }
}

  2)此時界面能夠這樣調用:post

@Html.Image("my-id", "~/Content/my-img.png", "Alt Text")

  總結:此方式最簡單,但缺點也很是明顯,由於是靜態類,沒法方便的進行依賴注入以調用其餘實例方法。ui

  二、繼承 WebViewPage<TModel> 實現自定義的 WebViewPage ,在子類中實現返回界面 HTML 字符串的方法。this

  此種方式可參照Abp框架中多語言的本地化實現過程,步驟以下:url

  1)繼承 WebViewPage 類spa

public abstract class AbpWebViewPage<TModel> : WebViewPage<TModel>

  2)實現方法,返回指定 Key 名稱的本地化語言字符串

/// <summary>
/// Gets localized string for given key name and current language.
/// </summary>
/// <param name="name">Key name</param>
/// <returns>
/// Localized string
/// </returns>
protected virtual string L(string name)
{
    return this._localizationSource.GetString(name);
}

  3)在 Web.config 中配置視圖基類

<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="Yb.AbpZero.Web.Views.AbpZeroTemplateWebViewPageBase">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.Optimization" />
<add namespace="Yb.AbpZero.Web" />
<add namespace="Yb.AbpZero.Localization" />
</namespaces>
</pages>
</system.web.webPages.razor>

  4)這樣視圖頁面上就能夠方便的調用 @L("Dashboard") 代碼輸出對應語言的字符串內容

  總結:此種方式須要在指定文件夾下的 Web.config 中配置頁面視圖的基類,在未配置的頁面中沒法進行方法的調用

  三、推薦的最佳方案

  咱們換種方式實現 Helper 方法,經過使用全局 Razor 視圖中的 Helper 代碼去訪問後臺方法並輸出結果

  1)繼承 System.Web.WebPages.HelperPage ,並重寫 Html 屬性

  此處須要注意的是 System.Web.WebPages.HelperPage 的 Html 對象和以下重寫的 Html 對象不是同一個類,爲便於記憶、統一以 MVC Razor 中的關鍵字進行界面調用,咱們此處仍是把屬性名稱定義爲 Html 。

public class HelperPage : System.Web.WebPages.HelperPage
{
    // Workaround - exposes the MVC HtmlHelper instead of the normal helper
    public static new HtmlHelper Html
    {
      get { return ((WebViewPage) WebPageContext.Current.Page).Html; }
    }
}    

  2)把 Helper 方法放到 App_Code 文件夾下的 Razor 視圖中

  咱們已經知道Razor能夠訪問本路徑下其餘 Razor 視圖中定義的 Helper 方法,但如今咱們考慮的是任意路徑下 Razor 視圖可均共享該 Helper 方法。

  首先在 App_Code 文件夾下建立一個 Razor 視圖,該視圖將會被進行動態編譯,經過 Razor 的視圖引擎調用後臺方法輸出界面所需的 HTML 代碼,代碼以下:

@inherits YbRapidSolution.Mvc.HelperPage
@using System.Web.Mvc.Html
@helper Partial(string id)
{
    Html.RenderAction("_Widget", "Home", new { id });
}

  3)咱們在 _Widget 的後臺方法中來訪問數據庫,而後生成頁面部分視圖並返回至界面,代碼以下:

#region CMS部件呈現

/// <summary>
/// CMS部件呈現
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[ChildActionOnly]
public PartialViewResult _Widget(string id)
{
  if (string.IsNullOrEmpty(id))
  {
    return PartialView("E404");
  }

  var widget = _widgetService.GetById(id);
  if (widget == null)
  {
    return PartialView("E404");
  }
  if (string.IsNullOrWhiteSpace(widget.TemplatePath))
  {
    return PartialView("_Widget", widget);
  }
  return PartialView(widget.TemplatePath, widget);
}

#endregion 

  4)這樣就可在任意頁面進行調用以下代碼生成界面所需的 Html 字符串,而字符串的內容則可放到數據庫中,可在須要的時候在後臺進行修改和維護:

@_Widget.Partial("31dbfb04b41e4883bab880ceec2cfef3")

  總結:此種方式無需額外配置便可實現 Helper 方法的全局共享,調用的時候可使用本身定義的標籤,代碼可讀性更強。

相關文章
相關標籤/搜索