Beispiel #1
0
        public async Task Execute(CrmRequestMessage request, Func <Task <HttpResponseMessage> > action)
        {
            int retryNumber = 0;

            while (true)
            {
                var response = await action();

                retryNumber++;
                if (!response.IsSuccessStatusCode)
                {
                    //先判断content为空
                    var requestBody = string.Empty;
                    if (response.RequestMessage.Content != null)
                    {
                        requestBody = await response.RequestMessage.Content.ReadAsStringAsync();
                    }
                    var strContent = await response.Content.ReadAsStringAsync();

                    //这个后面没用到,还容易报错,暂时注释
                    //var error = JsonSerializerHelper.Deserialize<CrmWebApiError>(strContent);
                    UtilityException ex          = null;
                    bool             canContinue = false;
                    TextFragment     fragment;
                    switch ((int)response.StatusCode)
                    {
                    case 412:
                        fragment = new TextFragment()
                        {
                            Code = TextCodes.CrmWebApiConcurrencyError,
                            DefaultFormatting = "调用Crm的webapi出现并发性错误,Uri:{0},Body:{1},错误信息:{2}",
                            ReplaceParameters = new List <object>()
                            {
                                response.RequestMessage.RequestUri.ToString(), requestBody, strContent
                            }
                        };
                        ex = new UtilityException((int)Errors.CrmWebApiConcurrencyError, fragment);
                        break;

                    case 429:
                        if (retryNumber >= request.MaxRetry)
                        {
                            fragment = new TextFragment()
                            {
                                Code = TextCodes.CrmWebApiLimitError,
                                DefaultFormatting = "调用Crm的webapi出现限制性错误,Uri:{0},Body:{1},错误信息:{2}",
                                ReplaceParameters = new List <object>()
                                {
                                    response.RequestMessage.RequestUri.ToString(), requestBody, strContent
                                }
                            };

                            ex = new UtilityException((int)Errors.CrmWebApiLimitError, fragment);
                        }
                        else
                        {
                            await Task.Delay(response.Headers.RetryAfter.Delta.Value);

                            //System.Threading.Thread.Sleep(response.Headers.RetryAfter.Delta.Value);
                            canContinue = true;
                        }
                        break;

                    default:
                        fragment = new TextFragment()
                        {
                            Code = TextCodes.CrmWebApiCommonError,
                            DefaultFormatting = "调用Crm的webapi出现错误,Uri:{0},Body:{1},错误信息:{2}",
                            ReplaceParameters = new List <object>()
                            {
                                response.RequestMessage.RequestUri.ToString(), requestBody, strContent
                            }
                        };

                        ex = new UtilityException((int)Errors.CrmWebApiCommonError, fragment);
                        break;
                    }

                    if (ex != null)
                    {
                        throw ex;
                    }

                    if (!canContinue)
                    {
                        break;
                    }
                }
                else
                {
                    break;
                }
            }
        }
Beispiel #2
0
        public async Task <CrmResponseMessage> Execute(CrmRequestMessage request)
        {
            //填充request属性
            request.ApiVersion      = CrmApiVersion;
            request.MaxRetry        = CrmApiMaxRetry;
            request.OrganizationURI = CrmUrl;

            var handle        = _crmMessageHandleSelector.Choose(request.GetType().FullName);
            var requestResult = await handle.ExecuteRequest(request);

            string strContentType     = null;
            string strContentChartSet = null;
            Dictionary <string, string> contentParameters = new Dictionary <string, string>();

            HttpClient httpClient = null;

            if (TokenServiceType.ToLower() == CrmServiceTokenGenerateServiceNames.AD.ToLower())
            {
                var userName = TokenServiceParameters[CrmServiceTokenGenerateServiceParameterNames.UserName].ToString();
                var password = TokenServiceParameters[CrmServiceTokenGenerateServiceParameterNames.Password].ToString();
                var domain   = TokenServiceParameters[CrmServiceTokenGenerateServiceParameterNames.Domain].ToString();
                httpClient = new HttpClient(new HttpClientHandler()
                {
                    Credentials = new NetworkCredential(userName, password, domain)
                });
            }
            else
            {
                httpClient = _httpClientFactory.CreateClient();
            }

            using (httpClient)
            {
                foreach (var headerItem in requestResult.Headers)
                {
                    switch (headerItem.Key.ToLower())
                    {
                    case "content-type":
                        strContentType = await headerItem.Value.ToDisplayString(
                            async (item) =>
                        {
                            return(await Task.FromResult(item));
                        },
                            async() =>
                        {
                            return(await Task.FromResult(";"));
                        }
                            );

                        break;

                    case "content-type-chartset":
                        strContentChartSet = headerItem.Value.First();
                        break;

                    case "accept":
                        httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(headerItem.Value.First()));
                        break;

                    default:
                        if (headerItem.Key.ToLower().StartsWith("content-type-"))
                        {
                            contentParameters[headerItem.Key.Substring(13)] = headerItem.Value.First();
                            break;
                        }
                        httpClient.DefaultRequestHeaders.Add(headerItem.Key, headerItem.Value);
                        break;
                    }
                }


                //判断是否需要加入代理
                if (request.ProxyUserId != null)
                {
                    httpClient.DefaultRequestHeaders.Add("MSCRMCallerID", request.ProxyUserId.ToString());
                }


                HttpResponseMessage responseMessage = null;
                HttpContent         httpContent     = null;
                try
                {
                    await _crmMessageResponseHandle.Execute(request, async() =>
                    {
                        //获取令牌
                        if (TokenServiceType.ToLower() != CrmServiceTokenGenerateServiceNames.AD.ToLower())
                        {
                            var tokenService = _crmServiceTokenGenerateServiceSelector.Choose(TokenServiceType);
                            var strToken     = await tokenService.Genereate(TokenServiceParameters);

                            httpClient.DefaultRequestHeaders.Add("Authorization", strToken);
                        }


                        switch (requestResult.Method.Method.ToLower())
                        {
                        case "get":
                            responseMessage = await httpClient.GetAsync(requestResult.Url);
                            break;

                        case "post":

                            if (requestResult.ReplaceHttpContent == null)
                            {
                                httpContent = new StringContent(requestResult.Body);
                                if (strContentType != null)
                                {
                                    httpContent.Headers.ContentType = new MediaTypeHeaderValue(strContentType);
                                    if (strContentChartSet != null)
                                    {
                                        httpContent.Headers.ContentType.CharSet = strContentChartSet;
                                    }
                                    foreach (var item in contentParameters)
                                    {
                                        httpContent.Headers.ContentType.Parameters.Add(new NameValueHeaderValue(item.Key, item.Value));
                                    }
                                }
                            }
                            else
                            {
                                httpContent = requestResult.ReplaceHttpContent;
                            }
                            responseMessage = await httpClient.PostAsync(requestResult.Url, httpContent);

                            break;

                        case "put":

                            if (requestResult.ReplaceHttpContent == null)
                            {
                                httpContent = new StringContent(requestResult.Body);
                                if (strContentType != null)
                                {
                                    httpContent.Headers.ContentType = new MediaTypeHeaderValue(strContentType);
                                    if (strContentChartSet != null)
                                    {
                                        httpContent.Headers.ContentType.CharSet = strContentChartSet;
                                    }
                                    foreach (var item in contentParameters)
                                    {
                                        httpContent.Headers.ContentType.Parameters.Add(new NameValueHeaderValue(item.Key, item.Value));
                                    }
                                }
                            }
                            else
                            {
                                httpContent = requestResult.ReplaceHttpContent;
                            }
                            responseMessage = await httpClient.PutAsync(requestResult.Url, httpContent);

                            break;

                        case "patch":

                            if (requestResult.ReplaceHttpContent == null)
                            {
                                httpContent = new StringContent(requestResult.Body);
                                if (strContentType != null)
                                {
                                    httpContent.Headers.ContentType = new MediaTypeHeaderValue(strContentType);
                                    if (strContentChartSet != null)
                                    {
                                        httpContent.Headers.ContentType.CharSet = strContentChartSet;
                                    }
                                    foreach (var item in contentParameters)
                                    {
                                        httpContent.Headers.ContentType.Parameters.Add(new NameValueHeaderValue(item.Key, item.Value));
                                    }
                                }
                            }
                            else
                            {
                                httpContent = requestResult.ReplaceHttpContent;
                            }

                            responseMessage = await httpClient.PatchAsync(requestResult.Url, httpContent);

                            break;

                        case "delete":
                            responseMessage = await httpClient.DeleteAsync(requestResult.Url);
                            break;

                        default:
                            TextFragment fragment = new TextFragment()
                            {
                                Code = TextCodes.CrmMessageExecuteNotSupportMethod,
                                DefaultFormatting = "Crm消息处理不支持名称为{0}的HttpMethod",
                                ReplaceParameters = new List <object>()
                                {
                                    requestResult.Method.Method
                                }
                            };
                            throw new UtilityException((int)Errors.CrmMessageExecuteNotSupportMethod, fragment);
                        }

                        return(responseMessage);
                    });
                }
                finally
                {
                    if (httpContent != null)
                    {
                        httpContent.Dispose();
                    }
                }
                Dictionary <string, IEnumerable <string> > responseHeaders = new Dictionary <string, IEnumerable <string> >();
                foreach (var headerItem in responseMessage.Headers)
                {
                    responseHeaders.Add(headerItem.Key, headerItem.Value);
                }
                var result = await handle.ExecuteResponse(requestResult.Extension, requestResult.Url, requestResult.Body, (int)responseMessage.StatusCode, responseHeaders, await responseMessage.Content.ReadAsStringAsync(), responseMessage);

                return(result);
            }
        }