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

标签 c# .net sql-server asp.net-web-api sqlclr

我有一个使用 MVC Web API 2 服务的 WPF 应用程序。使用 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。任何帮助将不胜感激,并提前致谢。

最佳答案

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

您也不应该在 SQLCLR 中使用异步调用。这些还需要将程序集标记为 UNSAFE,并且在这种环境中通常不是一个好主意。

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

关于c# - 通过 HTTPClient 使用 c# CLR 存储过程调用 Web API 2 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44539999/

相关文章:

c# - 一般的奇怪行为

c# - 如何测试类在 C# 中是否正常工作?

c# - 当我将 TimeSpan.Zero 作为过期项添加到缓存时会发生什么?

java - Xamarin Android 垂直 ViewPager

c# - OleDbConnection 仅当工作簿也在 Excel 中打开时才查找单元格值

c# - 相当于 C# BigInteger 的 SQL

sql-server - 尽管凭据正确,Azure SQL Server 连接错误 - 错误号 :18456, 状态 :1, 类别:14

c# - VC++和C#如何编写托管DLL或非托管DLL?

c# - IronPython DLR;将参数传递给编译代码?

sql - 如何将 SQL PIVOT 用于多个聚合?