2017-06-14 60 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