четверг, 14 июня 2012 г.

Тонкости получения списка SharePoint

Есть несколько способов получения списка по его названию без выбрасывания исключения. Это индексатор SPListCollection и метод SPListCollection.TryGetList. Однако не стоит исключать, что в процессе жизни решения названия списков могут измениться. Это вполне вероятно, особенно при переходе от пилотной эксплуатации к промышленной. В это время решением попользовались простые пользователя и поняли как всякие мелочи, вроде названия списка, будут удобны именно им, а не разработчикам, которые эти названия придумывали.
В отличии от названия, Url и Guid списка не меняются на протяжении жизни развернутого решения. При каждом разворачивании Guid'ы списков меняются, поэтому использовать их для поиска нужных списков не удобно. А вот Url, пожалуй, является самым главным претендентом для поиска списков. Мне удалось найти только один метод, позволяющий получить список по Url, это SPWeb.GetList. Однако его недостатком является выбрасывание исключения при попытке получения списка по несуществующему Url. Это можно обойти при помощи объекта SPFolder. Каждый список имеет RootFolder, в котором хранятся страницы для просмотра списка элементов и форм элемента. Для его получения есть метод не выбрасывающий исключений. Вот как можно получить список, обезопасив себя от исключений:

SPWeb web          = site.RootWeb;
SPFolder folder    = web.GetFolder("your list url");
if (true == folder.Exist)
    //Если библиотека
    if (null != folder.DocumentLibrary)
        return folder.DocumentLibrary;
    else
        return web.GetList(folder.Url);

Таким образом, исключение может возникнуть только при попытке получить список по Url существующей на сайте папке, не принадлежащей к списку. Например, "Lists". Однако, вероятность того, что программист сам попытается получить список по такому Url мала и в большинстве случаем достаточно описанного выше метода.

7 комментариев:

  1. А смысл? Ведь если списка нет, то это исключительная ситуация, а мало что можно сделать кроме как прекратить работу. Для этого и нужны exceptions. Достаточно ловить DirectoryNotFoundException чтобы обработать ситуацию когда список не найден.

    ОтветитьУдалить
  2. Производительность. Даже не сработавший блок try catch влияет на скорость выполнения. В стэк добавляются специальные маркеры, позволяющие не падать потоку при выбрасывании исключения, а отлавливать и обрабатывать это исключение.
    В классической книжке по отладке .NET приложений (ту, что написал бывший спецназовец), отлавливание исключения и предупреждение его сравнивается с открученной на колесе гайкой. Можно ехать с открученной гайкой и восстанавливать машину после удара в стену, а можно перед ездой посмотреть на колеса и закрутить недостающую гайку.
    На практике же надо взвешивать. Быть может дешевле сломать одну машину из миллиона, чем просмотреть 4 миллиона колес.

    ОтветитьУдалить
  3. >>(true == folder.Exist)
    зачем такая конструкция?

    ОтветитьУдалить
  4. Только удобство чтения, никакой функциональной значимости нет.

    ОтветитьУдалить
  5. >> Даже не сработавший блок try catch влияет на скорость выполнения.
    http://stackoverflow.com/questions/1350264/try-catch-performance
    В кратце: почти не влияет. Кроме того не нужно получать много списков в цикле, иначе можно воспользоваться проходом по всем спискам.

    ОтветитьУдалить
  6. я выношу такие конструкции в extension method для SPWeb. Часто оборачиваю все в try/catch и возвращаю null в случае любого exception-а и на вызывающей стороне проверяю на null. Для большинства задач достаточно.

    ОтветитьУдалить
  7. С try/catch так же могут возникнуть сложности связанные с маскировкой исключений. Например, я не уверен, что DirectoryNotFoundException возникает только когда нету списка по указанному Url. Наверняка это так, но все же пару раз напоровшись на замаскированные подобными способами исключения, я стараюсь не доводить дело до их отлавливания.

    >не нужно получать много списков в цикле, иначе можно воспользоваться проходом по всем спискам
    Возможно так будет лучше. Зависит от конкретной ситуации.

    ОтветитьУдалить