none
asp:TextBox не хочет сохранять и отображать альтернативные символы RRS feed

  • Вопрос

  • Есть проект где нужно хранить тексты на множестве языков а конкретно TextBox не хочет сохранять символ "æ" и сохраняет и отображает как знак вопроса. Как заставить его работать с этим символом?
    О сколько нам открытий чудных, готовит просвещения дух
    4 сентября 2011 г. 14:01

Ответы

  • >  изменить collation для базы или поля  
     
    create table test (txt nvarchar(100))
    exec sys.sp_tablecollations 'test' -- collation: SQL_Latin1_General_CP1_CI_AS
    -- меняем collation для txt 
    ALTER TABLE test ALTER COLUMN txt nvarchar(100)  COLLATE Cyrillic_General_CI_AS
    -- добавить 'æ'
    insert into test (txt) values (N'æ')
    select * from test -- получим 'æ'
    
    • Изменено Malobukv 5 сентября 2011 г. 12:01
    • Помечено в качестве ответа Marchellо 5 сентября 2011 г. 12:23
    5 сентября 2011 г. 11:57
  • За 18 лет работы в IT таких ошибок я ещё не делал :) видимо из-за того что юникод раньше не особо использовал - небыло необходимости :)

    Было:

     

    BEGIN
    
    SET @FinalSQL = 'UPDATE Articles SET [ArticlesTextOS]=''' + RTRIM(LTRIM(@Value)) + ''',[ArticlesTitleOS]=''' + RTRIM(LTRIM(@ArticlesTitle)) + ''' WHERE [ArticlesID]=' + STR(@SearchID)
    
    END 
    

     

    Стало:

    BEGIN SET @FinalSQL = 'UPDATE Articles SET [ArticlesTextOS]=N''' + RTRIM(LTRIM(@Value)) + ''',[ArticlesTitleOS]=N''' + RTRIM(LTRIM(@ArticlesTitle)) + ''' WHERE [ArticlesID]=' + STR(@SearchID) END 
    

    Найдите разницу :)

    Все остальные настройки и в приложении и в базе были великолепны - теперь всё сохраняется, помечаю Ваш ответ как правильный ибо мой глаз приметил эту чёртову букву в Вашем тексте :) СПАСИБО!


    О сколько нам открытий чудных, готовит просвещения дух
    5 сентября 2011 г. 12:27

Все ответы

  • в web.config в globalization что указано?
    см. http://msdn.microsoft.com/en-us/library/hy4kkhe0(v=VS.100).aspx


    • Изменено Malobukv 4 сентября 2011 г. 14:14
    4 сентября 2011 г. 14:14
  • Когда указываю UTF-8 сайт превращается в белиберду но даже при этом он не хочет отправить "'æ" в базу корректно. Когда указываю 1251 сайт отображается верно но результат отправки некорректный. Вношу в поле базы символ через эксплорер самого MS SQL 2008 символ сохраняется как положено.

    О сколько нам открытий чудных, готовит просвещения дух
    4 сентября 2011 г. 16:07
  • > при этом он не хочет отправить "'æ" в базу корректно

    в базе collation какой?

    exec sys.sp_tablecollations 'table'
    

    4 сентября 2011 г. 16:12
  • может когда отправляеш в базу надо указывать кодировку, смотри http://msdn.microsoft.com/ru-ru/library/system.text.encoding.aspx
    • Предложено в качестве ответа Letos07 4 сентября 2011 г. 16:54
    • Отменено предложение в качестве ответа Marchellо 4 сентября 2011 г. 17:33
    4 сентября 2011 г. 16:54
  • Cyrillic_General_CI_AS
    О сколько нам открытий чудных, готовит просвещения дух
    4 сентября 2011 г. 17:02
  • По указанной тобой ссылке выше при попытке открыть ошибка: "The specified CGI application encountered an error and the server terminated the process."

    О сколько нам открытий чудных, готовит просвещения дух
    4 сентября 2011 г. 17:06
  • Нет не то если поле в базе nvarchar оно обязано хранить utf-8 и эксперимент с прямым внесением символа выше говорит что база не при чем. asp:TextBox так же судя по документации поддерживает работу с UTF-8 здесь определенно что то нужно делать с настройками приложения хотя ума не приложу что ещё подкрутить
    О сколько нам открытий чудных, готовит просвещения дух
    4 сентября 2011 г. 17:32
  • В какой именно момент текстбокс у вас теряет текст? Сразу после постбэка превращает его "вопрос в ромбе"? Выставленный в коде Text="æ" отображается корректно? Или как квадрат?

    Судя по всему, у вас просто на странице кодировка не прописана, или определяется неверно. Проверьте, что выбрано в при просмотре страницы в меню View/Encoding (в IE). Если там вдруг не utf-8 - пропишите тэг с кодировкой на странице, внутри head:

     

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    


     

    4 сентября 2011 г. 18:04
  • Вот ещё мысль для раздумий - сейчас глянул формат исходников и они хранятся в 1251 а что это для VS2010 нормально?
    О сколько нам открытий чудных, готовит просвещения дух
    4 сентября 2011 г. 18:17
  • content-type прописан как положено в head так же в конфиге указана globalization на utf-8. Символ "æ" сохраняется как знак вопроса и даже если в базе в поле внести символ как положенно то выводится в textbox как вопрос.
    О сколько нам открытий чудных, готовит просвещения дух
    4 сентября 2011 г. 18:20
  • Ок, прописан - это еще не значит что он действует. Проверьте, что решил браузер. Мало ли, он обнаружил русские символы на странице, и продетектил 1251.

    На стандартном проекте asp.net никаких проблем с ae нет. Если принудительно включить 1251 в браузере - то появляются. Формат сохранения по умолчанию - unicode with signature.

    И проверяйте не что сохраняется, а что содержится на сервере в свойстве TextBox.Text. Ищите место, где проблема с кодировкой, а то сейчас цепочка слишком длинная.
    • Изменено PashaPash 4 сентября 2011 г. 18:33
    4 сентября 2011 г. 18:31
  • Браузер рапортует что выбрал utf-8
    О сколько нам открытий чудных, готовит просвещения дух
    4 сентября 2011 г. 18:41
  • > сайт превращается в белиберду
    проверил на следующем: в web.config параметры globalization - текущие, без изменений.
    в Visual Studio для страницы: File - Advanced Save Options = "Unicode (UTF-8 with signature) - Codepage 65001"
    сервер отдает http-заголовок: Content-Type: text/html; charset=utf-8

    æ - выводится на странице нормально


    в global.asax добавил protected void Application_BeginRequest() и поставил брейкпоинт.

    если методом POST отправить строку с æ на сервер, то приходит %u00e6
    вызов this.Request.Form["..."] возвращает æ

     

    4 сентября 2011 г. 18:54
  • Тогда проверяйте что именно отправил браузер, fiddler-ом. Должна быть строка вида ...&ctl00%24MainContent%24TextBox1=%C3%A6... в TextView и символ æ в WebForms. Можете просто скопировать сюда Raw View запроса, чтобы было понятно что ушло на сервер.

    И на сервере проверьте содержимое TextBox.Text при получении запроса, в отладке.

    4 сентября 2011 г. 18:58
  • Сслыка, которую дал Malobukv - Элемент globalization (схема параметров ASP.NET), попробуйте в другом браузере, если опять будет ошибка. Или попробуйте в конце url добавить знак вопроса.

    Попробуйте пересохранить исходники в формате unicode, как указал Malobukv в ответе. Хотя проблема скорей всего не в этом.

    Попробуйте по совету PashaPash проверить передаваемые данные.

    Не забудьте отметить ответ, который решит проблему. Спасибо.


    Для связи [mail]
    5 сентября 2011 г. 8:14
    Модератор
  • Ну значит текущий итог: В конфиге приложения
    <globalization fileEncoding="utf-8" requestEncoding="utf-8" responseEncoding="utf-8" culture="ru-RU" uiCulture="ru-RU"/>
    Далее на всех страницах в разделе @Page параметр

    ContentType="text/html; charset=UTF-8"
    Далее при передаче значения базе:
    .Parameters.Add("@ArticlesTitle"SqlDbType.NVarChar).Value = ArticlesTitle
    Далее уже в самой базе:
    @ArticlesTitle nvarchar(150) = ''
    И по ходу там же:
    BEGIN
    SET @FinalSQL = 'UPDATE Articles SET [ArticlesTextOS]=''' 
    RTRIM(LTRIM(@Value)) + ''',[ArticlesTitleOS]=''' 
    RTRIM(LTRIM(@ArticlesTitle)) + ''' WHERE [ArticlesID]=' STR(@SearchID)
    END

    Ну не хочет сохранить 'æ' вместо этого '?'


    О сколько нам открытий чудных, готовит просвещения дух
    5 сентября 2011 г. 9:04
  • Чему равно ArticlesTitle при добавлении параметра, в отладке? Локализуйте проблему, не правьте код наугад.
    5 сентября 2011 г. 9:14
  • Я ввожу символ в поле TextBox затем проверяю перед передачей параметра в базу все корректно символ до момента передачи правильный! В базе нагло присваиваю переменной символ но в поле сохраняется вопросительный знак - база не хочет сохранить символ и заменяет на вопросительный знак. Пробую подставить любой другой альтернативный символ тот же результат сохраняет вопрос. Меняю изначальный вопрос почему база не хочет сохранить в поле nvarchar символ utf-8 - "æ"?
    О сколько нам открытий чудных, готовит просвещения дух
    5 сентября 2011 г. 10:38
  • > не хочет сохранить символ

    collation может быть разным у базы, таблиц и столбцов
    http://msdn.microsoft.com/en-us/library/ms190920.aspx

    5 сентября 2011 г. 10:46
  • Не открывается ссылка
    О сколько нам открытий чудных, готовит просвещения дух
    5 сентября 2011 г. 10:53
  • > Не открывается ссылка

    в Chrome? попробуйте http://msdn.microsoft.com/en-us/library/ms190920 (без .aspx)

    5 сентября 2011 г. 10:55
  • Какой collation должен быть для моей ситуации?

     


    О сколько нам открытий чудных, готовит просвещения дух
    5 сентября 2011 г. 11:16
  • В редакции SQL Express не могу найти возможность изменить collation для базы или поля есть ли возможность изменить частно через t-sql?
    О сколько нам открытий чудных, готовит просвещения дух
    5 сентября 2011 г. 11:28
  • Да вижу есть возможность сменить collation через t-sql но легче создать базу с нуля и перенести данные по таблично
    О сколько нам открытий чудных, готовит просвещения дух
    5 сентября 2011 г. 11:43
  • >  изменить collation для базы или поля  
     
    create table test (txt nvarchar(100))
    exec sys.sp_tablecollations 'test' -- collation: SQL_Latin1_General_CP1_CI_AS
    -- меняем collation для txt 
    ALTER TABLE test ALTER COLUMN txt nvarchar(100)  COLLATE Cyrillic_General_CI_AS
    -- добавить 'æ'
    insert into test (txt) values (N'æ')
    select * from test -- получим 'æ'
    
    • Изменено Malobukv 5 сентября 2011 г. 12:01
    • Помечено в качестве ответа Marchellо 5 сентября 2011 г. 12:23
    5 сентября 2011 г. 11:57
  • За 18 лет работы в IT таких ошибок я ещё не делал :) видимо из-за того что юникод раньше не особо использовал - небыло необходимости :)

    Было:

     

    BEGIN
    
    SET @FinalSQL = 'UPDATE Articles SET [ArticlesTextOS]=''' + RTRIM(LTRIM(@Value)) + ''',[ArticlesTitleOS]=''' + RTRIM(LTRIM(@ArticlesTitle)) + ''' WHERE [ArticlesID]=' + STR(@SearchID)
    
    END 
    

     

    Стало:

    BEGIN SET @FinalSQL = 'UPDATE Articles SET [ArticlesTextOS]=N''' + RTRIM(LTRIM(@Value)) + ''',[ArticlesTitleOS]=N''' + RTRIM(LTRIM(@ArticlesTitle)) + ''' WHERE [ArticlesID]=' + STR(@SearchID) END 
    

    Найдите разницу :)

    Все остальные настройки и в приложении и в базе были великолепны - теперь всё сохраняется, помечаю Ваш ответ как правильный ибо мой глаз приметил эту чёртову букву в Вашем тексте :) СПАСИБО!


    О сколько нам открытий чудных, готовит просвещения дух
    5 сентября 2011 г. 12:27
  • > Найдите разницу

    N

    P.S.
    N можно не указывать, если использовать параметры и AddWithValue   

    var sc = new SqlConnection("...");
    var c = sc.CreateCommand();
    c.CommandText = "insert into test (txt) values (@txt)";
    c.Parameters.AddWithValue("@txt", "æ");
    sc.Open();
    c.ExecuteNonQuery();
    sc.Close();


    • Изменено Malobukv 5 сентября 2011 г. 13:03 добавил P.S.
    5 сентября 2011 г. 12:32
  • Вы видимо не поняли суть передачи смотрите выше там работа с базой через класс параметры строго типизированы.
    О сколько нам открытий чудных, готовит просвещения дух
    6 сентября 2011 г. 8:49
  • А зачем тогда динамическая генерация SQL? Она сводит на нет всю строгую типизацию. Почему не написать простой UPDATE?

    У вас же там сейчас возможен SQL Injection - можно спустить @Value вида '-- и текст у всех статей станет пустым. И вообще все что угодно выполнить после него.


    • Изменено PashaPash 6 сентября 2011 г. 9:19
    6 сентября 2011 г. 9:18
  • Спокойно! Без паники! Сейчас специально зашел и попытался сделать этот самый SQL Enjection - провокация! Не инжектируется :)
    О сколько нам открытий чудных, готовит просвещения дух
    6 сентября 2011 г. 10:05
  • Так же смотрим вот здесь http://msdn.microsoft.com/ru-ru/library/ms161953

    пункт: "Использование SQL-параметров безопасных типов"

    Далее там по тексту: "В этом примере параметр @au_id обрабатывается как буквенное значение, а не исполняемый код. Это значение проверяется по типу и длине. Если значение @au_id не соответствует указанным ограничениям типа и длины, то будет вызвано исключение."

    Напротив в Вашем примере строгой типизации нет и возможен то самый SQL Injection


    О сколько нам открытий чудных, готовит просвещения дух
    6 сентября 2011 г. 10:42
  • я про @ArticlesTitle, а не про ID. у него тип string/nvarchar(max), судя по коду. Может быть вы его эскейпите выше по коду, но это нужно проверить. В статье MSDN параметр используется "как есть", а не для генерации SQL. Т.е. статья как раз советует сделать так, как выше предложил Malobukv.

    Например, следующие значения параметров определенно приводят к удалению таблицы пользователей:

     

    DECLARE @Value nvarchar(max) = ''' WHERE 1=0; DROP Table Users --'
    DECLARE @ArticlesTitle nvarchar(max) = ''
    DECLARE @SearchID int = 0
    DECLARE @FinalSQL nvarchar(max) = ''
    
    SET @FinalSQL = 'UPDATE Articles SET [ArticlesTextOS]=''' + RTRIM(LTRIM(@Value)) + ''',[ArticlesTitleOS]=''' + RTRIM(LTRIM(@ArticlesTitle)) + ''' WHERE [ArticlesID]=' + STR(@SearchID)
    
    
    (0 row(s) affected)
    Msg 3701, Level 11, State 5, Line 1
    Cannot drop the table 'Users', because it does not exist or you do not have permission.
    
    

    Вы уверены, что ваш код не позволяет передать значение Value вроде этого (с одинарной кавычкой)

    ' WHERE 1=0; DROP Table Users --

    Т.е. если не позволяет - то нужно наверняка знать про место, в котором делается экранирование. Чтобы случайно его не "пофиксить". Меня смущает сам факт генерации SQL для такого простого апдейта. В этом есть реальная необходимость? Если есть - то посмотрите ту же статью, раздел "Упаковка параметров с помощью функций QUOTENAME() и REPLACE()" - там практически такой же код, как у вас, но с исправленной проблемой.

    Выше моего примера с SQL нет :). А в примере Malobukv точно ничего не инжектируется - там как раз параметр и строгая типизация. 


    • Изменено PashaPash 6 сентября 2011 г. 13:09
    6 сентября 2011 г. 13:00