try 使用HttpClient从身份服务器获取令牌时出现获取415不支持的媒体类型错误.但当我使用RestClient时,它可以工作.为什么它不能与HttpClient一起工作.

以下是使用HttpClient的代码

HttpClient _client = new HttpClient();
string clientId = "clientid";
string issuer = "https://ourrdomain/token";
string secretKey = "secret";

var byteArray = System.Text.Encoding.ASCII.GetBytes(clientId + ":" + secretKey);
var httpRequestMessage = new HttpRequestMessage
{
    Method = HttpMethod.Post,
    RequestUri = new Uri(issuer),
    Headers = {
        { HttpRequestHeader.Authorization.ToString(), "Basic " + Convert.ToBase64String(byteArray) },
        { HttpRequestHeader.ContentType.ToString(), "application/x-www-form-urlencoded" },
        { HttpRequestHeader.CacheControl.ToString(), "no-cache" },
        { "grant_type", "client_credentials" }
    }
};
var response = _client.SendAsync(httpRequestMessage).Result;

下面是使用RestClient的代码

var request = new RestRequest();
var client = new RestClient(issuer);
string clientId = "clientid";
string issuer = "https://ourrdomain/token";
string secretKey = "secret";
var byteArray = System.Text.Encoding.ASCII.GetBytes(clientId + ":" + secretKey);
request.Method = Method.Post;
request.AddHeader("cache-control", "no-cache");
request.AddHeader("content-type", "application/x-www-form-urlencoded");
request.AddHeader("Authorization", "Basic " + Convert.ToBase64String(byteArray));
request.AddParameter("grant_type", "client_credentials");
var response2 = client.Execute(request);

推荐答案

100

HttpClient代码中的415不受支持的媒体类型错误可能是由于内容类型和正文的设置方式造成的.在HttpClient代码中,您直接设置了ContentType头,但没有以正确的格式提供正文内容

application/x-www-form-urlencoded.

HttpRequestMessage应该包含一个HttpContent对象,该对象具有正确设置的内容类型和编码为表单数据的主体.

以下是修复HttpClient代码的方法:

HttpClient _client = new HttpClient();
string clientId = "clientid";
string issuer = "https://ourrdomain/token";
string secretKey = "secret";

var byteArray = System.Text.Encoding.ASCII.GetBytes($"{clientId}:{secretKey}");
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
_client.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue { NoCache = true };

var requestData = new Dictionary<string, string>
{
    { "grant_type", "client_credentials" }
};
HttpContent content = new FormUrlEncodedContent(requestData);

var response = _client.PostAsync(issuer, content).Result;
  • 凭据将添加到默认请求标头中,该标头为 以更简洁的方式添加不经常更改的标头.
  • 表单数据正在以HttpContent的形式使用 FormUrlEncodedContent,它正确设置了Content-Type标头 到application/x-www-form-urlencoded.
  • 我们使用HttpClientPostAsync方法,它负责设置 正确的Content-Type报头并对内容进行编码.

确保正确处理结果,最好使用Async/AWait而不是.Result,以避免死锁并提高性能.下面是一个使用async/await的示例:

public async Task<TokenResponse> GetTokenAsync()
{
    // ... other code ...

    var response = await _client.PostAsync(issuer, content);
    if (response.IsSuccessStatusCode)
    {
        var json = await response.Content.ReadAsStringAsync();
        // Deserialize the JSON response to a token response object
        var tokenResponse = JsonConvert.DeserializeObject<TokenResponse>(json);
        return tokenResponse;
    }
    else
    {
        // Handle the error, log it, etc.
        return null;
    }
}

在这个async方法中,我们异步处理HTTP调用并返回反序列化的令牌响应对象.在try 阅读内容之前,始终判断响应是否成功.

Csharp相关问答推荐

有没有一种方法可以防止在编译时在MicrosoftC或非单线程上下文中调用方法?

如何注册实现同一接口的多个服务并注入到控制器构造函数中

ASP.NET Core 8.0 JWT验证问题:尽管令牌有效,但SecurityTokenNoExpirationError异常

将轮询与超时同步

为什么在使用动态obj+类obj时会调用串联?

TCPClient阅读流

如何使用XmlSerializer序列化带有CDATA节的XML文件?

在try 使用访问服务器上的文件夹时,如何解决CORS错误.NET核心API

在Docker容器中运行API项目时,无法本地浏览到index.html

无法使用[FromForm]发送带有图像和JSON的多部分请求

当我try 在与XAMP的MySQL服务器连接的ASP.NET核心应用程序中添加迁移时出现错误

未在Windows上运行的Maui项目

获取混淆&Quot;模糊引用&Quot;错误

我的命名管道在第一次连接后工作正常,但后来我得到了System.ObjectDisposedException:无法访问关闭的管道

此异步方法在重写方法中缺少等待运算符警告

流畅的验证--如何为属性重用规则?

C#USB条形码 scanner 在第二次扫描时未写入行尾字符

SharpZipLib在文件名前加上目录名,生成tar.gz

如何使用LINQ在C#中填充列表列表?

如何防止创建的线程超过可用硬件线程数?