2009年4月23日,星期四

修复我的Config Store框架和列表设置提示

最近有一些关于我的问题的报告 配置存储 解决方案,它提供了一个使用SharePoint列表存储配置值的框架。如果您使用的是Config Store,那么您肯定会对本文感兴趣,但是我也从中获得了一些我想传递的关于列表配置的一般提示。我要感谢我以前的公司的Richard Browne(无博客) cScape,因为修复程序和一些技巧来自于他-并提醒我注意该问题,他还设法在我之前解决了该问题,非常感谢,也非常感谢队友:-)

配置存储问题

在某些情况下,“配置存储”列表中的字段不可编辑,因为它们不再出现在列表编辑表单(EditForm.aspx)中。因此,除了具有4个可编辑字段外,仅“ Config name”字段以以下形式显示:

ConfigStoreMissingFields

我还没有完全弄清楚模式,但是我 认为 仅当您在安装了10月或12月累积更新的服务器上配置列表时,才可能出现此问题-否则这是Windows 2003和Windows 2008环境之间的差异(这将更加奇怪)。无论哪种方式,似乎都改变了在某些地方处理XML的方式。这就是为什么在早期版本中未发现此问题的原因。

I 之前曾见过此问题-但仅在使用Content Deployment(例如,使用 内容部署向导)-原始的“来源”列表总是很好。我们设法通过编写一些代码将这些字段从内容类型“重新添加”到列表中来解决此问题,因为这些字段实际上始终出现在内容类型上,并且数据仍被纠正存储。每次我们部署列表时都必须运行此代码,这很烦人,而不是关键,但是我想深入了解-但是,在发现某些人以“正常”使用方式遇到此问题时,它变得更大了问题。

原因

我一直都知道问题将归结于配置XML中的一个错误,但是由于我在以前的场合中一直在寻找它,所以我知道这是我所看到但没有看到的东西。在我的案例中,Richard发现我在ContentType元素下的FieldRef元素中使用了错误的值-我错误地认为'Name'属性需要与为该字段赋予的'StaticName'属性匹配;文档说此属性包含字段的内部名称。所以我的FieldRefs看起来像这样:

<ContentType ID="0x0100E3438B2389F84cc3965600BC16BF32E7" Name="Config item" 
Group="Config Store content types" Description="Represents an item in the config store." Version="0">
<FieldRefs>
<FieldRef ID="{33F5C8B4-A6BB-41a4-AB24-69F2152974C5}" Name="ConfigCategory" Required="TRUE" />
<FieldRef ID="{BD413479-48AB-41f5-8040-918F32EBBCC5}" Name="ConfigValue" Required="TRUE" />
<FieldRef ID="{84D42C64-D0BD-4c76-8ED3-0A9E0D261111}" Name="ConfigItemDescription" />
</FieldRefs>
</ContentType>

..以匹配如下所示的字段:

<Field ID="{33F5C8B4-A6BB-41a4-AB24-69F2152974C5}"
Name="Config category"
DisplayName="Config category"

StaticName="ConfigCategory"
....
....
/>

CORRECTED版本如下所示(请注意FieldRefs的Name属性的值更改):


<ContentType ID="0x0100E3438B2389F84cc3965600BC16BF32E7" Name="Config item"
Group="Config Store content types" Description="Represents an item in the config store." Version="0">
<FieldRefs>
<FieldRef ID="{33F5C8B4-A6BB-41a4-AB24-69F2152974C5}" Name="Config category" Required="TRUE" />
<FieldRef ID="{BD413479-48AB-41f5-8040-918F32EBBCC5}" Name="Config value" Required="TRUE" />
<FieldRef ID="{84D42C64-D0BD-4c76-8ED3-0A9E0D261111}" Name="Config item description" />
</FieldRefs>
</ContentType>

因此,我从中学到的主要知识是要记住 FieldRef属性的“名称”必须与Field属性的“名称”匹配 -这么简单。为什么以前能奏效?不幸的是不知道。

但是,我还拾起了一些我不知道的东西,一部分来自Richard(这个家伙需要博客!),一部分来自其他阅读/实验。

有关列表配置的一些便利知识

  • 要使列表上的字段为必填字段,“ Required”属性必须为“ TRUE”。不是'True'或'true'-这是预配框架对于该6选择布尔值感到不安的情况之一;-)
  • FieldRefs至少需要一个ID和Name(必须与“ Field”声明中的值匹配),但是您可以在此处覆盖某些其他内容,例如DisplayName-这反映了UI中可能出现的情况。
  • 如果在schema.xml的“表单”元素中使用“设置路径”属性,则不必在功能中包括列表.aspx文件(DispForm.aspx,EditForm.aspx和NewForm.aspx)。无需关联自定义列表表单)。
  • 您可以使用“ ContentTypeRef”元素将您的内容类型与列表相关联(仅指定内容类型ID),而不是使用需要重新声明所有FieldRefs的“ ContentType”元素。
  • 从schema.xml的“字段”部分删除所有默认的“系统”字段是安全的

除了这些技巧之外,我发现的最好的是Oskar Austegard的 MOSS:可怕的schema.xml 显示了如何剥离 schema.xml中的内容。我还没有尝试过,但是我确信这将是我声明式提供的下一个列表的起点。如果您对列表设置的细节感兴趣,我强烈建议您阅读它。

快乐的XMLing

8条评论:

纳格帕勒元帅说过...

克里斯你好,
DEC CU之后,我们在配置和语言存储上也遇到了同样的问题...,并且通过从列表中删除配置内容类型并将其重新附加到浏览器列表中来解决了该问题。

安迪·伯恩斯(Andy Burns)说过...

很高兴知道,即使MVP也会在CAML模式上遇到问题!

关于第5点,是不是您不必包括从父内容类型继承的字段?因此,不是所有“系统”(来自“项目”内容类型或更高类型)的内容都是必需的,而是隐含的吗?

另外,您可以使用 ContentTypeBinding 将一个附加到列表的元素。

克里斯·奥'Brien说过...

@元帅,

有趣的是-认为这实际上是我们的代码解决方法所做的。假设这样做没有数据丢失?

似乎越来越多地表明,12月的CU可能“不太容忍”供应XML中的错误?

谢谢,

C。

附言很高兴看到您同时使用了Config Store和Language Store :-)下周左右,我将将此修补程序回传到Language Store,并发布新版本。

克里斯·奥'Brien说过...

@安迪

:-)

关于第5点,是的,我同意这是安全删除那些字段的原因-我应该在那儿更清楚一些。

有趣的是,您提出了ContentTypeBinding。我在其他领域中使用了此方法(例如,将内容类型与Pages库相关联)。不要以为我也可以在这里使用它。

哪一种让我想知道为什么该模式提供了两种执行同一操作的方式,但这可能导致整个“另一番讨论;-)

干杯,

C。

安迪·伯恩斯(Andy Burns)说过...

I 看了一下 出于好奇。似乎ContentTypeRef是用于您最初定义列表时使用的,而ContentTypeBinding是用于您以后要添加列表时使用的。

克里斯·奥'Brien说过...

有趣的:-)

因此,阅读您的文章后,我们得出结论,您可以使用 要么 如果在同一功能中部署列表+内容类型,则使用ContentTypeRef或ContentTypeBinding?

C。

安迪·伯恩斯(Andy Burns)说过...

我认为。虽然我不知道如果List没有为它定义* any *内容类型会发生什么。也许您必须至少具有一种ContentTypeRef的内容类型,但是以后可以绑定其他内容类型。

并且您还将在功能中需要一个ListInstance节点。因此,我认为您需要:

-您的内容类型的ContentType节点
-列表节点定义列表的类型
-在列表上创建ListInstance
-ContentTypeBinding,将内容类型附加到新创建的列表。

实际上,我想这突出了主要的区别-定义列表时ContentTypeRef连接内容类型,因此它已经预配,而ContentTypeBinding在列表存在后附加一个。

迈克尔·汉斯说过...

有趣的讨论。一世'我们发现ContentTypeRef和ContentTypeBinding都是所有东西都需要在一起的"properly":

http://blog.mediawhole.com/2009/11/contenttyperef-vs-contenttypebinding.html