Недавно перенёс небольшое 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.