Pull to refresh

Перенос ASP.NET приложения на Mono. Поддержка русского языка

Reading time 3 min
Views 3.6K
Недавно перенёс небольшое ASP-приложение c .NET на Mono. Столкнулся с практически полным отсутствием поддержки русского языка при настройках по умолчанию. Использовалась связка Debian lenny (netinst) + Apache2 + mono-apache-server2.

Решение проблем:

Первая проблема: не отображается русский текст в теле ASPX-файлов

На первом же тесте возникла проблема потери русских букв в теле ASPX.
Например такой файл:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Test.aspx.cs" Inherits="Test" %>
<!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>Test</title>
</head>
<body>
  Тест русский.
</body>
</html>


В броузере отображался так:
image

Проблема была решена установкой свежей версии mono из lenny-backports.
aptitude -t lenny-backports install mono-apache-server libapache2-mod-mono


В результате получил читаемый текст:
image

Вторая проблема: переключение языка приложения в зависимости от настроек языка по умолчанию в броузере

В связке IIS + .NET процесс автоматически переключает свою локаль в зависимости от настроек броузера делающего запрос. Mono же игнорировал языковые параметры запроса и работал постоянно в английской локали.

Пришлось самостоятельно сделать HTTP-модуль переключающий языковые установки треда в зависимости от параметров передаваемых в запросе броузера.

Код модуля:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading;
using System.Web;

// Class for set interface language from browser language setting.
public class LangHTTPModule : IHttpModule
{
    public void Dispose() { }

    public void Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(context_BeginRequest);
    }

    // Set interface language.
    private void context_BeginRequest(object sender, EventArgs e)
    {
        HttpContext context = ((HttpApplication)sender).Context;
        HttpRequest req = context.Request;
        string reqLang = req.UserLanguages[0];

        switch (reqLang.ToLower())
        {
            case "ru": // Russian.
                reqLang = "ru-RU";
            break;
            case "ru-ru": // Russian.
                reqLang = "ru-RU";
            break;
            default: // Unknow value - set english (US) language.
                reqLang = "en-US";
            break;
        }

        Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(reqLang);
    }
}


И прописал его в web.config в разделе <system.web>:
<httpModules>
  <add name="LangHTTPModule" type="LangHTTPModule"/>
</httpModules>


Третья проблема: использование не юникодных кодировок

Переносимое приложение представляет собой текстовый парсер подготовки материалов для win-приложений. Приложения старые и могут работать только с CP-1251. Mono по умолчанию такой кодировки не знает.
И такой код
Encoding enc = Encoding.GetEncoding("Windows-1251");
выбрасывает исключение.

Дополнительные кодировки находятся в отдельной библиотеке. Ставятся следующей командой:
aptitude -t lenny-backports install libmono-i18n2.0-cil


Итоги

В результате я получил ASP-приложение корректно работающее с русским языком на основе Mono. Внутри приложения никаких изменений не вносил. Приложение использует как собственные так и уже скомпилированные внешние библиотеки, с ними тоже никаких проблем не возникло. Считаю что переход прошёл легко и в будущем собираюсь дальше использовать Mono.

Tags:
Hubs:
+24
Comments 11
Comments Comments 11

Articles