在MOSS中实现自动上传图片

我经常会被问到这么两个问题:

  • 在MOSS中,我们是否能换掉那个多行文本输入框默认的html编辑器?
  • 在多行文本输入框的html编辑工具栏中,插入图片那个按钮是否能让我将本地的图片上传到服务器上?

    我也不太清楚为什么,这两个问题我确实被问了无数遍,我每次都会回答:可以,没有问题。然后天马行空的说 一些我的想法,结果很多人还是没有搞清楚。恰好现在我也希望我的讨论区有图片上传的功能,昨天晚上就开始真正 的去实现这么一个文件上传。

    我在本文中,就具体的谈一谈,我们应该如何去实现它,并且阐述一下MOSS自身的一些机理。

    我做了一个小例子,大家可以先看一下,当然大家也可以从 http://www.oceanstudio.net/Lists/SharePoint3/AllItems.aspx这里直接看到我做的例子,为了防止机器人在我的讨论区灌水,本讨论区是需要注册登录才能发帖子的。我是贴图大王,大家先看贴图:

    首先,当我们点击“插入图片”按钮后,弹出了对话框,为了实现文件上传功能,我直接替换掉了这个对话框。

    这个对话框有两个功能,第一个就是原先的功能,你可以自己填写url,第二个功能就是你可以选择上载,然后通过uploadfile 控件,选择一个文件。在这里,我选择了我桌面上的一个图片文件,这个文件也是我的网站海洋工作室的logo。

    点击上传按钮,这个时候会显示上载成功。然后我们就可以点击确定按钮了。

    点击了确定按钮之后,我们可以看到,这个logo图片已经显示在多行文本区了。

    这是我们点击确定后,新建的一个帖子,图片能够正确的在web页面上显示出来。现在大家发帖子,就可以将自己的错误 信息截图直接贴到正文里,而不需要像以前那样添加到附件里面那么麻烦了。

    我们看一下这个图片的属性,这个图片显示的路径是:http://www.oceanstudio.net/Lists/SharePoint3/_ocean_upload/12861814871598000-logo.jpg, logo.jpg是这个文件的原文件名,为了防止文件名冲突,我直接在文件名前面加了一个时间戳。

    我终于过完了贴图瘾,下面我们就谈谈我们如何来做,大家觉得很奇怪,既然我从昨天晚上才开始想起来做,几个小时就做完了, 连blog都写出来了,这么简单的东西,SharePoint产品组干吗不直接加上这个功能?毕竟这是一个很实用的功能。

    我认为这个主要在于几点:

  • 最严重的问题,上传的图片存放在什么位置?这实际上是个很严重的问题,因为大家会发现我做的例子,当你的项目还没有 添加的时候,图片就已经上传到服务器上了。我是自己定了一个位置,位于列表的_ocean_upload目录,这个目录是我自己建立的。 但是很明显开发组不能这么干,因为如果我关闭了浏览器,那么这个上传上去的图片就永远存在与服务器上了,那么作为一个产品 来说,这是不能忍受的。而对于我们一个具体的解决方案,可以具体情况具体分析,我可以存放在任何位置,只要我觉得合适就可以。
  • 权限问题,MOSS的每个项目都是可以有单独权限的,而很明显项目里面的内容,如果有图片的话,那么这些图片的权限 也应该跟随项目的权限,而像我这样直接放在一个统一的目录里面,就等于凡是能阅读这个列表库的,就都能看到这些图片,图片的权限就无法 和具体的每一个栏目挂钩了。
  • 有人会说,那为什么不像附件一样呢?我们说附件,虽然你选择了附加文件,但是这些文件是当你点击确定,添加整个项目的时候 才会上传的,而不是事先传上去的。如果我们不事先上传图片,那么图片的位置就只能用一个统一的占位符来表示,而无法在编辑的时候直接预览, 我想这也是这个方案的一个问题。

    开发组可能考虑了还要多的东西,最终没有将这个功能加入进来,SPS2003没有,MOSS2007也同样没有。

    但是,我们却可以进行扩展,MOSS是个很灵活的架构,在MOSS的平台上进行开发,你会觉得非常的优雅,因为MOSS确实是一个非常优秀的开发平台。

    首先我们从原理开始讲起,第一个问题,我们能否替换掉那个Html编辑器?这个答案是没有问题,方案有二

  • 1:我们直接通过MOSS2007的自定义字段类型的特性,直接开发一个新的字段类型,这时UI是我们自己控制的,我们可以直接嵌入一个我们想要的HTML编辑器,这也是 最省时省力的方案。然后在需要用到的地方,建立这个新类型的字段就可以了。
  • 2:有人较真,说我就想改掉它自带的,而不是新建一个类型,那实际上就复杂了,我们就需要研究一下MOSS是如何做的了。

    我们知道,在MOSS里面,多行文本有三种形式,简单型,RTF型和增强RTF型。我们真正要动手的,实际上就是这个RTF型和增强RTF型。那么 在你新建或者编辑项目,含有这些类型的字段时,MOSS是如何做的呢?

    MOSS首先输出一个textarea标签,这个标签是多行文本框,然后紧随其后,它会调用一个JavaScript函数:RTE_ConvertTextAreaToRichEdit(),这个函数的定义如下:

      function RTE_ConvertTextAreaToRichEdit(
    strBaseElementID,
    fRestrictedMode,
    fAllowHyperlink,
    strDirection,
    strWebLocale,
    fSimpleTextOnly,
    fEditable,
    fUseDynamicHeightSizing,
    iMaxHeightSize,
    iMinHeightSize,
    strMode,
    urlWebRoot,
    strThemeUrl,
    strBodyClassName,
    fAllowRelativeLinks,
    strBaseUrl,
    fUseDynamicWidthSizing,
    iMaxWidthSize,
    iMinWidthSize,
    fEnforceAccessibilityMode,
    fPreserveScript,
    fHookUpEvents,
    fGenerateToolbar
    )
    

    其中第11个参数是strMode,这个参数为"FullHtml"时,就是增强的RTF类型,如果是Compatible,就是普通RTF类型。那么这个函数在哪儿呢? 它位于C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\LAYOUTS\2052下的FORM.JS ,这个路径是默认安装的路径,如果是英文版,就把2052换成1033(下同)。然后我们就可以打开FORM.JS看看这个函数是如何实现的。这个文件比较 长,差不多有6000行,好在没有进行任何混淆,版式也很规整,所以读起来并不难。通过阅读源代码,我们知道它在页面生成了一个IFrame,我们 所编辑的所有内容,都会被存到这个IFrame里面,并且使用RTE_TransferIFrameContentsToTextArea这个函数把IFrame里面的内容显示到 TextArea里面。所以实际上如果我们要替换编辑器的话,我们只要重新写这个函数就可以了,我们可以重写这个函数,输出我们自己的html编辑器, 只要最终在保存之前,我们把我们的html编辑器里面的内容存到这个TextArea里面就可以了。

    当然替换一个htmleditor实在是不划算的事情,因为自己写一个htmleditor很复杂,当然如果有现成的并且免费的html editor也不错。 不过我想大多数人,都希望修改原来的editor,比如增加个按钮什么的,这个也是可以做到的。因为在RTE_GetCompatibleToolBarDefinition 和RTE_FullHtmlToolBarDefinitionFactory这两个函数里面,定义了toolbar里面的按钮,我们只要在这里面增加新的按钮即可。

    下面就回到了第二个问题,如果我仅仅是希望添加图片的时候,让图片具有上传的功能,我该如何做呢?当点击了html编辑工具栏的“插入图片” 按钮后,调用了RTE_ModalDialog这个函数,在这个函数里面,弹出了那个对话框,这个对话框默认是/_layouts/RteDialog.aspx,因为MOSS 是不提供源代码的,所以改写RteDialog.aspx困难一点,我所采用的方法,就是重新写一个对话框。并且在这个对话框里面实现文件上传的功能。

    在写之前,我们要考虑一个问题,就是上传的图片放在什么地方?我想有下面几个地方:

  • 1:放在磁盘目录里面,并且这个磁盘目录能够在web上访问到,这种方式最简单,因为直接脱离了MOSS,我们的代码里面也不需要对MOSS进行任何操作了。 缺点就是完全脱离了MOSS,当我对我的网站进行备份时,我需要单独为磁盘上的这些图片备份。而且权限系统完全脱离了MOSS的管辖。
  • 2:放在MOSS的某个文件夹中,如果我们一个MOSS公共文件夹里面,有点就是当我备份站点时,这些图片会被一同备份。缺点是所有的图片都在一个文件夹里面, 会比较乱,而且权限无法区分清楚。
  • 3:放在各自的列表的某个文件夹里面,我的那个例子就是采用的这个方法,比如那个SharePoint讨论区,列表的名字是"SharePoint3",上传图片就会 放到对应的"SharePoint3/_ocean_upload"这么一个目录里面,第二种方法是一个网站对应一个目录,现在这种方法是一个列表对应一个目录。这个好处就是 当你删除列表时,图片也会一并被删除。权限也限制到了列表级,也就是拥有列表读权限的就能访问。缺点是权限仍然没有和某一个具体的项目挂钩。
  • 4:图片放到相应的项目所对应的目录下,我们知道如果列表允许附件,那么所有附件都会放在Attachment这个目录里面,并且在这个目录里面根据项目的id 分子目录,附件则放在对应项目的子目录里面,这样的好处就是当某个项目删除后,图片也立即删除了。但是要实现这个还是有一定问题的。主要就在与新建项目时, 还不知道新建的项目的id,这个时候先上传图片根本不知道放在什么地方,所以最终我采用了第三个方案。

    还有一个问题就是,我们的web application放在什么地方?很多文章都讲我们要放在_layouts下面,实际上,我们放到任何位置都可以,我 放的位置是/OceanFileUpload,大家从截图上就能看到。/OceanFileUpload是我在IIS下建立的虚拟应用,这个虚拟应用只要在MOSS的 站点下就可以使用MOSS的上下文。

    这个文件具体怎么上传我就不细讲了,因为在asp.net2.0里面,文件上传实在太容易了,有自带的FileUpload控件。当点击了上载按钮后,就把上传的 文件存到MOSS里面,讲文件存到MOSS里面,我们可以使用public SPFile Add(string urlOfFile, Stream stream);这个函数,其中的stream我们 可以直接从FileUpload.FileContent获得,因为这个FileContent本身就是一个Stream类型的。当然你的项目要引用Microsoft.Sharepoint.dll。

    文件上传完毕后,返回这个文件在服务器上的url就可以了。

    另外,因为网站采用Form认证后,批量上传图片的功能就无法使用了,所以我干脆自己做了一个Silverlight相册,这是基于Silverlight2 beta2的,欢迎大家去做客。点击进入我的图片

    本篇blog首发:oceanstudio-blog

    欢迎访问海洋工作室

  • posted on 2008-07-30 00:26  ocean  阅读(4008)  评论(15编辑  收藏  举报

    导航