iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 29
2
Software Development

從Asp.net框架角度進入Asp.net MVC原始碼系列 第 29

[Day29] 動手DIY改造 Asp.net MVC- 擴充在擴充,強化WebViewPage製作多國貨幣機制

前言

View頁面(razor,aspx...)都是繼承WebViewPage<TModel>頁面,

今天會帶大家寫一個範例完成透過Route判斷多國錢幣符號.

多國路由設定

Route設定上多一個{culture}區塊.如果使用者沒有輸入預設使用英文(en).

routes.MapRoute(
    name: "Default",
    url: "{culture}/{controller}/{action}",
    defaults: new { controller = "Home", action = "Index", culture = "en" });

取得貨幣符號

建立一個介面ICurrency裡面有個方法可以取得傳入國家貨幣符號.

CurrencyProvider類別透過Routes.Values["culture"]取得使用者傳遞語系國家.

透過此參數可以知道使用者想要使用哪個國家貨幣.

public interface ICurrency
{
    string GetCurrencySymbol();
}

public class CurrencyProvider : ICurrency
{
    public string GetCurrencySymbol()
    {
        HttpContextBase contextWrapper = new HttpContextWrapper(HttpContext.Current);

        string culture = RouteTable.Routes.GetRouteData(contextWrapper)?.Values["culture"] as string;

        return GetSymbol(culture);
    }

    private string GetSymbol(string culture)
    {
        switch (culture)
        {
            case "en":
                return "$";
            case "eu":
                return "£";
            default:
                return "$";
        }
    }
}

擴充 WebViewPage

Autofac多註冊一個

builder.RegisterType<CurrencyProvider>().As<ICurrency>();
DependencyResolver.SetResolver(new CustomerDependencyResolver(builder.Build()));

最後在建立一個CountryViewPage<TModel>抽象類別繼承於WebViewPage<TModel>.

在此類別中建立一個ICurrency屬性,並在建構子中透過DependencyResolver.Current.GetService給值

因為這間已經替換成Autofac解析器,所以會吃Autofac註冊的類別.

public abstract class CountryViewPage<TModel> : WebViewPage<TModel>
{
    public CountryViewPage()
    {
        Currency = DependencyResolver.Current.GetService<ICurrency>();
    }
    public ICurrency Currency { get;  }
}

RazorView使用擴充後WebViewPage

View上使用新WebViewPage<TModel>只需要在最上面加@inherits CountryViewPage<object>.
我們就可以透過@呼叫Currency物件.

@inherits CountryViewPage<object>

@{
    ViewBag.Title = "About";
}

<h2>@ViewBag.Title.</h2>
<h3>@ViewBag.Message @Currency.GetCurrencySymbol()</h3>

<p>Use this area to provide additional information.</p>

如果每個頁面都需要使用新的WebViewPage<TModel>可以透過web.config新增加一個<pages pageBaseType="CountryViewPage">Razor產生的C#程式碼繼承於此類別

<system.web.webPages.razor>
    <pages pageBaseType="CountryViewPage">
        <namespaces>
          <add namespace="System.Web.Mvc" />
          <add namespace="System.Web.Mvc.Ajax" />
          <add namespace="System.Web.Mvc.Html" />
          <add namespace="System.Web.Routing" />
        </namespaces>
    </pages>
</system.web.webPages.razor>

小結:

其實我們也可以繼承WebViewPage<TModel>來擴充View多變性

這邊有一個題目提供讀者來完成透過上面概念完成多國語系,這裡提供一條方法完成

寫一個string transfer(string key)透過Resource檔案來完成;

Github範例程式原始碼 CustomerWebViewPage分支上


上一篇
[Day28] 動手DIY改造 Asp.net MVC- 建立自己ActionInvoker和Model綁定機制
下一篇
[Day30] 鐵人賽完賽&總結
系列文
從Asp.net框架角度進入Asp.net MVC原始碼30

尚未有邦友留言

立即登入留言