2017-06-14 61 views
2

我有一個使用MVC Web API 2的服務的WPF應用程序。使用HTTPClient調用異步方法(如PostAsync和GetAsync)創建RestClient包裝器。對於前我的POST方法包裝將如下所示:使用c#調用Web API 2方法HTTPClient使用CLR存儲過程

using (var client = new HttpClient(new HttpClientHandler() 
             { AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip })) 
{ 
    var content = new FormUrlEncodedContent(postObject); 

    SetupClient(client, methodName, apiUrl, postObject, headerContent); 

    if (apiKey != null && appId != null) 
     await SetAuthorizationHeader(client, methodName, apiUrl, appId, apiKey, content).ConfigureAwait(false); 

    using (HttpResponseMessage response = Task.Run(() => client.PostAsync(apiUrl, content)).Result) 
    { 
     response.EnsureSuccessStatusCode(); 

     using (HttpContent httpContent = response.Content) 
     { 
      if (response.IsSuccessStatusCode) 
      { 
       result = response.Content.ReadAsAsync<T>().Result; 
      } 
     } 
    } 
} 

哪個工作正常。現在我正嘗試通過創建SQL Server數據庫項目來通過C#CLR存儲過程調用一些API調用。

C#CLR存儲過程會像:

[Microsoft.SqlServer.Server.SqlProcedure] 
public static void SQLRestClient(SqlString weburl, SqlString postBody, SqlString appIdString, SqlString apiKeyString, SecureString baseAddress, out SqlString returnval) 
{ 
    string apiUrl = Convert.ToString(weburl); 
    string baseAddressString = Convert.ToString(baseAddress); 

    string result = string.Empty; 
    var appId = ConvertToSecureString(Convert.ToString(appIdString)); 
    var apiKey = ConvertToSecureString(Convert.ToString(apiKeyString)); 

    try 
    { 
     string methodName = HttpMethod.Post.Method.ToUpper(); 

     using (var client = new HttpClient(new HttpClientHandler() 
     { 
      AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip 
     })) 
     { 
      var content = new FormUrlEncodedContent(postObject); 

      SetupClient(client, methodName, apiUrl, postObject, headerContent); 

      if (apiKey != null && appId != null) 
       await SetAuthorizationHeader(client, methodName, apiUrl, appId, apiKey, content).ConfigureAwait(false); 

      using (HttpResponseMessage response = Task.Run(() => client.PostAsync(apiUrl, content)).Result) 
      { 
       response.EnsureSuccessStatusCode(); 

       using (HttpContent httpContent = response.Content) 
       { 
        if (response.IsSuccessStatusCode) 
        { 
         result = response.Content.ReadAsStringAsync(); 
        } 
       } 
      } 
     } 
    } 
    catch (Exception ex) 
    { 
     SqlContext.Pipe.Send(ex.Message.ToString()); 
    } 

    returnval = result; 
} 

當我嘗試生成此過程中我得到建立自己的錯誤的DLL。 它,因爲編譯器不能識別集引用如

System.Net.Http.dll

當我通過這個線程

Sending HTTP POST request from SQL Server 2012 or SQL CLR C#

我找到了解決辦法了使用HttpWebRequest而不是HttpClient。由於我一直在我的應用程序中使用HttpClient,我不想切換到HttpWebRequest。

任何人都可以提出任何其他方式,以便我可以通過使用HttpClient生成CLR存儲過程DLL。任何幫助將不勝感激,並提前致謝。

回答

2

沒有,HttpClientSystem.Net.Http找到,該庫是不是supported .NET Framework libraries之一。您可以手動添加該庫,但不應該設置爲UNSAFE,因爲您沒有MS簽名證書,所以需要將數據庫設置爲TRUSTWORTHY ON。它也不能保證工作,因爲SQLCLR只允許純粹的MSIL程序集;混合模式程序集將不會加載。並且當前純MSIL的程序集可以更改爲在.NET Framework更新中混合使用。如果這種情況發生在您加載的不受支持的框架庫上,那麼您的項目將停止工作,您必須重寫它以不使用該庫。

您也不應該在SQLCLR中使用異步調用。這些還要求大會被標記爲UNSAFE,並且在這種環境下通常不是一個好主意。

最好,最安全,最可靠的選擇是使用HttpWebRequestHttpWebResponse

2

默認情況下,SQL服務器上只有一部分.net庫可用,我認爲它們列出了this page

WebRequest是由System.dll加載的System.Net命名空間的一部分,這就是爲什麼您可以輕鬆地將它用作CLR的一部分,以及爲什麼您查看的解決方案可能會使用它。

您可以將其他程序集加載到SQL以供CLR使用,如頁面的「Unsupported Libraries」部分所述。所以我認爲理論上你可以加載使用HttpClient所需的任何程序集,但是如果你想使用擴展,你可能會發現有幾個程序集。

例如HttpClient的是System.Net.Http.dll
的一部分,.PostAsJsonAsync是System.Net.Http.Formatting.dll的一部分

還有用於組件潛在的安全要求,在理想情況下,他們都簽署等,除非您在導入程序集時禁用這些檢查。

我在前面看過這些內容,雖然我沒花太多時間試圖讓HttpClient工作,但我最終使用了WebRequest,因爲不用擔心在外部部署其他程序集我正在創建的那個。

-
作爲參考,在情況下,鏈接斷裂,這是第一個鏈接上列出的庫:

庫/ SQL Server中 由CLR集成支持的命名空間:

  • CustomMarshalers
  • Microsoft.VisualBasic程序
  • Microsoft.VisualC
  • mscorlib程序
  • 系統
  • System.Configuration
  • System.Data
  • System.Data.OracleClient的
  • System.Data.SqlXml
  • System.Deployment
  • System.Security
  • System.Transactions
  • System.Web.Services
  • 的System.Xml
  • System.Core.dll
  • System.Xml.Linq.dll