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

Posted 微软动态CRM专家罗勇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用Fiddler修改请求信息通过Web API执行Dynamics 365操作(Action)实例相关的知识,希望对你有一定的参考价值。

Web API在Dynamics CRM中的功能越来越强大,Dynamics 365 (Dynamics CRM V8.2) 又增加了一些通过通过Web API可以执行的操作(Action) ,比如 ExecuteWorkflow这个Action,具体Web API可以执行哪些操作呢?可以参考SDK的 Web API Action Reference 章节,也有在线版本,在线版本是 Web API Action Reference 。当然,这个章节的内容会变化,要查看Dynamics CRM对应版本的SDK。今天要讲解的是利用Fiddler的Replay功能通过Web API调用操作。

在继续阅读之前,如果你对通过Web API执行操作没有概念,强烈建议你先阅读我的文章:Dynamics CRM 2015/2016新特性之二十四:使用Web API执行操作 。

我们先看 ExecuteWorkflow Action 的说明,可以知道它是一个绑定操作, 它有一个输入参数 EntityId ,也有返回参数,是个asyncoperation 实体记录类型。为了测试需要,先要找一个工作流,我这里有一个工作流如下,我这里故意没有选中 作为按需流程 ,是因为我想看看不选中这个是否也可以通过代码执行这个工作流,当然在界面上通过运行工作流此时是找不到这个工作流的。

 

然后我需要找一条这个工作流对应实体的一条记录,我这里选择一条记录。顺便介绍下如何获取记录ID的方法,右击一条记录,选择 在新窗口中打开 。

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

 

然后就会在新窗口中打开,可以看到打开记录时候的URL是类似: https://demo.luoyong.me/main.aspx?etc=10007&extraqs=&histKey=789763582&id=%7bB907DE1B-CF99-E611-8161-000D3A80C8B8%7d&newWindow=true&pagetype=entityrecord&sitemappath=SFA%7cExtensions%7cly_test#348434379 。这个URL中的id=%7b 和 %7d之间的就是这个记录的ID。

我们还需要执行的工作流的ID,在解决方案中双击打开该工作流,有类似这样的URL:https://demo.luoyong.me/sfa/workflow/edit.aspx?_CreateFromId=%7b2721DA92-65A4-E511-80CB-000D3A80CE7F%7d&_CreateFromType=7100&appSolutionId=%7b2721DA92-65A4-E511-80CB-000D3A80CE7F%7d&id=%7b6BEBC426-F722-4B64-AE5D-0DA379F8A8C4%7d 

同样的我们可以拿到这个工作流的ID。

我这里借助Fiddler来Replay,启用Fiddler抓包,右击一个请求,选择 Replay > Reissue from Composer.

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

在Fiddler的Composer中打开页面类似如下:

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

 

然后我们就可以更改请求方法,请求URL,请求头Header和请求体Body。我这里更改如下:

POST的URL我改成了:https://demo.luoyong.me/api/data/v8.2/workflows(6BEBC426-F722-4B64-AE5D-0DA379F8A8C4)/Microsoft.Dynamics.CRM.ExecuteWorkflow

 Request Body我改成了如下,特别注意这个Cookie的元素值要保留,用来认证的,当然也会过期:

Content-Type: application/json; charset=utf-8
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
Cookie: ReqClientId=dff59da0-52dd-42f9-8ab9-e62ad9b24e57; e9cd027f-26a3-e511-80c6-000d3a807ec7_bd2a5c49-6b08-4eda-8a15-84159d9fd349=/Date(1478082706255)/; persistentNavTourCookie=HideNavTour; CRM_MSG_BAR_ServiceDeskAlert%23e9cd027f-26a3-e511-80c6-000d3a807ec7=HideMessage; MSISAuth=77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48U2VjdEJicSt6NHgwUmc4NUxhSWFPU2lNUW9DQlRpcm53TkY0aGNUV1ZOYmVzMXphVStQU1JGd1JrT3BWTlM2cFcreXF4UFI3S1QrOTVNTGF1Slgxd1VJYmFWUFd2a3pyKzhQLzFIMm5nVnFSc3pxV1RKbjlrMWxlRWhB; MSISAuth1=M3VIZmdZZmVFcTExU3ErbDBiR1dPQUUvaEMxMFFOejlYa2tRdUxPNFd4SmVLVm82bkw1WllTWU84aDBRMkVqQUdlK1dIQ1A5cjgyQ3p0Z2dvQWhZQk1RNnJlZnJJdXNjVUFBQUFPVUdacjkrcTY0cHhyd2JyYVVuTWEyRVlVUU09PC9Db29raWU+PC9TZWN1cml0eUNvbnRleHRUb2tlbj4=; CRM_MSG_BAR_e9cd027f-26a3-e511-80c6-000d3a807ec7GetAppsForCrm=HideMessage; CRM_MSG_BAR_EnableS2SAlert%23e9cd027f-26a3-e511-80c6-000d3a807ec7=HideMessage

 Request Body我改成了:

{"EntityId":"B907DE1B-CF99-E611-8161-000D3A80C8B8"}

 我执行的话会返回HTTP Status为500,内部错误:

HTTP/1.1 500 Internal Server Error
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; odata.metadata=minimal
Expires: -1
Server: Microsoft-IIS/8.5
REQ_ID: 5b92fe5f-7856-4817-bc18-210b20fa2b08
OData-Version: 4.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 24 Jul 2017 15:33:39 GMT
Content-Length: 2869

{
"error":{
"code":"","message":"Workflow must be marked as on-demand or child workflow.","innererror":{
"message":"Workflow must be marked as on-demand or child workflow.","type":"System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]","stacktrace":" at Microsoft.Crm.Extensibility.OrganizationSdkServiceInternal.Execute(OrganizationRequest request, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, Boolean checkAdminMode, ExecutionContext executionContext)\r\n at Microsoft.Crm.Extensibility.OData.CrmODataExecutionContext.Execute(OrganizationRequest request, ExecutionContext executionContext)\r\n at Microsoft.Crm.Extensibility.OData.CrmODataServiceDataProvider.ExecuteOperation(CrmODataExecutionContext context, EdmOperation edmOperation, Dictionary`2 parameters, Dictionary`2 boundParameters)\r\n at Microsoft.Crm.Extensibility.OData.ActionController.ProcessOperationRequest(String operationName, Dictionary`2 operationParameters, EntityReference entityReference, String boundEntityName, String boundEntityType)\r\n at Microsoft.Crm.Extensibility.OData.ActionController.PostBoundAction(String entityName, String key, String operationName, ODataUntypedActionParameters parameters)\r\n at lambda_method(Closure , Object , Object[] )\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
}
}
}

提示很清晰,工作流必须要选中 作为按需流程 或者是子流程才行。于是我停用该工作流,然后激活该工作流,再来尝试,执行结果如下:

如果查看原版的返回内容是这样的:

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; odata.metadata=minimal
Expires: -1
Server: Microsoft-IIS/8.5
REQ_ID: 0ad59cc7-ab4e-49bf-a05b-8b522db29c75
Preference-Applied: return=representation
OData-Version: 4.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 24 Jul 2017 15:39:04 GMT
Content-Length: 38136

{
"@odata.context":"https://demo.luoyong.me/api/data/v8.2/$metadata#asyncoperations/$entity","statecode":0,"asyncoperationid":"f9349b37-8670-e711-826c-000d3a80c8b8","_regardingobjectid_value":"b907de1b-cf99-e611-8161-000d3a80c8b8","_owningextensionid_value":"c8556024-8670-e711-826c-000d3a80c8b8","createdon":"2017-07-24T15:39:03Z","_workflowactivationid_value":"c8556024-8670-e711-826c-000d3a80c8b8","depth":1,"messagename":"ExecuteWorkflow","_ownerid_value":"e9cd027f-26a3-e511-80c6-000d3a807ec7","name":"\u7f57\u52c7\u6d4b\u8bd5\u5b9e\u4f53\u5b57\u6bb5\u503c\u53d8\u66f4\u540e\u8fd0\u884c\u7684\u5de5\u4f5c\u6d41","correlationid":"0c36b86f-f64f-4ba5-bf58-d260ab9e4022","parentpluginexecutionid":"00000000-0000-0000-0000-000000000000","iswaitingforevent":false,"correlationupdatedtime":"2017-07-24T15:39:03Z","timezoneruleversionnumber":0,"_modifiedby_value":"bef8b450-fb18-4078-a7ac-2b281e1cf051","primaryentitytype":"ly_test","statuscode":0,"operationtype":10,"modifiedon":"2017-07-24T15:39:03Z","sequence":183869,"_modifiedonbehalfby_value":"e9cd027f-26a3-e511-80c6-000d3a807ec7","executiontimespan":0.0,"_createdonbehalfby_value":"e9cd027f-26a3-e511-80c6-000d3a807ec7","_createdby_value":"bef8b450-fb18-4078-a7ac-2b281e1cf051","_owningbusinessunit_value":"487cdd4b-26a3-e511-80c6-000d3a807ec7","data":"<?xml version=\"1.0\" encoding=\"utf-16\"?><AsyncOperationData xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://schemas.datacontract.org/2004/07/Microsoft.Crm\"><CallerOrigin xmlns:d2p1=\"http://schemas.datacontract.org/2004/07/Microsoft.Crm.Sdk\" i:type=\"d2p1:WebServiceApiOrigin\" /><InitiatingUserId>e9cd027f-26a3-e511-80c6-000d3a807ec7</InitiatingUserId><InputParameters xmlns:d2p1=\"http://schemas.microsoft.com/xrm/2011/Contracts\" xmlns:d2p2=\"http://schemas.datacontract.org/2004/07/System.Collections.Generi<d2p2:value>499,024,149.58</d2p2:value></d2p1:KeyValuePairOfstringstring></d2p1:FormattedValues><d2p1:Id>b907de1b-cf99-e611-8161-000d3a80c8b8</d2p1:Id><d2p1:KeyAttributes xmlns:d5p1=\"http://schemas.microsoft.com/xrm/7.1/Contracts\" /><d2p1:LogicalName>ly_test</d2p1:LogicalName><d2p1:RelatedEntities /><d2p1:RowVersion>2368019</d2p1:RowVersion></d2p2:value></d2p1:KeyValuePairOfstringanyType><d2p1:KeyValuePairOfstringanyType><d2p2:key>AsyncOperationId</d2p2:key><d2p2:value xmlns:d4p1=\"http://schemas.microsoft.com/2003/10/Serialization/\" i:type=\"d4p1:guid\">f9349b37-8670-e711-826c-000d3a80c8b8</d2p2:value></d2p1:KeyValuePairOfstringanyType></SharedVariables><Stage>30</Stage></AsyncOperationData>","_owninguser_value":"e9cd027f-26a3-e511-80c6-000d3a807ec7","subtype":1,"message":null,"dependencytoken":null,"postponeuntil":null,"_owningteam_value":null,"completedon":null,"recurrencepattern":null,"workflowstagename":null,"recurrencestarttime":null,"errorcode":null,"hostid":null,"utcconversiontimezonecode":null,"requestid":null,"friendlymessage":null,"retrycount":null,"startedon":null
}

 可以看到执行成功,我去界面上也可以看到执行了工作流:


以上是关于利用Fiddler修改请求信息通过Web API执行Dynamics 365操作(Action)实例的主要内容,如果未能解决你的问题,请参考以下文章

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

利用fiddler拦截接口请求并篡改数据

Fiddler拦截http请求修改数据

利用Fiddler对Jmeter的请求进行抓包

fiddler断点测试修改响应指令有啥作用

Fiddler断点调试