我有一个使用MVC Web API服务的WPF应用程序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。任何帮助将不胜感激,并提前感谢。
答案 0 :(得分:2)
默认情况下,SQL Server上只有.net库的子集可用,我认为this page列出。
WebRequest是System.dll加载的System.Net命名空间的一部分,这就是为什么你可以轻松地将它作为CLR的一部分使用,以及为什么你看到的解决方案可能会使用它。
您可以将其他程序集加载到SQL中供CLR使用,如&#34; Unsupported Libraries&#34;页面的一部分。所以我认为理论上你可以加载使用HttpClient所需的任何程序集,尽管如果你想使用扩展,你可能会发现有几个程序集。
e.g。 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
答案 1 :(得分:2)
不,HttpClient
中找到System.Net.Http
,该库不是supported .NET Framework libraries中的一个。您可以手动添加该库,但是您不应该将其设置为UNSAFE
,并且需要将数据库设置为TRUSTWORTHY ON
,因为您没有MS签名证书。它也不能保证工作,因为SQLCLR只允许纯MSIL组件;混合模式程序集将不会加载。当前纯MSIL的程序集可以在.NET Framework更新中更改为混合。如果您加载的不受支持的框架库发生这种情况,那么您的项目将停止工作,您必须重写它以不使用该库。
您也不应该在SQLCLR中使用异步调用。这些还要求将大会标记为UNSAFE
,并且在这种环境中一般不是一个好主意。
最好,最安全,最可靠的选择是使用HttpWebRequest
和HttpWebResponse
。