2017-01-31 33 views
0

我正嘗試使用HttpClient.PostAsync將json發送到Web API。它可以從控制檯應用程序運行,但不能從我的CRM插件運行。做了一些研究,我注意到它可能與插件運行和線程的上下文有關。反正這是我的調用代碼:HttpClient PostAsync在CRM插件中不起作用

public async void Execute(IServiceProvider serviceProvider) 
    { 
     IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); 

     if (context.InputParameters.Contains("Target")) 
     { 
      if (context.InputParameters["Target"] is Entity) 
      { 
       Entity entity = (Entity)context.InputParameters["Target"]; 

       if (entity.LogicalName == "new_product") 
       { 
        IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); 
        IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId); 

        try 
        { 
         if (entity.Contains("new_begindate") && entity.Contains("new_expirationdate")) 
         { 
          await OnlineSignUp(entity, service); 
         } 
        } 
        catch (InvalidPluginExecutionException) 
        { 
         throw; 
        } 
        catch (Exception e) 
        { 
         throw new InvalidPluginExecutionException(OperationStatus.Failed, "Error signing up: " + e.Message); 
        } 
       } 
      } 
     } 
    } 

,這裏是發送json的相關代碼:

private async Task<HttpResponseMessage> OnlineSignUp(Entity license, IOrganizationService service) 
    { 
     ... 

     var json = JsonConvert.Serialize(invitation); 
     var content = new StringContent(json, Encoding.UTF8, "application/json"); 

     var httpClient = new HttpClient(); 
     httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Token", "token=7d20f3f09ef24067ae64f4323bc95163"); 
     Uri uri = new Uri("http://signup.com/api/v1/user_invitations"); 
     var response = await httpClient.PostAsync(uri, content).ConfigureAwait(false); 
     int n = 1; 
     return response; 
    } 
} 

將引發異常,消息「正在中止線程」。誰能告訴我我做錯了什麼?

+0

更新:不僅不能在調試。當我從CRM運行它時,它確實有效。 – gareth99

回答

6

我猜這是怎麼回事基於使用的異步/等待對該有些隨機失敗。我不認爲CRM確實支持插件在完成之前返回控制權。當它失敗時,看起來線程正在幕後清理。

CRM已經處理插件的多線程,並且支持將插件步驟註冊爲異步,如果它們長時間運行(或不需要在同步管道中運行)。它將使更多的意義在這裏使用同步HTTP調用,比如:

var response = httpClient.PostAsync(uri, content).Result;

編輯:爲了說明這一點,這是什麼是最有可能發生的過於輕視例如,當CRM去開球插件並且你正在使用async/await(來自LinqPad)。

static async void CrmInternalFunctionThatKicksOffPlugins() 
{ 
    var plugin = new YourPlugin(); 
    //NOTE Crm is not going to "await" your plugin execute method here 
    plugin.Execute(); 
    "CRM is Done".Dump(); 
} 

public class YourPlugin 
{ 
    public async void Execute() 
    { 
     await OnlineSignUp(); 
    } 

    private async Task<HttpResponseMessage> OnlineSignUp() 
    { 
     var httpClient = new HttpClient(); 
     var r = await httpClient.PostAsync("http://www.example.com", null); 
     "My Async Finished".Dump(); 
     return r; 
    } 
} 

,它將打印:

CRM完成
我的異步完成

+0

我同意這個答案,並將第二個建議移動到一個異步插件 - 如果你擔心延遲返回給用戶。如果你看看CRM的插件體系結構,在插件中使用async/await調用沒有任何意義。由於管道是同步的,你已經有一個執行它的線程,所以你沒有真正從等待中獲得用戶或系統資源的好處。 – Nicknow