Недавно перенёс небольшое ASP-приложение c .NET на Mono. Столкнулся с практически полным отсутствием поддержки русского языка при настройках по умолчанию. Использовалась связка Debian lenny (netinst) + Apache2 + mono-apache-server2.
Решение проблем:
На первом же тесте возникла проблема потери русских букв в теле ASPX.
Например такой файл:
В броузере отображался так:

Проблема была решена установкой свежей версии mono из lenny-backports.
В результате получил читаемый текст:

В связке IIS + .NET процесс автоматически переключает свою локаль в зависимости от настроек броузера делающего запрос. Mono же игнорировал языковые параметры запроса и работал постоянно в английской локали.
Пришлось самостоятельно сделать HTTP-модуль переключающий языковые установки треда в зависимости от параметров передаваемых в запросе броузера.
Код модуля:
И прописал его в web.config в разделе <system.web>:
Переносимое приложение представляет собой текстовый парсер подготовки материалов для win-приложений. Приложения старые и могут работать только с CP-1251. Mono по умолчанию такой кодировки не знает.
И такой код
выбрасывает исключение.
Дополнительные кодировки находятся в отдельной библиотеке. Ставятся следующей командой:
В результате я получил ASP-приложение корректно работающее с русским языком на основе Mono. Внутри приложения никаких изменений не вносил. Приложение использует как собственные так и уже скомпилированные внешние библиотеки, с ними тоже никаких проблем не возникло. Считаю что переход прошёл легко и в будущем собираюсь дальше использовать Mono.
Решение проблем:
Первая проблема: не отображается русский текст в теле 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>
В броузере отображался так:

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

Вторая проблема: переключение языка приложения в зависимости от настроек языка по умолчанию в броузере
В связке 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.
