O exemplo abaixo é um código que compila sem problema algum, porém, durante a sua execução lança a exceção System.ArrayTypeMismatchException na linha em que o inteiro 1 é atribuído a posição 0 do array b.

using System;

namespace CompilerTypeCheck
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                string[] a = new string[3];
                object[] b = a;
                b[0] = 1;
            }
            catch (System.ArrayTypeMismatchException atmex)
            {
                System.Console.WriteLine("An error occured while executing this program. Error details: " + atmex.StackTrace);
            }

            System.Console.WriteLine("Press  to exit…”);
            System.Console.ReadLine();
        }
    }
}

1 Objetivo

O propósito deste artigo é apresentar os procedimentos para gerar uma documentação de código a partir dos comentários XML.

2 Requerimentos de sistema

A solução proposta foi desenvolvida utilizando-se os softwares abaixo:
• Windows Server 2003 R2 Enterprise Edition SP2.
• .NET Framework 2.0.
• Visual Studio 2005 Team Suite.
• HTML Help WorkShop
• SandCastle 2.3.8000.26.
• SandCastle Help File Builder 1.6.0.2.

3 Acrônimos

Acrônimo Descrição
VO Value Object
CHM Compiled HTML Help

4 Procedimentos

4.1 Configuração do Visual Studio.NET

A primeira etapa do procedimento é configurar os seus projetos no VS.NET para gerarem o arquivo XML de documentação quando mesmo for compilado. Para obter este resultado, siga para as propriedades do projeto e selecione a opção XML documentation file na seção Build, como mostra a ilustração abaixo:

http://www.orchestratechnology.com.br/blog/vsnet2005/ConfiguringXMLGeneration.JPG

4.2 Comentando o seu código

A utilização de comentários no código é muito importante, talvez não para você mesmo naquele momento da confecção do código, mas quando tiver de realizar alguma manutenção corretiva ou preventiva depois de alguns meses ou quando outra pessoa suportará seu código. Portanto, não confie na sua boa memória, comente seu código. Abaixo segue um exemplo de uma classe (VO) comentada:

using System;

namespace OrchestraTechnology.SandCastle.VO.Security
{
    /// <summary>
    /// Classe para transferência dos dados de um usuário.
    /// </summary>
    [System.Serializable]
    public class User
    {
        #region Attributes
        private string firstName;
        private string lastName;
        private string email;
        #endregion

        #region Properties
        /// <summary>
        /// Nome do usuário
        /// </summary>
        public string FirstName
        {
            get { return firstName; }
            set { firstName = value; }
        }

        /// <summary>
        /// Sobrenome do usuário
        /// </summary>
        public string LastName
        {
            get { return lastName; }
            set { lastName = value; }
        }

        /// <summary>
        /// Endereço de e-mail do usuário
        /// </summary>
        public string Email
        {
            get { return email; }
            set { email = value; }
        }
        #endregion

        #region Constructors
        /// <summary>
        /// Construtor padrão.
        /// </summary>
        /// <example>
        /// <code>
        /// OrchestraTechnology.SandCastle.VO.Security.User user = new OrchestraTechnology.SandCastle.VO.Security.User();
        /// </code>
        /// </example>
        public User()
        {
        }

        /// <summary>
        /// Construtor alternativo.
        /// </summary>
        /// <param name="firtName">Nome do usuário</param>
        /// <param name="lastName">Sobrenome do usuário</param>
        /// <param name="email">Endereço de e-mail do usuário</param>
        /// <example>
        /// <code>
        /// OrchestraTechnology.SandCastle.VO.Security.User user = new OrchestraTechnology.SandCastle.VO.Security.User("Evandro", "Paula", "evandro@orchestratechnology.com.br");
        /// </code>
        /// </example>
        public User(string firtName, string lastName, string email)
        {
            this.FirstName = firstName;
            this.LastName = lastName;
            this.Email = email;
        }
        #endregion
    }
}

4.3 Inspecionando o arquivo XML gerado

Quando compilar o projeto uma arquivo XML será gerado de acordo com as configurações (diretório e nome do arquivo) realizadas no passo 5.2.

<xml version="1.0"?>
<xml version="1.0"?>
<doc>
    <assembly>
        <name>OrchestraTechnology.SandCastle.VO</name>
    </assembly>
    <members>
        <member name="T:OrchestraTechnology.SandCastle.VO.Security.User">
            <summary>
            Classe para transferência dos dados de um usuário.
            </summary>
        </member>
        <member name="M:OrchestraTechnology.SandCastle.VO.Security.User.#ctor">
            <summary>
            Construtor padrão.
            </summary>
            <example>
            <code>
            OrchestraTechnology.SandCastle.VO.Security.User user = new OrchestraTechnology.SandCastle.VO.Security.User();
            </code>
            </example>
        </member>
        <member name="M:OrchestraTechnology.SandCastle.VO.Security.User.#ctor(System.String,System.String,System.String)">
            <summary>
            Construtor alternativo.
            </summary>
            <param name="firtName">Nome do usuário</param>
            <param name="lastName">Sobrenome do usuário</param>
            <param name="email">Endereço de e-mail do usuário</param>
            <example>
            <code>
            OrchestraTechnology.SandCastle.VO.Security.User user = new OrchestraTechnology.SandCastle.VO.Security.User("Evandro", "Paula", "evandro@orchestratechnology.com.br");
            </code>
            </example>
        </member>
        <member name="P:OrchestraTechnology.SandCastle.VO.Security.User.FirstName">
            <summary>
            Nome do usuário
            </summary>
        </member>
        <member name="P:OrchestraTechnology.SandCastle.VO.Security.User.LastName">
            <summary>
            Sobrenome do usuário
            </summary>
        </member>
        <member name="P:OrchestraTechnology.SandCastle.VO.Security.User.Email">
            <summary>
            Endereço de e-mail do usuário
            </summary>
        </member>
    </members>
</doc>

Note que nós são criados para manter as referências do assembly e seus membros, bem como como os comentários que foram inseridos.

4.4 SandCastle Help File Builder

A etapa final compreende na criação de um projeto no SandCastle Help File Builder referenciando os arquivos XML que são gerados durante a compilação e realizar o Build do projeto.

http://www.orchestratechnology.com.br/blog/vsnet2005/ConfiguringSandCastleBuilder.JPG

Um arquivo de ajuda com a extensão CHM, veja a ilustração abaixo:

http://www.orchestratechnology.com.br/blog/vsnet2005/CHMFile.JPG

5 Softwares

Os softwares utilizados neste artigo podem ser obtidos nos endereços abaixo:

HTML Help WorkShop
http://www.microsoft.com/downloads/details.aspx?FamilyID=00535334-c8a6-452f-9aa0-d597d16580cc&displaylang=en

SandCastle 2.3.8000.26
http://www.microsoft.com/Downloads/details.aspx?FamilyID=e82ea71d-da89-42ee-a715-696e3a4873b2&displaylang=en

SandCastle Help File Builder 1.6.0.2
http://www.codeplex.com/SHFB/Release/ProjectReleases.aspx?ReleaseId=8261

6 Código-fonte

É possível baixar o código-fonte utilizado para a elaboração deste artigo no endereço http://www.orchestratechnology.com.br/blog/vsnet2005/SandCastle_20080117_1712.zip.

Ward Cunningham.
http://www.aboutus.org/Ward_Cunningham

1 Objetivo

O propósito deste artigo é apresentar uma proposta de solução para que aplicações web suportem outras línguas, tais como: espanhol, inglês, etc. Também é objetivo deste documento guiar o processo de implementação da globalização, inclusive o processo de tradução.

2 Requerimentos de sistema

A solução proposta foi desenvolvida utilizando-se os softwares abaixo:
• .NET Framework 2.0.
• Visual Studio 2005 Team Suite.
• Microsoft Excel 2007.

3 Arquitetura da solução

3.1 Visão geral

A implementação da globalização será realizada utilizando-se arquivos de recursos locais (.resx) para cada uma das páginas. Desta forma, o trabalho em equipe pode ser facilitado, assim como o isolamento de possíveis bugs.
Na figura abaixo podemos identificar a utilização de arquivos de recursos locais para as páginas Default.aspx e Language.aspx nos idiomas português e inglês.
Os arquivos devem se nomeados utilizando o formato .aspx..resx. Note que os arquivos Default.aspx.resx e Language.aspx.resx não seguem este formato. Tais arquivos devem possuir o texto do idioma padrão da aplicação, pois toda vez que não for possível encontrar um arquivo de recurso local para o idioma preferido do usuário, estes serão utilizados.

ResxFiles - ResxFiles

O idioma a ser utilizado será obtido a partir das configurações do navegador.

BrowserLanguagePreferences - BrowserLanguagePreferences

Para obter tal resultado, devemos incluir a configuração destacada abaixo no web.config da aplicação:

<xml version="1.0"?>
<configuration>
	<appSettings/>
	<connectionStrings/>
	<system.web>
		<compilation debug="true"/>
		<authentication mode="Windows"/>
		<globalization culture="auto" uiCulture="auto"/>
	</system.web>
<configuration>

Em alternativa a uma configuração incorreta do browser ou a ausência de direitos para realizar tal configuração, as páginas deverão permitir que o usuário escolha o idioma preferido para visualizar as páginas. Tal escolha deverá ser gravada em um cookie, lida nas próximas visitas as páginas e deverá ter prioridade sobre as configurações do navegador.

O cookie pode ser gravado utilizando-se o código exemplo abaixo:

System.Web.HttpCookie cookie =
	new System.Web.HttpCookie("LanguagePreference", culture);
cookie.Domain="orchestratechnology.com.br";
cookie.Expires=System.DateTime.Now.AddDays(30);
this.Response.Cookies.Add(cookie);

A leitura do cookie e alteração do idioma corrente deverá ser realizada no evento Application_BeginRequest no arquivo Global.asax. Veja o exemplo abaixo:

void Application_BeginRequest(object sender, EventArgs e)
{
    System.Web.HttpCookie cookie =
	this.Request.Cookies["LanguagePreference"];
    if (cookie != null)
    {
        System.Threading.Thread.CurrentThread.CurrentUICulture =
	new System.Globalization.CultureInfo(cookie.Value, true);
    }
}

4 Procedimentos

4.1 Configuração para o idioma português

O primeiro passo para a implementação da globalização é criar a pasta App_LocalResources no projeto da aplicação web. Siga os passos:

• Clique com o botão direito do mouse no projeto web e escolha a opção “New Folder”. Em seguida, renomeie-a para App_LocalResources.

ProjectViewCreatingNewFolder - ProjectViewCreatingNewFolder

• Clique com o botão direito na pasta App_LocalResources e escolha a opção “Add New Item…”.

AppLocalResourcesFolderAddNewItem - AppLocalResourcesFolderAddNewItem

• Selecione o template “Resource File” e defina um nome para o arquivo de acordo com o formato .aspx.resx.

AddingDefault.aspx.resx - AddingDefault.aspx.resx

• Preencha o arquivo com os textos que deverão ser traduzidos. A coluna Name deverá ser preenchida de acordo com o formato .. Veja o exemplo abaixo:

FillingUpDefault.aspx.resx - FillingUpDefault.aspx.resx

• Edite a página com os atributos meta:resourcekey.


<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" meta:resourcekey="Page" %>
<!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:LinkButton ID="lkbChangeLanguage" runat="server" OnClick="lkbChangeLanguage_Click" meta:resourcekey="lkbChangeLanguage"></asp:LinkButton>
        <br /><br />
        <asp:Label id="lblName" runat="server" meta:resourcekey="lblName"></asp:Label>
        <asp:TextBox id="txtName" meta:resourcekey="txtName" runat="server"></asp:TextBox>
        <br />
        <asp:Label id="lblSpecialty" runat="server" meta:resourcekey="lblSpecialty"></asp:Label>
        <asp:DropDownList id="ddlSpecialty" runat="server" meta:resourcekey="ddlSpecialty">
            <asp:ListItem meta:resourcekey="ListItem1"/>
            <asp:ListItem meta:resourcekey="ListItem2"/>
            <asp:ListItem meta:resourcekey="ListItem3"/>
            <asp:ListItem meta:resourcekey="ListItem4"/>
        </asp:DropDownList>
        <br />
        <asp:Label id="lblEmail" runat="server" meta:resourcekey="lblEmail"></asp:Label>
        <asp:TextBox id="txtEmail" runat="server" meta:resourcekey="txtEmail"></asp:TextBox>
        <br /><br />
        <asp:Button ID="btnInsert" runat="server" meta:resourcekey="btnInsert" />
    </div>
    </form>
</body>
</html>


4.2 Processo de tradução

Os passos descritos nesta seção foram desenhados para facilitar a interação entre o tradutor e o desenvolvedor.
Os exemplos contemplam apenas a tradução para o idioma inglês, pois para os demais o processo é o mesmo.

• Copie o arquivo Default.aspx.resx e cole na pastas App_LocalResources. Em seguida, altere o nome do novo arquivo para Default.aspx.en-us.resx.
• Selecione todos os textos do arquivo e cole em uma planilha Excel.

ResourceDataInExcel2007 - ResourceDataInExcel2007

• Trave todas as células da coluna A e destrave as da coluna B para que o tradutor não altere o ID.Property dos controles acidentalmente. Para isso, clique selecione as células da coluna, clique com o botão direito sobre a seleção e escolha Format Cells….

FormattingCells - FormattingCells

• Trave ou destrave as células selecionando o checkbox Locked.

LockingCells - LockingCells

• Proteja a planilha, clicando na aba Review e no botão Protect Sheet. Depois, informe uma senha e selecione os checkboxes de acordo com a figura abaixo:

ProtectingSheet - ProtectingSheet

• Envie a planilha para o tradutor.
• Quando a tradução estiver completa, exclua as linhas do arquivo de Default.aspx.en-us.resx e cole as linhas da planilha Excel.
• Repita os passos descritos acima para os demais idiomas.

5 Dica

Para facilitar a geração do arquivo de resource (.resx) para as páginas que já existem, é possível, a partir do modo design de visualização da página, utilizar a opção Generate Local Resource no menu Tools. Contudo, após a geração do arquivo será necessários normalizar os nomes dos controles.

Tip - Tip

6 Código-fonte

É possível baixar o código-fonte utilizado para a elaboração deste artigo no endereço http://www.orchestratechnology.com.br/blog/aspnet20/Globalization_20071109.zip.

« Página Anterior -