PeopleEditor и Internet Explorer 9

Сначала я покажу как работает PeopleEditor в IE 8, а потом покажу почему он не хочет работать так же в IE 9 и что надо сделать, чтобы исправить эту ситуацию.

Как работает PeopleEditor

Когда мы вводим текст в поле и нажимаем на кнопку валидации, то происходит асинхронный вызов для валидации введенных данных на сервере в результате которого клиенту возвращается XML-документ примерно вот такого содержания:

  1. <Entities Append="False" Error="" DoEncodeErrorMessage="True" Separator=";" MaxHeight="3">
  2.  <Entity Key="MSCPC11\zhukovv" DisplayText="MSCPC11\zhukovv" IsResolved="True" Description="MSCPC11\zhukovv">
  3.   <ExtraData>
  4.    <ArrayOfDictionaryEntry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  5.     <DictionaryEntry>
  6.      <Key xsi:type="xsd:string">SPUserID</Key>
  7.      <Value xsi:type="xsd:string">1</Value>
  8.     </DictionaryEntry>
  9.     <DictionaryEntry>
  10.      <Key xsi:type="xsd:string">AccountName</Key>
  11.      <Value xsi:type="xsd:string">MSCPC11\zhukovv</Value>
  12.     </DictionaryEntry>
  13.     <DictionaryEntry>
  14.      <Key xsi:type="xsd:string">PrincipalType</Key>
  15.      <Value xsi:type="xsd:string">User</Value>
  16.     </DictionaryEntry>
  17.    </ArrayOfDictionaryEntry>
  18.   </ExtraData>
  19.   <MultipleMatches />
  20.  </Entity>
  21. </Entities>

После чего эти данные преобразуются и записываются в скрытое поле для дальнейшей передачи на сервер верифицированных данных:

Ошибка в Internet Explorer 9

Теперь мы дошли до момента, где и происходит ошибка. Если теперь отправить данные на сервер, то произойдет следующая ошибка:

System.InvalidOperationException: Префикс пространства имен

Т.е. при разборе данных на сервере полученный XML не содержит определения пространства имен XSD.

Если же мы вызовем повторную валидацию данных на странице, то и в этом случае получим ошибку, но уже на стороне клиента, не доходя до асинхронного вызова. Причина та же: неверно сформирован XML-документ:

Ошибка при валидации PeopleEditor'а

Сам асинхронный вызов происходит одинаково во всех браузерах, сервер реагирует на эти асинхронные запросы, не зависимо от браузера, их породившего. Следовательно, проблема, связанная с IE9, происходит на клиенте, а именно в момент преобразования полученных от сервера данных при асинхронном вызове на стороне клиента.

Данные в скрытом поле

Если посмотреть данные, которые в итоге записываются в скрытое поле PeopleEditor'а, то мы увидим характерное их отличие друг от друга в различных браузерах. Данные такого вида будут присутствовать в Internet Explorer 8:

  1. <ArrayOfDictionaryEntry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  2.      <DictionaryEntry>
  3.       <Key xsi:type="xsd:string">SPUserID</Key>
  4.       <Value xsi:type="xsd:string">1</Value>
  5.      </DictionaryEntry>
  6.      <DictionaryEntry>
  7.       <Key xsi:type="xsd:string">AccountName</Key>
  8.       <Value xsi:type="xsd:string">MSCPC11\zhukovv</Value>
  9.      </DictionaryEntry>
  10.      <DictionaryEntry>
  11.       <Key xsi:type="xsd:string">PrincipalType</Key>
  12.       <Value xsi:type="xsd:string">User</Value>
  13.      </DictionaryEntry>
  14.     </ArrayOfDictionaryEntry>

А в Internet Explorer 9 те же операции приведут нас к немного иному результату:

  1. <ArrayOfDictionaryEntry>
  2.    <DictionaryEntry>
  3.     <Key xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">SPUserID</Key>
  4.     <Value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">1</Value>
  5.    </DictionaryEntry>
  6.    <DictionaryEntry>
  7.     <Key xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">AccountName</Key>
  8.     <Value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">MSCPC11\zhukovv</Value>
  9.    </DictionaryEntry>
  10.    <DictionaryEntry>
  11.     <Key xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">PrincipalType</Key>
  12.     <Value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">User</Value>
  13.    </DictionaryEntry>
  14.   </ArrayOfDictionaryEntry>

EntityEditor.js

Теперь ясно, почему происходит ошибка при разборе XML-данных. Осталось понять где это происходит. Для этого нам понадобится скрипт EntityEditor.js, а именно его DEBUG-версия.

Если включить режим отладки в браузере и "проследить" процесс исполнения скрипта, то станет понятно, что виноват XmlSerializer, который не регистрирует так необходимое нам пространство XSD.

Internet Explorer 9 не умеет возвращать свойства firstChild, innerXml и прочее.

Не очень красивое решение

Я не стал искать красивое решение этой баги. Для меня было важно сделать так, чтобы все работало. Я просто добавил две строки в блок кода, в котором используется XmlSerializer:

  1. //delete namespace from data elements
  2. data = data.replace(' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type=', ' xsi:type=');
  3. //add namespace to root element
  4. data = data.replace('<ArrayOfDictionaryEntry>', '<ArrayOfDictionaryEntry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">');

Если кто-то знает как эти две строки заменить более красивым кодом - пишите в комментариях. Я убежден, что скоро должен выйти (или уже вышел) какой-нибудь hotfix, который решит эту проблему, когда продукт от Microsoft не работает с продуктом от Microsoft.

Вот примеры работоспособности модифицированного PeopleEditor в различных браузерах:

Уменьшаем размер EntityEditor.js

Теперь осталось сжать debug-версию файла entityeditor.debug.js. О том как это делается есть замечательная статья замечательного программиста Андрея Тарицына.

Проект, чтобы попробовать работоспособность PeopleEditor здесь.


Поделиться

Коментарии