.RESXMechanizm lokalizacji dostępny w .NET pozwala nam na stworzenie w łatwy różnej zawartości strony/aplikacji w zależności od kraju bądź kultury, w której użytkownik się znajduję.Edycja zawartości, jak i jej zarządzanie jest dużo łatwiejsze z plikami resx, nawet jeśli nie budujemy strony multi-językowej.
Mechanizm ten jest domyślnie wykorzystywany w CMS DotNetNuke.
W ASP.NET mamy do dyspozycji dwa foldery „App_GlobalResources” i „App_LocalResources.”.
Mechanizm lokalizacja jest zależny od tego, do którego folderu umiesz plik .resx. W tym wpisie właśnie skoncentrujemy się na tych różnicach.
Jak sama nazwa wskazuje Globalne zasoby nadają się doskonalone do zawartości, która będzie się powtarzać na wielu stronach. Serwisy, nad którymi pracowałem zwykle miały tylko globalne zasoby.
Lokalne zasoby są dostępne tylko dla wybranej strony bądź kontrolki ascx. W CMS DotNetNuke lokalne zasoby są powszechne, ponieważ jak na dobry CMS przystało można w nim pisać swoje własne moduły. Moduły te powinny być niezależne od siebie. Nazwy lokalny zasobów jednego modułu nigdy nie będą się kłóciły z lokalnymi zasobami innego modułu.
Teraz omówimy mechanizm działania plików resx.
App_GlobalResources
Utworzyłem plik R3.resx w folderze App_GlobalResources. Zawiera on jeden element o nazwie „A” i wartości „A”.
Poniżej znajduje się kod cały strony ASP.NET, która wykorzystuje ten globalny zasób i nie tylko.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="RESXTest.WebForm1" %>
<%@ Register Src="~/WUC.ascx" TagPrefix="uc" TagName="WUC" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" Text='<%$ Resources:R3, A %>' runat="server"/>
<asp:Label ID="Label2" meta:resourcekey="Label2" runat="server"/>
<uc:WUC runat="server" ID="ucWUC" />
</div>
</form>
</body>
</html>
Użycie globalnego zasobu wymaga użycia C# bloku kodu (Datasource expression) na stronie aspx.
<asp:Label ID="Label1" Text='<%$ Resources:R3, A %>' runat="server"/>
Wszystkie zasoby globalne nie zależnie od nazwy pliku zawarte są w przestrzeni nazw „Resource”.
using System;
namespace RESXTest
{
public partial class WebForm1 : System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e)
{
Response.Write(Resources.R3.A);
}
}
}
Aby odwołać się do danego elementu pliku resx wystarczy po przestrzeni nazw „Resource” napisać nazwę pliku .resx (R3) ,a potem nazwę elementu zasobu (A).
App_LocalResources
W przypadku lokalnych zasobów aplikacji ,aby z nich skorzystać trzeba spełnić parę warunków.
Po pierwsze plik .resx musi nazywać się tak samo, jak strona .aspx bądź kontrolka .ascx włączają w to jej rozszerzenie.
Jak widać na poniższym obrazku lokalny zasób dla strony WebForm1.aspx nazywa się „WebForm.aspx.resx”.
Dla porządku element zasobu warto nazwać tak samo, jak kontrolkę, w której ten element będzie wykorzystany. Nazwa elementu zasobu tak naprawdę będzie teraz aliasem do danej kontrolki i jej właściwości.
Element zasobu oprócz aliasu do kontrolki musi jeszcze zawierać po kropce nazwę właściwości, do której będzie on się odwoływał. W tym wypadku jest to „Text”, ale równie dobrze może to być właściwość „ToolTip” itp.
Dla kontrolki z aliasem Label2 właściwość Text zostanie uzupełniona wartością „B” .
Alias jednak jeszcze nie jest kojarzony z daną kontrolką. Używając tagu „meta:resourcekey” kojarzymy alias z danym elementem.
<asp:Label ID="Label2" meta:resourcekey="Label2" runat="server"/>
Tak jak pisałem wcześniej dla porządku warto nazywać aliasy tak samo jak Id kontrolki.
Analogicznie mechanizm działa dla kontrolek ascx.
Kod kontrolki wygląda podobnie jak poprzednio.
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="WUC.ascx.cs" Inherits="RESXTest.WUC" %>
<asp:Label Id="lblmy" runat="server" meta:resourcekey="lblmy" />
Jak się odwołać do lokalnego zasobu z poziomu kodu w C#.
Aby odwołać się do lokalnego zasobu w kodzie C# używamy metody „GetLocalResourceObject”. Metoda ta przyjmuje jako parametr nazwę danego elementu. Jak widzisz w kodzie nie wskazujemy w żaden sposób na plik .resx więc nawet z poziomu kodu lokalne zasoby są ograniczone do danej kontrolki bądź strony.
<% var s = GetLocalResourceObject("Test");
Response.Write(s.ToString());%>
W metodzie DotNetNuke można podać nazwę lokalnego zasobu, do którego chcemy się odwołać co łamię moim zdaniem filozofię lokalnych zasobów.
DotNetNuke.Services.Localization.Localization.GetString("StringName.Text", LocalResourceFile);