HttpResponseMessage.Content.ReasAsString 返回一个空字符串

Posted

技术标签:

【中文标题】HttpResponseMessage.Content.ReasAsString 返回一个空字符串【英文标题】:HttpResponseMessage.Content.ReasAsString returns an empty string 【发布时间】:2019-10-29 01:10:44 【问题描述】:

我有一个这样称呼的 WS:

HttpResponseMessage response = await client.PostAsync(url, new StringContent(json));

WS 将抛出一个异常(禁止),在我进行 PostAsync 调用的 Blazor 应用程序中,我将得到一个带有响应代码 405 的 HttpResponseMessage,不知道为什么它是 405,它应该是 403(邮递员返回 403) .

我已启用 CORS(ServiceStack 代码):

Plugins.Add(new CorsFeature(allowedOrigins: "*",
  allowedMethods: "GET, POST, PUT, DELETE, OPTIONS",
  allowedHeaders: "*",
  allowCredentials: true));

这是我在 PostAsync 之前所做的一些 Console.Writeline:

加载资源失败:服务器响应状态为405()

** 已更新 **

这是两种方法:

    public async Task<TResponse> PostAsync<TResponse, TRequest>(string requestUri, TRequest request)
    
        string url = GetUrl(requestUri);
        Console.WriteLine("URI: " + url);
        string json = JsonConvert.SerializeObject(request);
        Console.WriteLine($"url | json");
        HttpResponseMessage response = await client.PostAsync(url, new StringContent(json));
        return await GetResponseOrThrowHttpException<TResponse>(response);
    


    private async Task<T> GetResponseOrThrowHttpException<T>(HttpResponseMessage response)
    
        Console.WriteLine($"GetResponseOrThrowHttpException: response.StatusCode");
        string responseString = await response.Content.ReadAsStringAsync();
        Console.WriteLine($"GetResponseOrThrowHttpException ContentStringResult: |responseString|");
        if (!response.IsSuccessStatusCode)
        
            Newtonsoft.Json.Linq.JObject jsonObject = Newtonsoft.Json.Linq.JObject.Parse(responseString);
            string responseStatusString = jsonObject["ResponseStatus"].ToString();

            Console.WriteLine($"GetResponseOrThrowHttpException 4: responseStatusString");
            ResponseStatus responseStatus = JsonConvert.DeserializeObject<ResponseStatus>(responseStatusString);
            Console.WriteLine($"Throwing HttpException: response.StatusCode responseStatus.Message");
            throw new HttpException(response.StatusCode, responseStatus.Message);
        
        return JsonConvert.DeserializeObject<T>(responseString);
    

当我尝试获取响应的字符串值时,它是空的:

string responseString = await response.Content.ReadAsStringAsync();

responseString 是一个空字符串(长度为0)。

如果我在 Postman 中运行完全相同的请求,我会得到有效响应:

因此,在上图底部看到的响应 JSON 是我想在 Blazor 应用程序中使用的,并将其解析为 JSON 对象并从那里继续。 我还注意到,我在这里收到了一个 403 错误,这是我所预料的,而在 Blazor 应用程序中,我收到了一个 405。

即使我在 WS 端启用了 CORS,这是否是一个 CORS 问题?

【问题讨论】:

状态码 405: Method not allowed,这表示你认为的可能不一样,你能调试一下urljson中的内容PostAsync 是的,它对 405 很有趣。我更新了答案,增加了一些代码和 console.writelines 以及 URL(被屏蔽了一点)。它们是相同的,并且都是 POST。 CORS 已启用,我在 WS 中得到了预期的异常。 您的邮递员请求中似乎有很多标头,这些标头对于您在服务器上的请求是否是必要的?我没有看到你添加它们 嗯,Postman 中有 8 个自动添加的标题,我似乎无法删除。但是,在这两种情况下,通过邮递员或 Blazor,服务器中都会抛出相同的异常(我期望和想要的),因此请求到达相同的东西。错误消息“din version....”也是我在 WS 端生成的,因此就 WS 而言它的行为相同。 8 个自动添加的标头与 WS 无关。 哦,Postman 说“这些标头是 Postman 自动生成的,不会随您的请求一起保存”:-) 【参考方案1】:

我猜你的内容应该是这样发布的:

new StringContent(json, Encoding.UTF8, "application/json")

即使这不是你痛苦的原因,最好还是这样使用它......

希望对你有帮助……

【讨论】:

是的,JohnChris 和 codevision 带领我朝着正确的方向前进,并弄清楚了。谢谢=) 您可以使用 Blazor 扩展方法 public static Task PostJsonAsync(this HttpClient httpClient, string requestUri, object content),这样可以省去您的麻烦。 谢谢。是的,我知道那个,但由于某种原因我现在不记得了,我选择不使用它,或者它不起作用......或者什么......不记得了=)【参考方案2】:

验证您是否为域设置了正确的 CORS 配置。 看起来您从 Blazor 应用程序调用了另一个 domain:port 组合。即使这个 C#,浏览器内的所有安全规则仍然适用。

【讨论】:

谢谢,CORS 已设置并正常工作。我有其他允许且工作正常的请求(在此登录测试之前)。 你能运行 Fiddler 并检查实际发送到服务器的内容吗?这样你就会真正看到会发生什么反应? Blazor 没有什么特定的规则,与 JS fetch 相同。很可能这仍然是 CORS 问题,另一种选择是,如果服务器返回 405,您将无法读取内容响应,而这正是您想要的响应。如果您不期望 405,则查找 CORS。 我期待的是 403,而不是 405...邮递员给了我 403,但 Blazor 应用程序给了我 405。 好的,从 Blazor 发送的 DTO(登录对象)似乎不正确(属性均为 NULL),但在 Postman 中,它们是可以的。这可能是问题所在。 你把我引向了正确的方向;它是“Content-Type”=) 默认是plain/text,而不是必需的application/json。这创建了 405。如果您愿意,请在此创建一个答案 =)

以上是关于HttpResponseMessage.Content.ReasAsString 返回一个空字符串的主要内容,如果未能解决你的问题,请参考以下文章