使用HTTPClient的c#CLR存储过程调用Web API 2方法

问题描述 投票:2回答:2

我有一个WPF应用程序,它使用MVC Web API 2的服务。使用HTTPClient创建RestClient包装器来调用异步方法,如PostAsync和GetAsync。对于我的POST方法包装器将是这样的:

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。任何帮助将不胜感激,并提前感谢。

c# .net sql-server asp.net-web-api sqlclr
2个回答
2
投票

不,HttpClientSystem.Net.Http被发现,并且那个图书馆不是supported .NET Framework libraries之一。您可以手动添加该库,但不应该因为它需要设置为UNSAFE而需要将数据库设置为TRUSTWORTHY ON,因为您没有MS签名证书。它也不能保证工作,因为SQLCLR只允许纯MSIL组件;混合模式程序集将不会加载。当前纯MSIL的程序集可以在.NET Framework更新中更改为混合。如果您加载的不受支持的框架库发生这种情况,那么您的项目将停止工作,您必须重写它以不使用该库。

您也不应该在SQLCLR中使用异步调用。这些还要求大会标记为UNSAFE,并且在这种环境中一般不是一个好主意。

最好,最安全,最可靠的选择是使用HttpWebRequestHttpWebResponse


2
投票

默认情况下,SQL Server上只有.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.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
© www.soinside.com 2019 - 2024. All rights reserved.