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相关问答推荐

后台线程上的延迟WriteableBitmap写入导致闪烁

ASP.NET Core将SON重新序列化为派生类

Plotly.NET访问互联网时出现异常

在C#中使用in修饰符

在一个模拟上设置一个方法,该模拟具有一个参数,该参数是一个numc函数表达式

在路由中使用枚举

在具有不同属性名称的两个类之间创建关系

在EF Core中,有没有什么方法可以防止在查询中写入相同的条件,而代之以表达式?

将字节转换为 struct 并返回

Swagger没有显示int?可以为空

如何使用.NET6WPF打印车票?

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

升级后发出SWITCH语句

EF Core:如何对关系属性进行建模?

错误:此版本的Visual Studio无法打开以下项目

从GRPC连接创建ZipArchive

如何使用IHostedService添加数据种子方法

为什么连接到Google OAuth2后,结果.Credential为空?

.NET6最小API:操作.MapGet之后的响应

Avalonia MVVM数据模板