在Dynamics 365中使用SharePoint集成做实体的附件管理,这里不像用Annotation实体存放附件可以直接用代码直接创建Annotation记录,如果想要对外部提供接口把附件上传到SharePoint,我们可以使用Power Automate中的SharePoint组件来生成文件,通过HTTP流供给外部系统调用。
下面是Power Automate的完整步骤
1.当收到HTTP请求时
method:POST
请求正文JSON架构:
{ "type": "object", "properties": { "contractId": { "type": "string" }, "fileList": { "type": "array", "items": { "type": "object", "properties": { "fileName": { "type": "string" }, "fileBase64": { "type": "string" } }, "required": [ "fileName", "fileBase64" ] } } } }
请求JSON示例:
{ "contractId": "09101368-65EA-ED11-8848-002248EE98C7", "fileList": [ { "fileName": "newpic.png", "fileBase64": "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAOCAYAAAAbvf3sAAAAAXNSR0IArs4c6QAArkJggg==" }, { "fileName": "测试文档V1.2.docx", "fileBase64": "UEsDBBQAAAAIAIdO4kCiCB42aAEAAHoCAAAQAAAAZG9jUHJvcHMvYXBwLnht..." } ] }
2.初始化result变量
添加一个初始化变量的操作,result为变量名,类型为对象,这个对象用来作为http请求的返回结果。
3.分析文件列表JSON
添加一个“数据操作”,选择“分析JSON”,内容选择入参里的fileList
4.获取合同记录
选择Dataverse里的按ID获取行操作,根据入参的contractId获取合同的相关信息。
5.获取id路径
这里初始化了一个字符串变量IdPath,用来存放附件的文档目录,后面的步骤会用,到下面的“值”可以不用管。
6.获取合同文档位置
添加一个Dataverse操作,用来获取当前合同记录的文档位置,表名称选择“文档位置”。
Fetch Xml查询的内容如下:
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false"> <entity name="sharepointdocumentlocation"> <attribute name="name" /> <attribute name="regardingobjectid" /> <attribute name="parentsiteorlocation" /> <attribute name="relativeurl" /> <attribute name="absoluteurl" /> <order attribute="name" descending="false" /> <filter type="and"> <condition attribute="locationtype" operator="eq" value="0" /> <condition attribute="servicetype" operator="eq" value="0" /> </filter> <link-entity name="new_contract" from="new_contractid" to="regardingobjectid" link-type="inner" alias="ae"> <filter type="and"> <condition attribute="new_contractid" operator="eq" value="@{outputs('获取合同记录')?['body/new_contractid']}" /> </filter> </link-entity> </entity> </fetch>
需要注意:单纯只创建一条合同记录,CRM后台是不会生成和它关联的sharepointdocumentlocation记录,在CRM窗体上打开“附件”选项卡后,后台就能查到sharepointdocumentlocation记录了,所以我们可以通过自动查询SharePoint文档的方式来触发生成sharepointdocumentlocation记录。我这里的在合同创建的后的自定义插件里执行对sharepointdocument的fetchxml查询,这样合同只要创建了,就会默认生成文档位置记录。
7.遍历文档位置
添加一个变量操作,将上一步查询到的文档位置的“相对URL”字段赋值给IdPath变量,第6步返回的是一个结果集,所以指定赋值结果后,操作会“遍历每一个”包含起来,实际上只会有一条记录返回。
8.初始化变量
初始化3个变量,FileFullName、FileName、FielExtension用来存放文件的文件名、不带后缀的文件名、文件后缀名。
9.遍历fileList
将入参里的fileList“应用到每一个”,循环逐条创建文件。
10.设置文件后缀名、文件名(无后缀)
通过文件名中的“.”分割获取文件的名称和后缀,表达式分别为last(split(items('应用到每一个')['fileName'],'.'))、replace(items('应用到每一个')['FileName'], variables('FielExtension'), '')
11.获取文件夹是否存在
如果当前合同没有上传过附件,那么文档目录在SharePoint对应的路径是不存在的,需要先判断文件夹是否存在。这里使用SharePoint的“将HTTP请求发送到SharePoint”操作。站点地址选择存放文档的SharePoint站点,方法选择GET,Uri为_api/web/GetFolderByServerRelativeUrl('/new_contract/@{variables('IdPath')}')/Exists。Uri中的new_contract为合同实体的逻辑名,如果是其他实体就换成对应实体的逻辑名称,返回的结果为true或false。
12.判断文件夹是否存在
表达式左侧为 body('获取文件夹是否存在')?['d']?['Exists']
13.获取文件(仅属性)
在“如果是”的分支,添加SharePoint操作“获取文件(仅属性)”,筛选查询添加文件名筛选条件FileLeafRef eq '@{items('应用到每一个')['fileName']}',结果会返回文件夹内符合文件名的文件属性。
14.检查文件名是否存在
添加分支操作,表达式左侧为 empty(outputs('获取文件(仅属性)')?['body/value']),右侧为true,如果不存在,则可以正常按文件名上传,如果文件名已经存在,则直接上传会出现重名错误,这时需要将文件更名或者删除已有文件,这里我选择将文件名后面增加一个时间后缀,避免文件重复。
15.创建文件
选择SharePoint的创建文件操作,站点地址为SharePoint的地址,文件夹路径为new_contract/@{variables('IdPath')},文件名为FileFullName变量,文件内容需要通过base64表达式进行转换,这里的表达式为:base64ToBinary(items('应用到每一个')['fileBase64'])
在第12步的“如果不是”分支,直接按原文件名创建就行。
16.响应
将result变量作为响应的正文返回,这里result的内容没有做处理,如果有需要也可以对result结果进行自定义处理。
- SharePoint Automate Dynamics 附件 Powersharepoint automate dynamics附件 dynamics automate模板power sharepoint automate文件 内容 operations dynamics automate finance automate schedule power flows variables automate notation power 脚本automate程序power automate request power apim 变量automate专栏power 注意事项automate事项power