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 здесь.

Виталий Жуков

Виталий Жуков

SharePoint архитектор, разработчик, тренер, Microsoft MVP (Office Development). Более 15 лет опыта работы с SharePoint, Dynamics CRM, Office 365, и другими продуктами и сервисами Microsoft.

Смотрите также

SharePoint 2007. Проверка на наличие элемента в списке

SharePoint 2007. Проверка на наличие элемента в списке

SharePoint 2007. База данных содержимого

SharePoint 2007. База данных содержимого

SharePoint 2007. Свой контрол на панели свойств веб-парта

SharePoint 2007. Свой контрол на панели свойств веб-парта

SharePoint 2007. Максимальное/минимальное значение поля в списке

SharePoint 2007. Максимальное/минимальное значение поля в списке

SharePoint 2007. Получение данных из нескольких списков и узлов

SharePoint 2007. Получение данных из нескольких списков и узлов