«Не удается выполнить это действие» при попытке предоставить экземпляр списка сайту TaxonomyField. - PullRequest
1 голос
/ 17 февраля 2011

Справедливое предупреждение: этот вопрос достаточно длинный, поэтому наберитесь терпения и оставайтесь со мной.

У меня есть две функции в пакете решений.Первый - это набор полей сайта и типов контента;давайте назовем это Feature A .Среди полей есть поле типа «TaxonomyFieldType» и связанное поле типа «Примечание» ( объяснение поля примечания ).

<Elements ...>  
<Field ID="{956a1078-ec35-4c04-83c4-0a3742119496}" 
        Name="TaxonomyTextField" 
        Type="Note" DisplayName="Tags_0" 
        ShowInViewForms="FALSE" 
        Required="FALSE"
        Group="MyGroup"
        Hidden="TRUE"/>

<Field ID="{92BC866B-0415-45F0-B431-D4DF69C421CC}"
        Name="Tags"
        DisplayName="Custom Tags"
        Type="TaxonomyFieldType"
        ShowField="Term1033"
        Required="FALSE"
        Group="MyGroup"
        >
  <Customization>
    <ArrayOfProperty>
      <Property>
        <Name>IsPathRendered</Name>
        <Value xmlns:q7="http://www.w3.org/2001/XMLSchema" p4:type="q7:boolean" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">true</Value>
      </Property>
      <Property>
        <Name>TextField</Name>
        <Value xmlns:q6="http://www.w3.org/2001/XMLSchema" p4:type="q6:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">{956a1078-ec35-4c04-83c4-0a3742119496}</Value>
      </Property>
    </ArrayOfProperty>
  </Customization>
</Field>
</Elements>

и

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <!-- Parent ContentType: Item (0x01) -->
  <ContentType ID="0x0100b61c774f4c0e4a89bf230cbb44cd4f75"
               Name="MyContent"
               Group="MyGroup"
               Description="Description of My Content Type"
               Inherits="FALSE"
               Overwrite="TRUE"
               Version="0">
    <FieldRefs>
      <FieldRef ID="{52578fc3-1f01-4f4d-b016-94ccbcf428cf}" DisplayName="Comments" Name="Comments" Required="FALSE"/>
      <FieldRef ID="{956a1078-ec35-4c04-83c4-0a3742119496}" Name="TimeTrackerTaxonomyTextField"/>
      <FieldRef ID="{92BC866B-0415-45F0-B431-D4DF69C421CC}" DisplayName="Tags" Name="Tags" Required="FALSE"/>
    </FieldRefs>
  </ContentType>
</Elements>

В приемнике функций для первой функции (назовем ее функцией A) я программно извлекаю эту TaxonomyField и проверяю, настроена ли она на получение терминов из заранее определенного набора терминов:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    SPWeb web = GetWebObj(properties.Feature.Parent);
    Guid fieldId = new Guid("92BC866B-0415-45F0-B431-D4DF69C421CC");
    TaxonomyField field = web.Fields[fieldId] as TaxonomyField;
    string groupName = properties.Feature.Properties["TaxonomyGroupName"].Value;
    string termSetName = properties.Feature.Properties["TermSetName"].Value;
    DiagnosticService logger = DiagnosticService.Local;

    TermSet set = null;
    TaxonomySession session = new TaxonomySession(web.Site);
    TermSetCollection termSets = session.GetTermSets(termSetName, System.Threading.Thread.CurrentThread.CurrentUICulture.LCID);
    if (termSets == null || termSets.Count == 0)
    {
        logger.WriteTrace(1, logger[CategoryId.Deployment], TraceSeverity.Medium,
            "Activity Tags term set not found.  Ensuring '{0}' group and '{1}' term set.", groupName, termSetName);
        // create the term set in the default store
        var store = session.DefaultSiteCollectionTermStore;
        var group = store.EnsureGroup(groupName);
        set = group.EnsureTermSet(termSetName);

        store.CommitAll();
        logger.WriteTrace(1, logger[CategoryId.Provisioning], TraceSeverity.Verbose, "created taxonomy group '{0}' and term set '{1}'", group, set);
    }
    else
    {
        logger.WriteTrace(1, logger[CategoryId.Deployment], TraceSeverity.Verbose, "term set found.");
        // need to make sure we grab the one in the right group, or it might be someone else's term set.                
        foreach (var termSet in termSets)
        {
            if (String.Equals(termSet.Group.Name,groupName))
            {
                if (set == null)
                {
                    set = termSet;
                }
                else
                {
                    logger.WriteTrace(1, logger[CategoryId.Deployment], TraceSeverity.Unexpected,
                        "Multiple term sets named '{0}' found in more than one taxonomy group.", termSetName);
                    throw new SPException(String.Format("Multiple term sets named '{0}' found in more than one taxonomy group.  "+
                                                        "Was there a previous installation that was not removed properly?", termSetName));
                }
            }
        }

        if (set == null)
        {
            // term set found, but in an unrecognized group.  leave it alone and do like above
            logger.WriteTrace(1, logger[CategoryId.Deployment], TraceSeverity.Verbose,
                "Term set '{0}' found, but in unrecognized group.  Provisioning new group and term set as configured.", termSetName);
            var store = session.DefaultSiteCollectionTermStore;
            var group = store.EnsureGroup(groupName);
            set = group.EnsureTermSet(termSetName);

            store.CommitAll();
            logger.WriteTrace(1, logger[CategoryId.Provisioning], TraceSeverity.Verbose, "created taxonomy group '{0}' and term set '{1}'", group, set);
        }
    }

    // set termSets to the newly created term set                
    field.SspId = set.TermStore.Id;
    field.TermSetId = set.Id;
    field.TargetTemplate = String.Empty;
    field.AnchorId = Guid.Empty;
    field.Open = true;
    field.AllowMultipleValues = true;
    field.Update();
}

Вторая функция содержит шаблоны списков и экземпляры, один из которых использует вышеуказанный тип содержимого;давайте назовем эту функцию Функция B .

Вот схема списка для списка, который взрывается при инициализации (элемент ListInstance не показан):

<?xml version="1.0" encoding="utf-8"?>
<List xmlns:ows="Microsoft SharePoint" Title="My List" FolderCreation="FALSE" Direction="$Resources:Direction;" Url="Lists/MyList" BaseType="0" xmlns="http://schemas.microsoft.com/sharepoint/">
  <MetaData>
    <ContentTypes>      
      <ContentTypeRef ID="0x0100b61c774f4c0e4a89bf230cbb44cd4f75"></ContentTypeRef>
    </ContentTypes>

    <Fields> 
      <Field ID="{956a1078-ec35-4c04-83c4-0a3742119496}" Name="TaxonomyTextField" Type="Note"/>      
      <Field ID="{92bc866b-0415-45f0-b431-d4df69c421cc}" Name="Tags" Type="TaxonomyFieldType"/>
      <Field ID="{52578FC3-1F01-4f4d-B016-94CCBCF428CF}" Name="_Comments" Type="Note"/>      
    </Fields>
    <Views>
      <View BaseViewID="1" Type="HTML" WebPartZoneID="Main" DisplayName="$Resources:core,objectiv_schema_mwsidcamlidC24;" DefaultView="TRUE" MobileView="TRUE" MobileDefaultView="TRUE" SetupPath="pages\viewpage.aspx" ImageUrl="/_layouts/images/generic.png" Url="AllItems.aspx">
        <Toolbar Type="Standard" />
        <XslLink Default="TRUE">main.xsl</XslLink>
        <RowLimit Paged="TRUE">30</RowLimit>
        <ViewFields>
          <!-- <FieldRef Name="Tags"></FieldRef> -->
          <FieldRef Name="_Comments"></FieldRef>
        </ViewFields>
        <Query>
          <OrderBy>
            <FieldRef Name="ID">
            </FieldRef>
          </OrderBy>
        </Query>
        <ParameterBindings>
          <ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" />
          <ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_DEFAULT)" />
        </ParameterBindings>
      </View>
    </Views>
    <Forms>
      <Form Type="DisplayForm" Url="DispForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
      <Form Type="EditForm" Url="EditForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
      <Form Type="NewForm" Url="NewForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
    </Forms>
  </MetaData>
</List>

ПослеРешение развертывается, я могу активировать Функция A без проблем.Столбцы сайта и типы контента созданы.Когда я пытаюсь активировать функцию B , стек вызовов активации функции взрывается и приводит к появлению страницы ошибки со следующей трассировкой стека:

[COMException (0x80004005): Cannot complete this action.

Please try again.]
   Microsoft.SharePoint.Library.SPRequestInternalClass.UpdateField(String bstrUrl, String bstrListName, String bstrXML) +0
   Microsoft.SharePoint.Library.SPRequest.UpdateField(String bstrUrl, String bstrListName, String bstrXML) +134

[SPException: Cannot complete this action.

Please try again.]
   Microsoft.SharePoint.Administration.SPElementDefinitionCollection.ProvisionListInstances(SPFeaturePropertyCollection props, SPSite site, SPWeb web, Boolean fForce) +23649702
   Microsoft.SharePoint.Administration.SPElementDefinitionCollection.ProvisionElements(SPFeaturePropertyCollection props, SPWebApplication webapp, SPSite site, SPWeb web, Boolean fForce) +197
   Microsoft.SharePoint.SPFeature.Activate(SPSite siteParent, SPWeb webParent, SPFeaturePropertyCollection props, Boolean fForce) +25437263
   Microsoft.SharePoint.SPFeatureCollection.AddInternal(SPFeatureDefinition featdef, Version version, SPFeaturePropertyCollection properties, Boolean force, Boolean fMarkOnly) +27496735
   Microsoft.SharePoint.SPFeatureCollection.AddInternalWithName(Guid featureId, String featureName, Version version, SPFeaturePropertyCollection properties, Boolean force, Boolean fMarkOnly, SPFeatureDefinitionScope featdefScope) +150
   Microsoft.SharePoint.SPFeatureCollection.Add(Guid featureId, Boolean force, SPFeatureDefinitionScope featdefScope) +83
   Microsoft.SharePoint.WebControls.FeatureActivator.ActivateFeature(Guid featid, SPFeatureDefinitionScope featdefScope) +699
   Microsoft.SharePoint.WebControls.FeatureActivatorItem.BtnActivateFeature_Click(Object objSender, EventArgs evtargs) +140
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +115
   System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +140
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +29
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2981

Я вполне уверен, что что-то естьнеправильно с настройкой TaxonomyField в компоненте A ;его связь с экземпляром списка во время инициализации является причиной ошибки (я определил это, комментируя фрагменты и развертывая снова и снова).Кажется, что очень мало документации или даже опыта блоггеров с TaxonomyFields и предоставлением их в списках, так что я немного растерялся.Кто-нибудь имеет представление о том, что происходит не так?

Ответы [ 3 ]

1 голос
/ 08 марта 2011

Я следовал Как подготовить столбцы управляемых метаданных SharePoint 2010 от Wictor Wilén и смог получить что-то похожее работающее (не забудьте также внести изменения из этого комментария ).

0 голосов
/ 16 октября 2015

Я получаю ту же ошибку при активации изолированной функции, которая содержит элементы ListInstance для изолированного пользовательского шаблона списка, который содержит пользовательский ContentTypeRef.Список создан, но при создании ошибки произошла ошибка.Кроме того, список содержит автоматически сгенерированный тип содержимого, а не тот, который указан в определении списка.Если вы продолжаете пытаться активировать эту функцию до тех пор, пока не будут созданы все списки, эта функция, наконец, активируется.

Кроме того, я заметил, что не могу обновить свойства настраиваемых полей в песочнице из решений SandBoxed в MOSS 2010. Я получаю то же самоетип ошибки, указывающий, что он не может завершить действие, когда SPListItem.UpdateField вызывается для настраиваемого поля, определенного через XML в изолированном решении.

Теперь я делаю вывод, что обновления изолированного поля не поддерживаются в изолированных решениях для MOSS 2010.

Вместо программного обновления полей из изолированного пользовательского типа содержимого следует полностью определить поле вОпределение поля XML и поле шаблона списка Элемент XML.

Способ получения вашего списка для использования пользовательского типа контента и активации без возникновения ошибки «Cannot Complete This Action»:

1) Используйте ContentTypeRef по умолчанию в определении списка, а не пользовательский, который вы создали.

https://msdn.microsoft.com/en-us/library/office/ms452896(v=office.14).aspx

Например: 0x01 Тип содержимого элемента по умолчанию

0x0101 Тип содержимого документа по умолчанию

В файле List Schema.xml, если вашТип содержимого основан на типе содержимого элемента по умолчанию. Вы должны изменить его на:

<ContentTypes>
    <ContentTypeRef ID="0x01"></ContentTypeRef>
</ContentTypes>

2) Добавить приемник событий, активируемый функцией, к функции, которая выполняет код для настройки типа содержимого списка.

Я написал функцию, которая в основном устанавливает тип контента для списка и избавляется от любых других типов контента, связанных со списком.Получатель события активации функции может запустить эту функцию и установить типы контента для ваших списков на тот, который должен быть.Функция ниже предполагает, что ваши типы контента имеют уникальные имена.Вы также можете добавить проверку имени группы типов контента, если это необходимо.

       public static string ConfigureCustomListForCustomContentType(SPWeb web, string strListName, string strCustomContentTypeName)
    {
        StringBuilder sbOutput = new StringBuilder();
        try
        {
            SPList customlist = web.Lists[strListName];

            SPContentType CustomContentType = null;
            //Validate Content Types
            //1) Find the Content Type in the Content Type list
            foreach (SPContentType spct in web.Site.RootWeb.ContentTypes)
            {
                if (spct.Name == strCustomContentTypeName)
                {
                    CustomContentType = spct;
                    break;
                }
            }

            if (CustomContentType == null)
            {
                sbOutput.Append("<div class='error'>Unable to find custom content type named " + strCustomContentTypeName +".</div>");
                return sbOutput.ToString();
            }
            sbOutput.Append("Found content Type "+CustomContentType.Name+"...<br />");

            Boolean bFoundContentType = false;


            customlist.ContentTypesEnabled = true;

            List<SPContentTypeId> RemoveContentTypeList = new List<SPContentTypeId>();
            //Remove all other content types
            foreach (SPContentType spct in customlist.ContentTypes)
            {
                if (spct.Name == strCustomContentTypeName)
                {
                    bFoundContentType = true;
                }
                else
                {
                    RemoveContentTypeList.Add(spct.Id);
                }

            }


        if (!bFoundContentType)
            {
                sbOutput.Append("Adding [" + strCustomContentTypeName + "] to List " + customlist.Title + "<br />");
                customlist.ContentTypes.Add(CustomContentType);
            }
            else
            {
                sbOutput.Append("[" + strCustomContentTypeName + "] already in List " + customlist.Title + ".<br />");
            }

            for (int i = 0; i < RemoveContentTypeList.Count; i++)
            {

                sbOutput.Append("Removing extra content type: " + customlist.ContentTypes[RemoveContentTypeList[i]].Name + "<br />");
                customlist.ContentTypes[RemoveContentTypeList[i]].Delete();
            }


        }
        catch (Exception ex)
        {
            sbOutput.Append("<div class='error'>Error occurred configuring "+strListName+": " + ex.ToString() + "<br /></div>");
        }

        return sbOutput.ToString();

    }

Это позволит вам создать экземпляр списка и установить тип контента в соответствии с вашим пользовательским типом контента.

Если список основан на типе события 0x0102, то вышеуказанная функция может не работать, не вызывая ошибки в изолированном решении.

Для типа события я использовал тип содержимого события по умолчанию и выполнилкод для настройки списка (добавление столбцов) по мере необходимости.

0 голосов
/ 09 марта 2011

В итоге я открыл инцидент поддержки в Microsoft, чтобы выяснить это.В конце концов, их сервисный представитель отследил его до установки свойства DisallowContentTypes="FALSE" в шаблоне списка и EnableContentTypes="TRUE" в схеме списка.Это решило мою проблему с подготовкой.

Однако у меня все еще есть проблема с возможностью создания элементов во вновь подготовленных списках, связанные с полем скрытого текста, которое должно сопровождать поле таксономии (grrr).Я подготовил поле примечания на сайте и сослался на него в своем шаблоне списка, и я установил для свойства TextField идентификатор этого поля примечания как в определении столбца сайта, так и в определении поля.

Wictor упоминает об этом (если я припомню, прочитав его пост), но здесь есть еще: http://www.sharepointconfig.com/2011/03/the-complete-guide-to-provisioning-sharepoint-2010-managed-metadata-fields/

В настоящее время я застрял в исключении, которое выдается во время создания предмета, говоря:

Не удалось получить значение столбца «Теги» из элемента управления типа поля «Управляемые метаданные».Подробности смотрите в журнале.Сообщение об исключении: Неверное имя поля.{956a1078-ec35-4c04-83c4-0a3742119496} http://server/sites/mysite / sites / mysite / Списки / Записи

...