• 【Moss开发系列】WF+Aspx进行Moss工作流开发(1)


    Moss平台下工作流设计分一般三种模式:

    一、根据Moss系统本身提供的一些流程模版,如审批工作流、三态工作流等进行定制。

    二、利用SharePoint Designer进行流程设计。

    三、前两种流程设计方式我们称之为流程定制,这种方式一般用于一些简单流程的处理,现实中有很多流程都需要专门的开发,对于这些复杂的流程,我们可以选用第三方流程开发工具(如K2),也可以选用标准的VS环境下的WF进行开发。

    Moss平台下流程开发最常规的做法是:用InfoPath设计表单,然后利用WF设计流程并收集数据,然后与列表关联,最后发布流程。

    这种方式看似简单,但做起来并不那么容易,因为InfoPath有其先天的不足,用InfoPath做过复杂流程的可能都经历过以下几点:

    (1) 界面数据与流程交互比较麻烦,界面本身定制也比较麻烦,常见的情况:客户觉得InfoPath不好看,结果有好多东西是改不了的

    (2) 界面上数据互动也较麻烦,比如常见的三级联动,仿Ajax验证,做起来也是很麻烦的事情

    (3) 大表单与项目清单的显示与控制方面,常见的情况有,客户要求审批界面上半部分显示项目的详细信息,下面是审批信息,而且不同审批人能看到的项目信息字段权限不同

    (4) 表单与表单代码的封装与重用,现实中的流程并不只简单的审批那么简单,一个复杂的流程涉及到的表单可能有上百个,难道都要从头设计,重用和表单管理本身是一个大的问题

    那么如果我们能用Aspx表单来取代InfoPath表单的话,所有问题都可以轻易解决,一切都变得随心所欲了,下面切入正题,如何使用Aspx界面来替换InfoPath表单:

    首先我们新建一个自定义列表“请假信息单”和一个“请假审批”任务类型列表

    然后打开VS2008,新建一个WEB应用程序,注意:不要建成网站类型,建WEB应用程序,Moss环境下部署较麻烦,而WEB应用程序生成单一程序集,易于程序集的签名与部署。

    然后对该WEB应用程序签名,以便于程序集可以部署在GAC中

    新建一目录“_Layouts”,复制 C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS 下的application.master到该目录下。

    删除默认的Default.aspx,新建一个审批页面 Approve.aspx,删除页面中原有HTML代码

    将 前台页面的 Inherits节改为该web应用程序集强命名程序集的名称,Inherits="Janet.AspxWorkflow.Forms.Approve,Janet.AspxWorkflow.Forms, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4af1d7891f28970c" 具体名字可以使用reflector查看。

    然后改写添加 MasterPageFile="~/_layouts/application.master" 使继承母版页”application.master” ,最终页面代码如下: 

    1 <%@ Page Language="C#" MasterPageFile="~/_layouts/application.master" AutoEventWireup="true"
    2 CodeBehind="Approve.aspx.cs" Inherits="Janet.AspxWorkflow.Forms.Approve,Janet.AspxWorkflow.Forms, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4af1d7891f28970c" %>
    3
    4  <%@ Import Namespace="Microsoft.SharePoint" %>
    5  <%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls"
    6 Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    7  <asp:Content ID="Content1" ContentPlaceHolderID="PlaceHolderPageTitle" runat="server">
    8 请假审批流程
    9  </asp:Content>
    10  <asp:Content ID="Content2" ContentPlaceHolderID="PlaceHolderTitleBreadcrumb" runat="server">
    11 &nbsp;
    12  </asp:Content>
    13  <asp:Content ID="Content3" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea"
    14 runat="server">
    15  </asp:Content>
    16  <asp:Content ID="Content5" ContentPlaceHolderID="PlaceHolderMain" runat="server">
    17 <TABLE width="650" style="font-size:12px;color:#369;BORDER-BOTTOM-STYLE: solid; BORDER-RIGHT-STYLE: solid; BORDER-COLLAPSE: collapse; BORDER-TOP-STYLE: solid; BORDER-LEFT-STYLE: solid" border="1" rules="all" cellSpacing="0" cellPadding="4">
    18 <tr>
    19 <td>请假人</td>
    20 <td>
    21 <%= this.UserName%>
    22 </td>
    23 </tr>
    24 <tr>
    25 <td>请假原因</td>
    26 <td>
    27 <%=this.UserMsg %>
    28 </td>
    29 </tr>
    30 <tr>
    31 <td>请假天数</td>
    32 <td>
    33 <%= this.Days%>
    34 </td>
    35 </tr>
    36 <tr>
    37 <td>审批意见</td>
    38 <td>
    39 <asp:TextBox ID="txtMsg" runat="server" TextMode="MultiLine" Rows="5" Columns="40"></asp:TextBox>
    40 </td>
    41 </tr>
    42 <tr>
    43 <td>是否通过</td>
    44 <td>
    45 <asp:RadioButtonList ID="radioPass" runat="server">
    46 <asp:ListItem Value="true" Selected="True">通过</asp:ListItem>
    47 <asp:ListItem Value="false">拒绝</asp:ListItem>
    48 </asp:RadioButtonList>
    49 </td>
    50 </tr>
    51 <tr><td></td>
    52 <td><asp:Button Text="提交" runat="server" ID="BtnSubmit" onclick="BtnSubmit_Click" /></td>
    53 </tr>
    54 </table>
    55  </asp:Content>
    56  

      

    项目中添加对Microsoft.SharePoint的引用,修改后台代码,改变页面继承自 Microsoft.SharePoint.WebControls.LayoutsPageBase

    编写提交处理事件,页面后台代码如下:

    代码
    1
    2  namespace Janet.AspxWorkflow.Forms
    3 {
    4 public partial class Approve : Microsoft.SharePoint.WebControls.LayoutsPageBase
    5 {
    6 protected SPList taskList; //请假审批任务列表
    7 protected SPListItem taskItem; //当前任务
    8
    9 public string UserName; //请假人
    10 public string UserMsg; //请假原因
    11 public string Days; //请假天数
    12
    13 protected void Page_Load(object sender, EventArgs e)
    14 {
    15 string strListID = Request.QueryString["List"];
    16 if (strListID != null)
    17 {
    18 taskList = Web.Lists[new Guid(strListID)];
    19 taskItem = taskList.GetItemById(Convert.ToInt32(Request.Params["ID"]));
    20 if (!Page.IsPostBack)
    21 {
    22 Guid workflowId = new Guid((string)taskItem["WorkflowInstanceID"]);
    23 SPWorkflow workflow = new SPWorkflow(Web, workflowId);
    24 SPListItem projectItem = workflow.ParentItem; //当前请假项目
    25
    26 this.UserName = projectItem["Author"].ToString();
    27 this.UserMsg=projectItem["请假原因"].ToString();
    28 this.Days = projectItem["请假天数"].ToString();
    29 }
    30 }
    31 }
    32
    33
    34
    35 protected void BtnSubmit_Click(object sender, EventArgs e)
    36 {
    37 try
    38 {
    39 if (taskItem != null)
    40 {
    41 SPWeb web = SPContext.Current.Web;
    42 web.AllowUnsafeUpdates = true;
    43 Hashtable taskHash = new Hashtable();
    44 taskHash["ApproveMsg"] = this.txtMsg.Text; //审批信息
    45 taskHash["approved"] = this.radioPass.SelectedValue; //审批状态,WF中获取用来判断,是否回退....
    46 SPWorkflowTask.AlterTask(taskItem, taskHash, true); //提交任务审批结果
    47 SPUtility.Redirect(taskList.DefaultViewUrl, SPRedirectFlags.UseSource, HttpContext.Current);
    48 }
    49 }
    50 catch (Exception ex)
    51 {
    52 Response.Write(ex.ToString());
    53 }
    54 }
    55 }
    56 }

       

    编写Feature配置文件,

    Feathre.xml 

    代码
    1 <?xml version="1.0" encoding="utf-8"?>
    2  <Feature Id="1161B2A1-FDED-47a2-B3FE-7C97DD6CC743" Title="请假审批内容类型" Scope="Site" Version="1.0.0.0" Hidden="FALSE" DefaultResourceFile="core" xmlns="http://schemas.microsoft.com/sharepoint/">
    3 <ElementManifests>
    4 <ElementManifest Location="form.xml" />
    5 </ElementManifests>
    6  </Feature>

    form.xml  

    代码
    1 <?xml version="1.0" encoding="utf-8"?>
    2  <Elements Id="D9170A70-D733-4886-9117-12410DF5A8B2" xmlns="http://schemas.microsoft.com/sharepoint/">
    3 <ContentType ID="0x0108010023070ff45efd410a8bb9252cbabc1211"
    4 Name="请假审批页面"
    5 Group="我的审批页面"
    6 Description="请假审批表单内容类型"
    7 Version="0">
    8 <FieldRefs>
    9 </FieldRefs>
    10 <XmlDocuments>
    11 <XmlDocument NamespaceURI="http://schemas.microsoft.com/sharepoint/events">
    12 <Receivers />
    13 </XmlDocument>
    14 <XmlDocument NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url">
    15 <FormUrls xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url">
    16 <New>_layouts/MyAspxTask/Approve.aspx</New>
    17 <Display>_layouts/MyAspxTask/Approve.aspx</Display>
    18 <Edit>_layouts/MyAspxTask/Approve.aspx</Edit>
    19 </FormUrls>
    20 </XmlDocument>
    21 </XmlDocuments>
    22 </ContentType>
    23 </Elements>

     注意:上面文件中的 _layouts/MyAspxTask/Approve.aspx 指向的是你的审批页面。    

    在C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES 下面建一目录 MyAspxTask ,然后把这两个XML文件放入该目录中。执行命令:STSADM -o InstallFeature -filename MyAspxTask\feature.xml -force   注册该Feature。

    注册成功后在“网站集功能”中能看到该内容类型,然后激活该内容类型

     

     然后进入“请假审批”任务列表的设置页,选择“高级设置”启用内容类型管理,如下图所示:

     然后在“请假审批”列表中添加刚才我们创建的那个内容类型:

     

     把我们的审批页面 approve.aspx 文件复制到 C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\MyAspxTask 目录下,然后把WEB应用程序的dll文件,拖到GAC中(C:\WINDOWS\assembly文件夹),到这里,页面部分设计完成,下面进行WF部分开发。

    该流程仅涉及到一级审批:

     注意:创建任务活动在这里要使用“CreateTaskWithContentType”,在该活动的"ContentTypeID"属性中输入 0x0108010023070ff45efd410a8bb9252cbabc1211,即form.xml中的ContentType节的ID中的值,整个流程的代码如下: 

    代码
    1 public sealed partial class Workflow1 : SequentialWorkflowActivity
    2 {
    3 public Workflow1()
    4 {
    5 InitializeComponent();
    6 }
    7
    8 public Guid workflowId = default(System.Guid);
    9 public SPWorkflowActivationProperties workflowProperties = new SPWorkflowActivationProperties();
    10 public Guid taskId1 = default(System.Guid);
    11 public SPWorkflowTaskProperties taskProperties1 = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();
    12
    13 private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e)
    14 {
    15
    16 }
    17
    18 private void createTaskWithContentType1_MethodInvoking(object sender, EventArgs e)
    19 {
    20 this.taskId1 = Guid.NewGuid();
    21 this.taskProperties1.AssignedTo = "jasper\\moss";
    22 this.taskProperties1.Title = string.Format("请审批【{0}】", this.workflowProperties.Item.DisplayName);
    23 }
    24
    25 private void onTaskChanged1_Invoked(object sender, ExternalDataEventArgs e)
    26 {
    27 bool approve = bool.Parse(this.taskProperties1.ExtendedProperties["approved"].ToString());
    28 string msg = approve ? "审批通过:" : "审批拒绝:";
    29 msg += this.taskProperties1.ExtendedProperties["ApproveMsg"].ToString();
    30 this.workflowProperties.Workflow.CreateHistoryEvent(approve ? 2 : 8, 0, this.workflowProperties.OriginatorUser, msg, "", ""); //写入工作流历史记录
    31 }
    32 }

      

    启动该工作流:

     审批该任务,看到我们熟悉的Aspx页面:

     审批结束: 

     

     请假审批结束,历史记录记录了该请假中间的审批过程,可以看到我的回家看老婆的希望已经破灭了......

     总结:这个只是一个简单的演示,很多细节没有进行处理。用Aspx做表单,一个流程的第一次使用感觉麻烦了点,后期经过一系列封装之后,做起来就简单的多了。

     示例项目下载

     下一篇将对aspx+wf进行一系列封装,使之能够轻易完成wf+infopath中的task1, task2 ... taskn的功能。

  • 相关阅读:
    Python requests“Max retries exceeded with url” error
    命令行链接mongo、redis、mysql
    python 删除字典某个key(键)及对应值
    python标准模块(二)
    python标准模块(一)
    格式化输出
    LeetCode----1. Two Sum
    文件操作(初阶)
    python函数基础
    python3内置函数
  • 原文地址:https://www.cnblogs.com/janet/p/1719315.html
Copyright © 2020-2023  润新知