我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面的微软最有价值专家(Microsoft MVP),欢迎关注我的微信公众号 MSFTDynamics365erLuoYong ,回复356或者20190830可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!

之前的文章 使用JS通过Web API执行批量操作,多个操作是一个事务! 讲的是JavaScript的做法,今天我实验了一阵子终于搞定了C#做法。

不多说,上代码,这个代码的用途简单,就是新建一个注释,然后将某个注释的stepid字段值设置为Y,两个操作做成一个事务:

  1. private static async Task<string> ExecuteBatch(string ODataBaseUrl)
  2. {
  3. Guid batchId = Guid.NewGuid();
  4. Guid changesetId = Guid.NewGuid();
  5. string returnVal = string.Empty;
  6. StringBuilder requestBody = new StringBuilder();
  7. requestBody.Append($"--batch_{batchId}");
  8. requestBody.Append("\n");
  9. requestBody.Append($"Content-Type: multipart/mixed;boundary=changeset_{changesetId}");
  10. requestBody.Append("\n");
  11. requestBody.Append("\n");
  12. requestBody.Append($"--changeset_{changesetId}");
  13. requestBody.Append("\n");
  14. requestBody.Append("Content-Type: application/http");
  15. requestBody.Append("\n");
  16. requestBody.Append("Content-Transfer-Encoding:binary");
  17. requestBody.Append("\n");
  18. requestBody.Append("Content-ID: 1");
  19. requestBody.Append("\n");
  20. requestBody.Append("\n");
  21. requestBody.Append($"POST {ODataBaseUrl}annotations HTTP/1.1");
  22. requestBody.Append("\n");
  23. requestBody.Append("Content-Type: application/json;type=entry");
  24. requestBody.Append("\n");
  25. requestBody.Append("\n");
  26. JObject jObject = new JObject(
  27. new JProperty("subject", "克隆出来的记录"),
  28. new JProperty("filename", "MSFTDynamics365erLuoYong.jpg"),
  29. new JProperty("filesize", ),
  30. new JProperty("documentbody", "/9j/4AAQSkZJRgAB2cFFABRRRQAUUUUAf//Z"
  31. requestBody.Append("\n");
  32. requestBody.Append($"--changeset_{changesetId}");
  33. requestBody.Append("\n");
  34. requestBody.Append("Content-Type: application/http");
  35. requestBody.Append("\n");
  36. requestBody.Append("Content-Transfer-Encoding:binary");
  37. requestBody.Append("\n");
  38. requestBody.Append("Content-ID: 2");
  39. requestBody.Append("\n");
  40. requestBody.Append("\n");
  41. requestBody.Append($"PUT {ODataBaseUrl}annotations(4B502B89-4520-E911-B0C6-E05D5152C120)/stepid HTTP/1.1");
  42. requestBody.Append("\n");
  43. requestBody.Append("Content-Type: application/json;type=entry");
  44. requestBody.Append("\n");
  45. requestBody.Append("\n");
  46. requestBody.Append("{\"value\":\"Y\"}");
  47. requestBody.Append("\n");
  48. requestBody.Append("\n");
  49. requestBody.Append($"--changeset_{changesetId}--");
  50. requestBody.Append("\n");
  51. requestBody.Append("\n");
  52. requestBody.Append($"--batch_{batchId}--");
  53. HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create($"{ODataBaseUrl}$batch");
  54. request.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["userName"], ConfigurationManager.AppSettings["passWord"]);
  55. request.Method = "POST";
  56. request.ContentType = $"multipart/mixed;boundary=batch_{batchId}";
  57. request.Accept = "application/json";
  58. request.Headers.Add("OData-MaxVersion", "4.0");
  59. request.Headers.Add("OData-Version", "4.0");
  60. byte[] buffer = Encoding.UTF8.GetBytes(requestBody.ToString());
  61. request.ContentLength = buffer.Length;
  62. using (Stream stream = await request.GetRequestStreamAsync())
  63. {
  64. stream.Write(buffer, , buffer.Length);
  65. stream.Flush();
  66. }
  67. using (WebResponse response = await request.GetResponseAsync())
  68. {
  69. var webResponse = response as HttpWebResponse;
  70. if (webResponse.StatusCode == HttpStatusCode.OK)
  71. {
  72. Stream Answer = response.GetResponseStream();
  73. StreamReader _Answer = new StreamReader(Answer);
  74. returnVal = _Answer.ReadToEnd();
  75. }
  76. else
  77. {
  78. throw new Exception($"Error. {webResponse.StatusCode}");
  79. }
  80. }
  81. return returnVal;
  82. }

我的执行效果如下,我这里是执行成功HTTP STATUS CODE = 200)后显示了返回内容:

如果改成用 HttpClient 来发起请求,代码如下,个人推荐使用这种:

  1. private static async Task<string> ExecuteBatch(string ODataBaseUrl)
  2. {
  3. Guid batchId = Guid.NewGuid();
  4. Guid changesetId = Guid.NewGuid();
  5. string returnVal = string.Empty;
  6. StringBuilder requestBody = new StringBuilder();
  7. requestBody.Append($"--batch_{batchId}");
  8. requestBody.Append("\n");
  9. requestBody.Append($"Content-Type: multipart/mixed;boundary=changeset_{changesetId}");
  10. requestBody.Append("\n");
  11. requestBody.Append("\n");
  12. requestBody.Append($"--changeset_{changesetId}");
  13. requestBody.Append("\n");
  14. requestBody.Append("Content-Type: application/http");
  15. requestBody.Append("\n");
  16. requestBody.Append("Content-Transfer-Encoding:binary");
  17. requestBody.Append("\n");
  18. requestBody.Append("Content-ID: 1");
  19. requestBody.Append("\n");
  20. requestBody.Append("\n");
  21. requestBody.Append($"POST {ODataBaseUrl}annotations HTTP/1.1");
  22. requestBody.Append("\n");
  23. requestBody.Append("Content-Type: application/json;type=entry");
  24. requestBody.Append("\n");
  25. requestBody.Append("\n");
  26. JObject jObject = new JObject(
  27. new JProperty("subject", "克隆出来的记录"),
  28. new JProperty("filename", "MSFTDynamics365erLuoYong.jpg"),
  29. new JProperty("filesize", ),
  30. new JProperty("documentbody", "/9j/4AAQSkZJRRRQAUUUUAf//Z"),
  31. new JProperty("isdocument", true),
  32. new JProperty("mimetype", "image/jpeg"),
  33. new JProperty("notetext", "罗勇测试用的"),
  34. new JProperty("objectid_account@odata.bind", "/accounts(C543D891-9FBD-E911-B0D1-8280A40FB795)")
  35. );
  36. requestBody.Append(JsonConvert.SerializeObject(jObject));
  37. requestBody.Append("\n");
  38. requestBody.Append("\n");
  39. requestBody.Append($"--changeset_{changesetId}");
  40. requestBody.Append("\n");
  41. requestBody.Append("Content-Type: application/http");
  42. requestBody.Append("\n");
  43. requestBody.Append("Content-Transfer-Encoding:binary");
  44. requestBody.Append("\n");
  45. requestBody.Append("Content-ID: 2");
  46. requestBody.Append("\n");
  47. requestBody.Append("\n");
  48. requestBody.Append($"PUT {ODataBaseUrl}annotations(85412E8C-B08D-E911-B0C9-C8187530CEF1)/stepid HTTP/1.1");
  49. requestBody.Append("\n");
  50. requestBody.Append("Content-Type: application/json;type=entry");
  51. requestBody.Append("\n");
  52. requestBody.Append("\n");
  53. requestBody.Append("{\"value\":\"Y\"}");
  54. requestBody.Append("\n");
  55. requestBody.Append("\n");
  56. requestBody.Append($"--changeset_{changesetId}--");
  57. NetworkCredential credentials = new NetworkCredential(ConfigurationManager.AppSettings["userName"], ConfigurationManager.AppSettings["passWord"]);
  58. HttpMessageHandler messageHandler = new HttpClientHandler()
  59. {
  60. Credentials = credentials
  61. };
  62. using (HttpClient httpClient = new HttpClient(messageHandler))
  63. {
  64. httpClient.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");
  65. httpClient.DefaultRequestHeaders.Add("OData-Version", "4.0");
  66. httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
  67. MultipartContent mainContent = new MultipartContent("mixed", $"batch_{batchId.ToString().Replace("\"","")}");
  68. StringContent sc = new StringContent(requestBody.ToString());
  69. sc.Headers.Clear();
  70. sc.Headers.Add("Content-Type", $"multipart/mixed;boundary={changesetId.ToString()}");
  71. mainContent.Add(sc);
  72. var response = await httpClient.PostAsync($"{ODataBaseUrl}$batch", mainContent);
  73. if (response.IsSuccessStatusCode)
  74. {
  75. returnVal = await response.Content.ReadAsStringAsync();
  76. }
  77. else
  78. {
  79. var errorMsg = await response.Content.ReadAsStringAsync();
  80. throw new Exception(errorMsg);
  81. }
  82. return returnVal;
  83. }
  84. }

通过C#代码调用Dynamics 365 Web API执行批量操作的更多相关文章

  1. 使用JS通过Web API执行批量操作,多个操作是一个事务!

    关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复235或者20161105可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong. ...

  2. Dynamics 365 Web Api之基于single-valued navigation property的filter查询

    本篇要讲的是dynamics 新版本中web api的一个改进功能,虽然改进的很有限,但至少是改进了. 举个例子,我们现在知道联系人的名字vic,我们想找出客户记录中主要联系人名字为vic的所有客户, ...

  3. 利用Fiddler修改请求信息通过Web API执行Dynamics 365操作(Action)实例

    本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复261或者20170724可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong.me ...

  4. 不借助工具在浏览器中通过Web API执行Dynamics 365操作(Action)实例

    摘要: 本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复262或者20170727可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyon ...

  5. Dynamics CRM Web API中的and和or组合的正确方式!

    关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复243或者20170111可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong. ...

  6. MVC项目实践,在三层架构下实现SportsStore-09,ASP.NET MVC调用ASP.NET Web API的查询服务

    ASP.NET Web API和WCF都体现了REST软件架构风格.在REST中,把一切数据视为资源,所以也是一种面向资源的架构风格.所有的资源都可以通过URI来唯一标识,通过对资源的HTTP操作(G ...

  7. Dynamics CRM2016 Web Api之分页查询

    在dynamics crm web api还没出现前,我们是通过fetchxml来实现的,当然这种方式依旧可行,那既然web api来了我们就拥抱新的方式. web api中我们通过指定查询的条数来实 ...

  8. 延迟调用或多次调用第三方的Web API服务

    当我们调用第三方的Web API服务的时候,不一定每次都是成功的.这时候,我们可能会再多尝试几次,也有可能延迟一段时间再去尝试调用服务. Task的静态方法Delay允许我们延迟执行某个Task,此方 ...

  9. 利用Fiddler修改请求信息通过Web API执行操作(Action)实例

    本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复261或者20170724可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong.me ...

随机推荐

  1. SAP QM 检验批里样品数量的确定

    SAP QM 检验批里样品数量的确定 如下的检验批890000045939, 样品数量是50 PC. 检查该检验批对应的检验计划, 这些检验特性都有自己的取样策略,相关的取样数量,体现在结果录入界面, ...

  2. 信通院发布《云计算发展白皮书 (2019年) 》 (附PPT解读)

    来源: 中国信息通信研究院CAICT 为了进一步促进云计算创新发展,建立云计算信任体系,规范云计算行业,促进市场发展,提升产业技术和服务水平.由中国信息通信研究院(以下简称“中国信通院”)主办,中国通 ...

  3. electron初探问题总结

    使用electron时间不是很久,随着使用的深入慢慢的也遇到一些问题,下面总结一下遇到的问题与大家分享,避免趟坑. 主要问题汇总如下: webview与渲染进程renderer间通信 BrowserW ...

  4. 文件上传报错:Unknown: file created in the system's temporary directory

    nginx+php下文件上传成功,但会有错误提示如下: <b>Notice</b>:  Unknown: file created in the system's tempor ...

  5. Python 标准类库-数字和数学模块之decimal使用简介

    标准类库-数字和数学模块之decimal使用简介 by:授客 QQ:1033553122 例子 >>>from decimal import * >>>getcon ...

  6. ubutu tornado python3.7.5 nginx supervisor 部署web api

    环境: 1.Ubuntu 服务器 2.python3.7.5 安装 1.python3.7.5 安装的话还是比较简单,流程大致是./configure ->make && mak ...

  7. HTTP与FILE协议的区别

    File协议 file协议(本地文件传输协议)主要是用来访问本地计算机的文件,一般用Windows的资源管理器直接打开进行读取一个HTML文件时,默认会使用file协议 基本格式是: file:/// ...

  8. Android五大布局详解——FrameLayout(帧布局)

    FrameLayout 这个布局相对前面两节介绍的布局就简单了很多,因此它的应用场景也就特别的少.这种布局没有方便的定位方式,所有的控件都会默认摆放在布局的左上角.新建UILayoutTestThre ...

  9. Git问题汇总

    1.fatal: refusing to merge unrelated histories $git pull origin master --allow-unrelated-histories 2 ...

  10. Windows下Kafka 2.3.0的下载和安装

    Kafka是由Apache软件基金会开发的一个开源流处理平台,是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据. 特性:(1)通过O(1)的磁盘数据结构提供消息的持久化 ...