Динамическая установка режима read only для веб части SocialCommentWebPart

Веб часть SocialCommentWebPart относится к новым возможностям, которые появились в Sharepoint 2010. Она позволяет пользователям добавлять комментарии на страницы, где она установлена. Данная веб часть делает сайт, созданный на Sharepoint, более социальным и улучшает взаимодействие с пользователями. Одно из распространенных требований к такой функциональности – ограничение возможности оставлять комментарии, т.е. не все пользователи сайта должны иметь возможность комментировать контент. Например, вы можете решить, что только зарегистрированные пользователи должны иметь возможность оставлять комментарии (в случае если вы разрабатываете self-service систему), или вы можете использовать авторизацию на основе членства в определенной группе. В обоих случаях вам надо установить веб часть SocialCommentWebPart в режим только для чтения (read only) динамически во время исполнения. У данной веб части есть свойство SocialCommentWebPart.WebPartPropertyAllowNewComment. Но как и остальные свойства веб частей, предполагается что администратор или ответственный за контент установит ее один раз, и эта установка будет влиять на всех пользователей. Это не то, что нам нужно. Наша цель – дать возможность определенным пользователям оставлять комментарии, а другим – запретить.

Если вы изучите код веб части SocialCommentWebPart в reflector-е, то увидите, что вся функциональность реализована в отдельном user control-е SocialCommentControl (это неплохой паттерн при проектировании веб частей – выносить функциональность в user control, т.к. ваши дизайнеры по-прежнему будут иметь возможность править разметку без изменений кода). У этого элемента управления есть свойство AllowNewComment и веб часть устанавливает это свойство при добавлении элемента управления SocialCommentControl в свою коллекцию контролов. Это свойство – то, что нам нужно. К сожалению, оно объявлено как internal, так что мы не сможем использовать его напрямую в нашем коде. Нам поможет reflection. Предположим, что мы добавили веб часть непосредственно на page layout (т.е. она не добавлена через UI на publishing page, созданную на основе нашего page layout-а. В последнем случае, подход будет таким же. Единственное, что нужно будет сделать – это определить идентификатор веб части):

<SPSWC:SocialCommentWebPart 
    runat="server" 
    Title="Comments" 
    AllowEdit="True" 
    AllowConnect="True" 
    ConnectionID="00000000-0000-0000-0000-000000000000" 
    IsIncluded="True" 
    Dir="Default" 
    PartImageLarge="" 
    IsVisible="True" 
    AllowMinimize="True" 
    ZoneID="" 
    ID="g_61df80f5_8c13_4355_aeee_a52b497e81c6" 
    FrameState="Normal" 
    ExportMode="All" 
    AllowHide="True" 
    SuppressWebPartChrome="False" 
    DetailLink="" 
    ChromeType="None"
    DescriptionLocId="Null" 
    MissingAssembly="Cannot import this Web Part." 
    PartImageSmall="" 
    AllowRemove="True" 
    HelpMode="Modeless" 
    FrameType="TitleBarOnly" 
    AllowZoneChange="True" 
    PartOrder="1" 
    Description="Enable users to leave short, publicly-viewable notes about this page." 
    HelpLink="" 
    DescriptionLocIdNum="0" 
    ExportControlledProperties="True" 
    IsIncludedFilter="" 
    __MarkupType="vsattributemarkup" 
    __WebPartId="{61df80f5-8c13-4355-aeee-a52b497e81c6}" 
    WebPart="true" 
    Height="" 
    Width="">
</SPSWC:SocialCommentWebPart>

Для того чтобы установить веб часть в режим только для чтения, используем следующий код, который можно добавить непосредственно на page layout как серверный скрипт:

<script runat="server" type="text/C#">
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        if (yourOwnLogic())
        {
            SocialCommentControl c =
                ControlFinder.FindChildControl<SocialCommentControl>(g_61df80f5_8c13_4355_aeee_a52b497e81c6);
            if (c != null)
            {
                ReflectionHelper.CallMethod(c, "set_AllowNewComment", false);
            }
        }
    }
</script>

Здесь функция yourOwnLogic() – любая функция, которую вы можете использовать для определения того, имеет текущий пользователь право оставлять комментарии или нет (как я уже говорил, например, вы можете проверить является ли пользователь членом определенной группы или нет). В приведенном коде были использованы 2 дополнительных компонента: ControlFinder и ReflectionHelper. Их реализация довольно простая. ControlFinder рекурсивно ищет элемент управления с указанным в generic-е типом в указанной коллекции:

public static class ControlFinder
{
    public static T FindChildControl<T>(Control startingControl) where T : Control
    {
        T found = null;
        foreach (Control c in startingControl.Controls)
        {
            found = c as T;
            if (found == null)
            {
                found = FindChildControl<T>(c);
            }
            if (found != null)
            {
                break;
            }
        }
        return found;
    }
}

ReflectionHelper – вспомогательный класс, который можно использовать, если вам надо поэкспериментировать с внутренним устройством Sharepoint (я понимаю, что в реальной жизни это может быть необходимым, но помните, что этот способ не является официальным способом работы с Sharepoint и не поддерживается):

public static class ReflectionHelper
{
    public static object CallMethod(object obj, string name, params object[] argv)
    {
        BindingFlags bf = 0 | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
        MethodInfo mi = obj.GetType().FindMembers(MemberTypes.Method, bf, Type.FilterName, name)[0] as MethodInfo;
        return mi.Invoke(obj, argv);
    }

    public static object CallStaticMethod(Type t, string name, params object[] argv)
    {
        BindingFlags bf = 0 | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
        MethodInfo mi = t.FindMembers(MemberTypes.Method, bf, Type.FilterName, name)[0] as MethodInfo;
        return mi.Invoke(null, argv);
    }

    public static object GetStaticData(Type t, string name)
    {
        BindingFlags bf = 0 | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
        FieldInfo fi = t.FindMembers(MemberTypes.Field, bf, Type.FilterName, name)[0] as FieldInfo;
        return fi.GetValue(null);
    }
}

С указанным подходом веб часть SocialCommentWebPart будет работать в режиме только для чтения, если у пользователя нет достаточных прав, и будет позволять добавлять комментарии авторизованным пользователям.

Реклама

Об авторе sadomovalex

Старший инженер, team lead, консультант. Работаю в стеке .Net. Последние несколько лет занимаюсь разработкой enterprise приложений под Sharepoint, чему и будет в основном посвящена тематика этого блога. Также активно использую и интересуюсь ASP.Net MVC, DDD, TDD, Agile. Активно участвую в жизни многих профессиональных сообществ, SPb .Net UG, SPb ALT.Net, rsdn, Finland SP UG и др.
Запись опубликована в рубрике Sharepoint, Social computing. Добавьте в закладки постоянную ссылку.

2 комментария на «Динамическая установка режима read only для веб части SocialCommentWebPart»

  1. Сергей:

    Добрый день. Подскажите начинающему пользователю SharePoint.
    Как создавать на страницах web части SocialCommentWebPart что бы их содержание не дублировалось. Т.е. на каждой странице отдельная (своя) SocialCommentWebPart
    Спасибо

  2. Сергей, добрый день,
    комментарии к страницам хранятся в отдельной social database, и они привязаны к странице с использованием урла. Т.е. если две страницы имеют разные урлы, то и комментарии у них будут разными. Для этого ничего специально делать не надо. Детали внутреннего устройства этого механизма можно прочитать в этом посте: https://sadomovalex.wordpress.com/2011/12/17/change-page-url-for-social-comments-html/.
    По умолчанию в Sharepoint нельзя создать две страницы с одинаковыми урлами (что вполне логично). Так что просто добавьте веб часть в page layout и все будет работать по умолчанию.

Добавить комментарий

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

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s