解决办法:在场解决方案中替换 SharePoint 内容类型和网站栏

优采云 发布时间: 2022-09-24 06:04

  解决办法:在场解决方案中替换 SharePoint 内容类型和网站栏

  替换 SharePoint 内容类型和 网站字段解决方案中的列内容

  本文介绍了替换内容类型和 网站 列,将 网站 列添加到新的内容类型,然后使用 SharePoint 客户端对象模型 (CSOM) 将以前的内容类型替换为新的内容类型内容类型时间转换过程。

  重要

  您无法将场解决方案迁移到 SharePoint Online。通过应用本文中描述的技术和代码,可以构建一个使用更新的内容类型和 网站 列的新解决方案,并向您的场解决方案或声明性沙盒解决方案报告提供类似的功能。然后可以将此新解决方案部署到 SharePoint Online。

  使用本文中的代码需要额外的代码才能生成功能齐全的解决方案。例如,本文不讨论如何向 Office 365 进行身份验证,如何实现所需的异常处理等。有关其他代码示例,请参阅 Office 365 开发人员模式和实践项目。

  注意事项

  本文中的代码按原样提供,不提供任何明示或暗示的保证,包括对特定用途的适用性、适销性或不侵权的暗示保证。

  用 CSOM 替换内容类型和 网站列:

  创建一个新的内容类型。

  创建一个新的网站列(也称为字段)。

  向新的内容类型添加一个新的 网站 列。

  用新的内容类型替换旧的内容类型引用。

  在下面的代码中,Main 显示了将内容类型和 网站列替换为 CSOM 所需的操作序列。

  static void Main(string[] args)

{

using (var clientContext = new ClientContext("http://contoso.sharepoint.com"))

{

Web web = clientContext.Web;

CreateContentType(clientContext, web);

CreateSiteColumn(clientContext, web);

AddSiteColumnToContentType(clientContext, web);

// Replace the old content type with the new content type.

ReplaceContentType(clientContext, web);

}

}

  在下面的代码中,GetContentTypeByName 从当前的 网站 中获取内容类型:

  使用 Web.ContentTypes 属性获取 ContentType采集,它是当前在 网站 上的内容类型的集合。

  通过将 网站 内容类型名称与 name 参数提交的现有内容类型名称相匹配,从 网站 查找并返回内容类型。

   private static ContentType GetContentTypeByName(ClientContext cc, Web web, string name)

{

ContentTypeCollection contentTypes = web.ContentTypes;

cc.Load(contentTypes);

cc.ExecuteQuery();

return contentTypes.FirstOrDefault(o => o.Name == name);

}

  创建一个新的内容类型

  在以下代码中,CreateContentType 通过以下方式创建新的内容类型:

  创建一个名为 contentTypeName 的常量来存储内容类型的名称。新内容类型的名称将设置为先前内容类型的名称。

  调用 GetContentTypeByName 以在 网站 上查找匹配的内容类型。

  如果内容类型已经存在,则无需进一步操作,调用return时将控制权返回给Main。

  如果 content-type 不存在,则 content-type 属性将使用名为 newCt 的 ContentTypeCreationInformation 对象设置。

  新的内容类型 ID 将使用基础文档内容类型 ID 0x0101 分配给 newCt.Id。有关详细信息,请参阅基本内容类型层次结构。

  使用 ContentType采集.Add 添加新的内容类型。

  private static void CreateContentType(ClientContext cc, Web web)

{

// The new content type will be created using this name.

const string contentTypeName = "ContosoDocumentByCSOM";

// Determine whether the content type already exists.

var contentType = GetContentTypeByName(cc, web, contentTypeName);

// The content type exists already. No further action required.

if (contentType != null) return;

// Create the content type using the ContentTypeInformation object.

ContentTypeCreationInformation newCt = new ContentTypeCreationInformation();

newCt.Name = "ContosoDocumentByCSOM";

// Create the new content type based on the out-of-the-box document (0x0101) and assign the ID to the new content type.

newCt.Id = "0x0101009189AB5D3D2647B580F011DA2F356FB2";

// Assign the content type to a specific content type group.

newCt.Group = "Contoso Content Types";

ContentType myContentType = web.ContentTypes.Add(newCt);

cc.ExecuteQuery();

}

  

  创建一个新的网站列

  在下面的代码中,CreateSiteColumn 创建一个新的网站列:

  创建一个名为 fieldName 的常量来存储字段的名称。新字段的名称将设置为前一个字段的名称。

  使用 Web.Fields 属性获取在 网站 上定义的 网站 字段。

  通过将 网站 上的字段名称与 fieldName 匹配来查找 网站 上的匹配字段。如果该字段已经存在,则不需要进一步的操作,并且在调用 return 时将控制权传递回 Main。如果该字段不存在,则为 FieldAsXML 分配一个指定该字段架构的 CAML 字符串,然后使用 Field采集.AddFieldAsXml 创建该字段。

  private static void CreateSiteColumn(ClientContext cc, Web web)

{

// The new field will be created using this name.

const string fieldName = "ContosoStringCSOM";

// Load the list of fields on the site.

FieldCollection fields = web.Fields;

cc.Load(fields);

cc.ExecuteQuery();

// Check fields on the site for a match.

var fieldExists = fields.Any(f => f.InternalName == fieldName);

// The field exists already. No further action required.

if (fieldExists) return;

// Field does not exist, so create the new field.

string FieldAsXML = @"";

Field fld = fields.AddFieldAsXml(FieldAsXML, true, AddFieldOptions.DefaultValue);

cc.ExecuteQuery();

}

  向新的内容类型添加新的网站列

  在以下代码中,AddSiteColumnToContentType 通过以下方式在内容类型和字段之间创建关联:

  使用 ContentType.FieldLinks 属性加载内容类型,然后加载该内容类型中的字段引用。

  加载字段。

  使用 contentType.FieldLinks.Any(f => f.Name == fieldName) 匹配字段名称以确定内容类型是否引用该字段。

  如果内容类型已经引用了该字段,则不需要进一步的操作,并且在调用 return 时将控制权传递回 Main。如果内容类型不引用字段,则在 FieldLinkCreationInformation 对象上设置字段引用属性。

  将 FieldLinkCreationInformation 对象添加到 ContentType.FieldLinks 属性。

  private static void AddSiteColumnToContentType(ClientContext cc, Web web)

{

// The name of the content type.

const string contentTypeName = "ContosoDocumentByCSOM";

// The field name.

const string fieldName = "ContosoStringCSOM";

// Load the content type.

var contentType = GetContentTypeByName(cc, web, contentTypeName);

if (contentType == null) return; // content type was not found

// Load field references in the content type.

cc.Load(contentType.FieldLinks);

cc.ExecuteQuery();

// Load the new field.

Field fld = web.Fields.GetByInternalNameOrTitle(fieldName);

cc.Load(fld);

cc.ExecuteQuery();

// Determine whether the content type refers to the field.

var hasFieldConnected = contentType.FieldLinks.Any(f => f.Name == fieldName);

// A reference exists already, no further action is required.

if (hasFieldConnected) return;

// The reference does not exist, so we have to create the reference.

FieldLinkCreationInformation link = new FieldLinkCreationInformation();

link.Field = fld;

contentType.FieldLinks.Add(link);

contentType.Update(true);

cc.ExecuteQuery();

}

  

  用新的内容类型替换旧的内容类型引用

  在以下代码中,ReplaceContentType 检查所有库中的所有项目,查找引用旧内容类型的内容,并通过以下方式将这些引用替换为新内容类型 (ContosoDocumentByCSOM):

  将旧的内容类型 ID 分配给一个常量。

  使用 GetContentTypeByName 获取新的内容类型。

  使用 Web.Lists 获取 网站 上的所有列表。

  使用 cc.Load(lists, l => l.Include(list => list.ContentTypes) 加载 网站 上的所有列表以及每个列表的所有内容类型。

  对于每个返回的列表,使用 list.ContentTypes.Any(c => c.StringId.StartsWith(oldContentTypeId)) 在列表中搜索内容类型,将内容类型与旧的内容类型 ID 匹配。如果找到匹配项,则会将收录旧内容类型的列表添加到 listsWithContentType。

  对于 listsWithContentType 中的每个列表:

  确定是否已将新内容类型附加到列表中。如果新内容类型未附加到列表中,请使用 ContentType采集.AddExistingContentType 将新内容类型附加到列表中。

  获取列表中的所有列表项。

  对于每个列表项,获取列表项的内容类型 ID。确定列表项的内容类型 ID 是否与旧的内容类型 ID 相同。如果不同,请跳至下一个列表项。如果相同,请使用 ContentType.StringId 为列表项分配新的内容类型 ID。

  注意事项

  旧的内容类型仍在列表中,但这些类型不再可用。旧的内容类型现在可以从列表中删除并撤回。本文介绍如何仅替换文档内容类型。要覆盖页面布局上的内容类型,请务必更新 网站set 中每个页面布局的 AssociatedContentType 属性。

  private static void ReplaceContentType(ClientContext cc, Web web)

{

// The old content type.

const string oldContentTypeId = "0x010100C32DDAB6381*敏*感*词*4868DCD5AD*敏*感*词*A5307D6";

// The new content type name.

const string newContentTypeName = "ContosoDocumentByCSOM";

// Get the new content type and lists on the site.

ContentType newContentType = GetContentTypeByName(cc, web, newContentTypeName);

ListCollection lists = web.Lists;

// Load the new content type and the content types on all lists on the site.

cc.Load(newContentType);

cc.Load(lists,

l => l.Include(list => list.ContentTypes));

cc.ExecuteQuery();

var listsWithContentType = new List();

foreach (List list in lists)

{

bool hasOldContentType = list.ContentTypes.Any(c => c.StringId.StartsWith(oldContentTypeId));

if (hasOldContentType)

{

listsWithContentType.Add(list);

}

}

foreach (List list in listsWithContentType)

{

// Determine whether the new content type is already attached to the list.

var listHasContentTypeAttached = list.ContentTypes.Any(c => c.Name == newContentTypeName);

if (!listHasContentTypeAttached)

{

// Attach content type to list.

list.ContentTypes.AddExistingContentType(newContentType);

cc.ExecuteQuery();

}

// Get all list items.

CamlQuery query = CamlQuery.CreateAllItemsQuery();

ListItemCollection items = list.GetItems(query);

cc.Load(items);

cc.ExecuteQuery();

// For each list item, determine whether the old content type is used, and then update to the new content type.

foreach (ListItem listItem in items)

{

// Get the current content type for this list item.

var currentContentTypeId = listItem["ContentTypeId"] + "";

var isOldContentTypeAssigned = currentContentTypeId.StartsWith(oldContentTypeId);

// This item does not use the old content type - skip to next list item.

if (!isOldContentTypeAssigned) continue;

// Update the list item content type to the new content type.

listItem["ContentTypeId"] = newContentType.StringId; // new content type Id;

listItem.Update();

}

// Save all changes.

cc.ExecuteQuery();

}

}

  另见

  技巧:提升网站有效收录的seo技术操作方法有哪些

  网站 会产生很多 URL,但并不是每个 URL 都对 SEO 有帮助。比如对于很多不必要的URL链接,要进行一系列特殊的seo技术操作,保证搜索引擎抓取、索引和收录到对网站本身更有价值的页面内容,今天,wp自学笔记和朋友的题目是提高网站有效收录seo技术操作方法。

  改进网站有效收录的含义是控制搜索引擎抓取网站内容并对其进行索引的方式。下面以谷歌搜索引擎为例进行详细分析:

  请确保 Google 可以访问 Google 打算抓取的所有资源(图片、CSS 文件等)或网页;也就是说,它们不会被任何 robots.txt 规则阻止并且可供匿名用户访问。无法访问的页面不会出现在索引覆盖率报告中,但会显示为未被 URL 检查工具抓取。被阻止的资源只会在 URL 检查工具中显示为特定于 URL 的资源。如果页面上的重要资源被阻止,这可能会阻止 Google 正确抓取您的页面。使用 URL 检查工具呈现实际页面,以验证 Google 看到的页面是否符合您的预期。

  使用 robots.txt 规则防止抓取,并使用站点地图提供帮助。您可以阻止 Google 抓取 网站 中的重复内容或不太重要的资源(例如常用的小图片,如图标或徽标),以避免服务器因请求而过载。请勿使用 robots.txt 作为阻止 Google 将内容编入索引的机制;为此目的使用 noindex 或登录要求。详细了解如何阻止 Google 访问您的内容。

  网站地图

  站点地图是告诉 Google 哪些页面对您的 网站 很重要,以及提供其他信息(例如更新频率)并且对于抓取非文本内容(例如图像或视频)有用的重要方式) 也很重要。虽然 Google 不会只抓取站点地图中列出的页面,但它会首先抓取这些页面。这对于内容随时间变化或可能无法通过链接发现的 网站 页面尤其重要。使用站点地图有助于 Google 发现 网站 上的抓取页面并确定其优先级。单击此处了解有关站点地图的更多信息。

  国际化网站或多语言网站

  如果您的 网站 收录多种语言,或针对特定地区的用户,请注意以下几点:

  了解多区域和多语言网站,获取有关如何管理不同语言或区域的网站本地化内容的高级建议。

  

  使用 hreflang 告诉 Google 网站页面的不同语言版本。

  如果 网站 将其页面内容调整为所请求的语言环境,请了解这会如​​何影响 Google 抓取 网站 的方式。

  如果 网站使用 gTLD(.com、.org)而不是基于区域设置的 TLD(.ch、.in),您可以告诉 Google 将搜索结果定位到哪些国家/地区。

  迁移页面或网站

  如果您可能需要迁移单个 URL 或整个 网站,请遵循以下准则:

  迁移单个 URL

  如果您要将网页永久移动到其他地址,请记住为您的网页实施 301 重定向。如果由于某种原因迁移只是暂时的,请返回 302 告诉 Google 它应该继续抓取您的网页。

  您可以创建自定义 404 页面,以便在用户请求的页面已被删除时提供更好的体验。当用户请求的页面不再存在时,请确保返回真正的 404 而不是软 404。

  迁移网站

  如果您要迁移整个 网站,请实施所有必需的 301 和站点地图更改,然后让 Google 了解迁移情况,以便我们开始抓取新的 网站 并将您的信号转发到新 < @网站。了解如何迁移 网站。

  最佳实践

  

  确保链接可抓取。如果链接是带有 href 属性的标签,Google 只能跟踪它们。 Google 的抓取工具不会跟踪使用其他格式的链接。 Google 无法跟踪缺少 href 标记的链接,也无法跟踪由于脚本点击事件而导致标记作为链接执行时出现问题的其他链接。

  对付费链接、需要登录的链接或不受信任的内容(例如用户提交的内容)使用 rel=nofollow,以避免向他们发送良好的信号,或让他们的劣质影响到您。

  管理抓取预算:如果您的 网站 很大(有数亿页定期更改,或数千万页频繁更改),Google 可能无法抓取整个 网站。因此,您可能需要向 Google 指明 网站 上最重要的页面。目前执行此操作的最佳机制是在站点地图中列出最近更新或最重要的页面,并(可能暂时)使用 robots.txt 规则隐藏不太重要的页面。

  基于 AJAX网站:如果您 网站 使用 AJAX,请详细了解 Google 如何抓取 AJAX 页面。

  JavaScript 使用:查看 Google 对 网站 JavaScript 的建议。

  多页文章:如果您的文章 被分成多个页面,请确保您有用户可以点击的下一页和上一页链接(这些是可抓取的链接)。您只需执行此操作,Google 就可以抓取此类页面。

  无限滚动页面:谷歌可能无法滚动浏览无限滚动页面;如果要使页面可抓取,则应提供分页版本。详细了解易于搜索、无限滚动的网页。

  阻止访问更改状态的 URL,例如您可以发布评论、创建帐户、将商品添加到购物车或执行其他操作的网页 URL。使用 robots.txt 阻止这些 URL。

  查看可供 Google 索引的文件类型列表。如果您的文件类型无法被原生抓取,请确保它链接到相应的描述文本,或者(视频、图片或播客提要)在站点地图中提供元数据。

  如果 Google 似乎过于频繁地抓取您的 网站(这不太可能),您可以放慢您的 网站 抓取速度。但是,这种情况很少见。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线