风中的猪儿

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  9 随笔 :: 0 文章 :: 26 评论 :: 3 Trackbacks

2008年6月24日 #

最近一直和infopath表单打交道,碰到的问题也比较多,刚刚就碰到一个在程序中修改infopath表单中域的内容时出错的问题,写出来与大家共享一下,我想这个问题,可能玩infopath的话,迟早会碰上的吧。
具体表现就是在代码中对一些值类型的域进行更改的时候,代码报错,出错信息:"Schema validation found non-data type errors."
小弟对xml schema真的不是很了解,所以找了半天,最后总算在infopath team blog上找到标准答案
文章地址:http://blogs.msdn.com/infopath/archive/2006/11/28/the-xsi-nil-attribute.aspx
 

xsi:nil属性

你是否曾经在程序中设置域值时碰到schema valiadation错误?很多时候这个错误的原因是节点定义了“nillable”属性. Nillable属性是一个特殊的属性,它能出现在一个XML schemaxsd:elment.如果一个元素定义了xsi:nil属性,意味着这个元素被定义了,但是没有值,因此它是没有内容的。

然而,如果你试图在程序中给一个定义了nillable属性的节点设置值,你会得到一个错误信息:“Schema validation found non-data type errors.”。你可能会发现nillable属性常被定义在下面几种数据类型上:

  • Whole Number (integer)
  • Decimal (double)
  • Date (date)
  • Time (time)
  • Date and Time (dateTime)

要解决这个问题,你的代码需要先检测nil属性是否被定义了。如果定义了,那需要在给节点设置值之前移除这个属性。下面这段简单的程序使用一个XpathNavigator类,检查节点的node是否有nil属性。如果存在则删除掉。

public void DeleteNil(XPathNavigator node)
{
if (node.MoveToAttribute("nil""http://www.w3.org/2001/XMLSchema-instance"))
      node.DeleteSelf();
}


上面这段代码是通用的,你能很简单的调用这段代码在你需要编程改变一个域的值之前。下面是一个例子,这段代码被一个按钮的click事件调用。

//Create a Navigator object for the main data source
// 为主数据源创建一个Navigator对象
XPathNavigator xn = this.MainDataSource.CreateNavigator();

//Create a navigator object for the field (node) 
//where we want to set the current date value
// 为你要设置当前日期值的一个域(节点)创建一个navigator对象
XPathNavigator xnfield1 = xn.SelectSingleNode("/my:myFields/my:field1"this.NamespaceManager);

//Check if the "nil" attribute exists on this node
// 检查节点是否存在 “nil”属性
DeleteNil(xnfield1);

//Create a new dateTime object for the current date
// 创建一个包含当前日期的新的dateTime对象
DateTime curDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day);

//Set the value of field1 to the current date in the 
//correct format: yyyy-mm-dd
// 设置field1的值为使用”yyyy-mm-dd”格式的当前日期
xnfield1.SetValue(curDate.GetDateTimeFormats().GetValue(5).ToString());


posted @ 2008-06-24 14:20 风中的猪儿 阅读(127) | 评论 (0)编辑

2008年5月20日 #

下午公司需求人员和我说需要文档要带条码,心想这个还不简单,直接文档库设置-》信息管理策略设置-》定义策略-》把条码勾上。简单搞定~~~
然后在视图里把条码值和条码图形勾上,效果出来了。叫需求人员过来看一下,结果他提了一个需要自己传入条码值生成条码的需求,咱想,这还不简单,查一下Field,果然有个叫_dlc_BarcodeValue的field值,里面保存着条码值呢,修改他,update一下,刷新页面,傻了,只有条码值变了,条码图像并没有改变。这下犯难了,接着查Field,里面还有一个_dlc_BarcodePreview,和_dlc_BarcodeImage的属性,其中_dlc_BarcodeImage里存的是一个图片,显示出来的string全是乱七八糟的二进制的东西,看来这三个field都需要更改了,难道要我自己生成一个条形码的image然后存进去?

在GOOGLE上翻半天也没有什么结果。最后翻SDK,WSS SDK里还没有,是在Office sharepoint server文档中找到一个Barcode类,它有两个静态方法ProvisionBarcode 和ProvisionBarcodeWithValue 。

第一个方法是为SPListitem重新生成一个条形码值和图片,条码值是随机生成的,而第二个是按指定的条码值生成条码。
两个方法使用非常简单,我代码都不贴了,直接把参数贴出来吧
public static void ProvisionBarcode (
    SPListItem spListItem,
    
bool fOverwrite,
    
out string strValue,
    
out Image imBarcode
)
public static void ProvisionBarcodeWithValue (
    SPListItem spListItem,
    
bool fOverwrite,
    
ref string strValue,
    
out Image imBarcode
)

两个方法参数基本上一样
spListItem
需要重新生成的SPListItem。
fOverwrite
是否要覆盖当前的条码值(显然是要设成true)
strValue
条码值(这里注意一下,ProvisionBarcode 加上了out,意味着你传的这个strValue不需要初始化,方法完成后,这个strValue被赋了新的条码值,而ProvisionBarcodeWithValue使用的是ref,这要求你传入一个条码值,strValue必须先赋值,方法会按你传入的条码值生成图片等信息,还有,条码值是一个长度为10的字符串)
imBarcode
条码图像的Image对象。加上了out,不需要初始化。


乱七八糟的研究了点小东西……
posted @ 2008-05-20 16:40 风中的猪儿 阅读(318) | 评论 (3)编辑

2008年5月15日 #

 

有天无意之中翻SDK里的Technical Articles,发现一篇好文章,受启发,于是实验了一下,果然成功了

我们都知道我们自己开发的custom field,在word2007里的服务器属性中会显示为一个灰色的不可修改的文本框,提示你没办法在客户端进行编辑。通过此方法,可以自定义在word2007里的显示方式,当然,不能超过infopath定义的那几个控件。


 

步骤:

首先你总得有个custom field吧,要是不会,先学学custom field 再回来……我这里自己做了一个继承自SPFieldTextcustom field

首先进入网站设置,网站栏



添加一个cutom field,起个名字

   

再进入网站内容类型里

创建一个新的网站内容类型

 

父类型选:文档内容类型。父内容类型选择文档,确定。




 

接着,我们给这个网站内容类型添加一个栏,默认它只有一个标题



 

我们把我们的custom field添加进去



 

完了后,再在网站内容类型里点击“文档信息面板设置”,打开后,选择新建自定义模板




 

这时候,会自动打开你的infopath2007(一定要装了infopath 2007啊),打开后的表单是不是很熟悉?嘿嘿,就是在word2007里显示的那一块,不是么。接着,咱想怎么改就怎么改啦。




 

打开右边数据源,我们ns2:myField保存的就是咱们的自定义栏的内容了




 

把刚才那看着不爽的要求我们去服务器端修改的提示去掉,换上我自己的下拉菜单,双击可以编辑下接菜单的列表项(好像还可以用其它数据源的,没有试了,大家有兴趣可以试试)。还有一点就是这个模板是不能自己再建域的,这个会有提示。OK,手动输入几个列表框项,保存表单




 

接着发布,发布完了就完成了。接下来去一个文栏列表中,把网站内容类型改成我们刚才自定义的内容类型。





 

什么?不知道改?具体部骤不抓图了,好麻烦,文档库的设置里面-》高级设置-》是否允许管理内容类型?改为“是”,确定返回设置页。这时候下面的内容类型就可以修改了,点击“从现在网站内容类型添加”,加入咱刚才定义的那个 myContentType。确定返回设置页,再点击“更改新建按钮的顺序和默认内容类型,把文档那个类型的可见小勾去掉,确定返回,回到文栏库,新建一个myContentType类型文档,或是打开现有文档,HOHO,我们要的就出来了

posted @ 2008-05-15 16:11 风中的猪儿 阅读(402) | 评论 (1)编辑

2008年3月4日 #

 

要在MOSS中使用RMS,具体设置可以参考微软的文档,非常详细,下载地址

http://www.microsoft.com/downloads/details.aspx?FamilyID=7bab2321-71e6-4cf2-8bcd-0880e0d1cda3&DisplayLang=en

文档中用了三台服务器,一台AD服务器,一台MOSS服务器和一台RMS服务器,我的电脑较慢,不可能开三个虚拟机,所以全装在一台机器上,实践证明,也是可以的。

RMS部署的时候,如果有疑问,可以参考一篇叫《RMS部署实战》的文章,每一步都有截图,非常详细

 

最后一点我碰到的问题就是按微软的文档,在MOSS管理中心设置RMS的时候选择"使用在 Active Directory 中指定的默认 RMS 服务器"项,点确定后出现"所需的 Windows Rights Management Client 存在,但无法正确配置。正确配置 WRM Client 之前,IRM 将不会运行。"

让我郁闷了好半天,删掉RMS重装还是一样。在网上搜到一篇讨论这个问题的贴子,按上面的做了也没有解决问题 ,但是你也可以试一下,说不定就能解决问题。

最后自己摆弄半天,解决的办法是如下

先在RMS管理站点中,进入“Extranet 群集的 URL 设置”设置一个URL

然后在MOSS管理中心设置RMS的时候,不选使用“Active Directory 中指定的默认 RMS 服务器”项,而选择第三项,指定的服务器项,然后把刚刚在RMS中设置的那个URL填上去(不要加后面的/_WMCS),确定,搞定。

posted @ 2008-03-04 09:16 风中的猪儿 阅读(266) | 评论 (3)编辑

2008年2月28日 #

朋友向我索要SDK时,我直接发网址给他,让他自己下载,结果发现SDK前天刚更新
做了一些改进,安装的时候,可以选择安装目录了
同时,还增加了不少samples,特别是增加了search samples,这是原来没有的
不错,马上下载看看

有兴趣的朋友去看看吧

http://www.microsoft.com/downloads/details.aspx?familyid=6D94E307-67D9-41AC-B2D6-0074D6286FA9&displaylang=en

posted @ 2008-02-28 10:04 风中的猪儿 阅读(79) | 评论 (0)编辑

2008年1月28日 #

好久以前写着玩的,今天从邮箱里翻出来的时候都有点认不得自己写的代码了,当时写出来自己还得意了一番。。。结果刚才运行就出现错误,赶紧修改一下……果然还是一个半成品啊……不过,给有兴趣的朋友看看吧


代码下载
posted @ 2008-01-28 10:45 风中的猪儿 阅读(107) | 评论 (0)编辑

2008年1月18日 #

  我们知道MOSS里所有的栏类型都是从SPField类继承过来的,在新建栏的类型中有项默认类型的叫做数字,我们需要的也是一个只读的数字栏,所以我们就拿这个开刀了。

翻开SDK文档,这个数字栏的类型是SPFieldNubmer,它还派生出一个SPFieldCurrency类,我们也派生出一个类,就叫ReadOnlyCountField。

本来我想做一个完整的自定义Field的,可是最近一直忙,上次写了一半的不小心被我删了,偷个懒,就用这种简单的方法实现。

新建一个项目ReadOnlyCountField。然后添加一个ReadOnlyCountField.cs文件,加入以下内容

public class ReadOnlyCountField : SPFieldNumber
    
{
        
public ReadOnlyCountField(SPFieldCollection fields, string fieldName)
            : 
base(fields, fieldName)
        
{
            
this.ShowInEditForm = false;
            
this.DefaultValue = "0";
        }

        
public ReadOnlyCountField(SPFieldCollection fields, string typeName, string displayName)
            : 
base(fields, typeName, displayName)
        
{
            
this.ShowInEditForm = false;
            
this.DefaultValue = "0";
        }

        
public override BaseFieldControl FieldRenderingControl
        
{
            
get
            
{
                BaseFieldControl control 
= new NumberField();
                control.FieldName 
= base.InternalName;
                
return control;
            }

        }

    }


 

我翻看SDK文档发现Field有一个ShowInEditForm属性,我本来以为在设置里有的,就不用弄这个只读字段了,可是我找了半天也没有找到,于是就想到派生出一个新类,在构造函数中将此值改为false。所以这个文件我们唯一要做的就是在构造函数设置一下这个值的默认值了。简单吧~~还有我们还重载了一个FieldRenderingControl方法,这个方法返回一个显示字段的control,这个control类继承BaseFieldControl类,如果要自定义一个Field的话,就需要自己写一个派生自BaseFieldControl类的control控件。这个网上教程很多了。翻看SDK文档就会发现每个MOSS内置的Field都会有个与之对应的control

 

再添加一个fldtypes_ReadOnlyCountField.xml文件


<?xml version="1.0" encoding="utf-8" ?>
<FieldTypes>
  
<FieldType>
    
<Field Name="TypeName">ReadOnlyCountField</Field>
    
<Field Name="ParentType">Number</Field>
    
<Field Name="TypeDisplayName">只读数字</Field>
    
<Field Name="TypeShortDescription">不可修改的只读数字</Field>
    
<Field Name="UserCreatable">TRUE</Field>
    
<Field Name="ShowInListCreate">TRUE</Field>
    
<Field Name="ShowInSurveyCreate">TRUE</Field>
    
<Field Name="ShowInDocumentLibraryCreate">TRUE</Field>
    
<Field Name="ShowInColumnTemplateCreate">TRUE</Field>
    
<Field Name="ShowInEditForm">FALSE</Field>
    
<Field Name="FieldTypeClass">ReadOnlyCountField, ReadOnlyCountField, Version=1.0.0.0, Culture=neutral, PublicKeyToken=239ba512823b3816</Field>
  
</FieldType>
</FieldTypes>

 

这个文件一定要以fldtypes开头,后面的就随便了,这里面定义了一个我们这个自定义属性的类型。如果你有兴趣对MOSS里的Field有兴趣,可以查看\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\XML下面的FLDTYPES.XML文件,一定不要修改哈……出了问题就麻烦了

还有就是<Field Name="FieldTypeClass">里的值,第一个为带命名空间的类名,第二个为程序集,最后一个PublicKeyToken=后面是强名称的key值,需要按下一步建立强名称编译后才能知道。可用Reflector打开编译好的dll来查看。

 

给项目建立强名称,就是项目属性里签名,把为程序集签名勾上,再新建一个KEY,把密码保护去掉(用不上),编译后,就差部署了

 

新建一个文本文件,起名叫Install.bat,输入以下内容

"%programfiles%\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil.exe" -uf ReadOnlyCountField
"%programfiles%\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil.exe" -if bin\Debug\ReadOnlyCountField.dll

copy 
/Y fldtypes_HitsCountField.xml "%CommonProgramFiles%\Microsoft Shared\web server extensions\12\TEMPLATE\XML\"

iisreset
 

运行这个batOK,部署完毕,去新建栏去看看,是否有“不可修改的只读数字”一种类型可以选了。


posted @ 2008-01-18 09:37 风中的猪儿 阅读(90) | 评论 (2)编辑

2008年1月7日 #

     摘要: 参考《MOSS中文档点击率统计的实现方法》一文,具体出处不太清楚,在网上搜到的,都没有标明出处或是原著,我也就不给出链接了,大家可以自己去搜一下。我按文中方法实现不成功,按照文中思路重新新写了一遍,原文中是通过修改Global.asax文件我发现这样没法调试(至少我这里没法调试,我这里总有点问题样的,工作流也没法附加进程调试,哪位高手能指定我一下为什么),于是改用HttpModule的方式,即可以... 阅读全文
posted @ 2008-01-07 10:32 风中的猪儿 阅读(1403) | 评论 (17)编辑