ocean

嘿嘿,我的地盘由我来
随笔 - 99, 文章 - 0, 评论 - 1058, 引用 - 28
数据加载中……

在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 阅读(2324) 评论(14)  编辑 收藏 网摘

    评论

    #1楼   回复  引用  查看    

    相册实现的很酷,改天我也模仿你的实现一个:P

    // 很巧,在Unified Communications培训的合影中居然发现了我的同事。。
    2008-07-30 01:08 | TerryLee      

    #2楼   回复  引用  查看    

    不错,收藏
    2008-07-30 02:20 | 个人知识管理      

    #3楼   回复  引用  查看    

    还在用MOSS呢,真是铁杆粉丝啊,呵呵
    2008-07-30 06:50 | 布尔      

    #4楼   回复  引用  查看    

    支持一下,和我昵称一样..
    2008-07-30 08:34 | 海洋      

    #5楼   回复  引用  查看    

    海洋大哥~~~太太太厉害了~~~
    我发现好多问这个问题的哦,收藏,下次需要的时候,随时翻看,HOHO
    2008-07-30 09:24 | 风中的猪儿      

    #6楼   回复  引用  查看    

    这个SharePoint3为什么那么耗资源啊?用这个到底要什么系统配置啊?
    2008-07-30 09:34 | 赵俊      

    #7楼   回复  引用  查看    

    "在MOSS的平台上进行开发,你会觉得非常的优雅,因为MOSS确实是一个非常优秀的开发平台。"----
    不敢苟同!
    2008-07-30 09:40 | badnewfish      

    #8楼   回复  引用  查看    

    “在MOSS的平台上进行开发,你会觉得非常的优雅,因为MOSS确实是一个非常优秀的开发平台。“
    --不敢苟同!
    2008-07-30 09:40 | badnewfish      

    #9楼   回复  引用  查看    

    摘要中的图片太大,麻烦调整一下。
    2008-07-30 09:45 | 博客园团队      

    #10楼   回复  引用  查看    

    好久不见海洋兄的文章了。

    #11楼   回复  引用  查看    

    支持一下
    2008-07-30 11:03 | 永春      

    #12楼[楼主]   回复  引用  查看    

    @TerryLee同学

    模仿做相册就算了吧,还是干点有意义的事情吧,不过我相册里面播放大图的那个工具栏上的按钮,就是上一页下一页旋转等按钮,都是我用xaml画出来的,而没有使用图片。另外就是还有些小问题,在FF里面高度不能随浏览器自动变化,而成了一个固定高度。全屏的时候高度计算的也不是太正确。



    @海洋

    老兄,我的真名就叫海洋。这个可不是昵称。



    @badnewfish

    不苟同就算了,也不用同一个回复发两遍啊。实际上我知道大多数MOSS开发人员都很痛苦,这个主要是因为对MOSS处在一知半解的状态下,就开始动手开发了,痛苦肯定可想而知。



    @博客园团队

    下次会注意,第一次使用摘要图片。可能我的屏幕分辨率过大,没注意图片的事情。我发现这个图片已经有人帮我调小了,感谢!



    @赵俊

    MOSS耗资源是一定的,因为这个本来就是为大型企业设计的,MOSS不是一个网站那么简单,至于服务器配置,有官方指导。如果你只用wss,就不是那么耗资源了。我的网站上只安装了wss3.0,当然最主要的原因是因为这个wss是免费的。我的服务器是2G内存,CPU是至强3G。当然这个服务器上还有20多个其他人的网站。但是跑起来也不感觉慢。



    @布尔

    实际上我什么都研究,最近研究Silverlight反而多一些,MOSS已经过时了,很快就O14了。只不过在我的网站讨论区又有人问这样的问题,而且我也希望我的网站的讨论区也有这个上传图片的功能。所以就做了这么个程序。粉丝现在已经称不上了。
    2008-07-30 13:36 | ocean      

    #13楼   回复  引用  查看    

    http://msdn.microsoft.com/en-us/library/ms520217.aspx" target="_new">http://msdn.microsoft.com/en-us/library/ms520217.aspx
    定制更简单些。
    2008-08-21 11:13 | pccai      

    #14楼   回复  引用  查看    

    为什么我的老是弹出一个新的页面呢?
    2008-08-21 17:52 | pccai      
    发表评论

    昵称: [登录] [注册]

    主页:

    邮箱:(仅博主可见)

    评论内容:

      登录  注册

    [使用Ctrl+Enter键快速提交评论]

    0 1256039




    相关文章:

    相关链接: