为啥没有将详细的错误消息传递给 HttpClient?

Posted

技术标签:

【中文标题】为啥没有将详细的错误消息传递给 HttpClient?【英文标题】:Why detailed error message is not passed to HttpClient?为什么没有将详细的错误消息传递给 HttpClient? 【发布时间】:2016-10-24 10:23:45 【问题描述】:

我使用的是自动生成的默认 Web Api 控制器。我正在客户端测试验证和错误处理。但不知何故,我意识到详细的错误消息没有传递给客户端。在这两种情况下,如果我抛出 HttpResponseException 或返回 IHttpActionResult,客户端只会看到“错误请求”,但看不到详细消息。谁能解释一下出了什么问题?

     public IHttpActionResult Delete(int id)
    
        if (id <= 0)
        
            var response = new HttpResponseMessage(HttpStatusCode.NotFound)
            
                Content = new StringContent("Id should be greater than zero.", System.Text.Encoding.UTF8, "text/plain"),
                StatusCode = HttpStatusCode.NotFound

            ;
            throw new HttpResponseException(response) // Either this way
        

        var itemToDelete = (from i in Values
                            where i.Id == id
                            select i).SingleOrDefault();

        if (itemToDelete == null)
        
            return BadRequest(string.Format("Unable to find a value for the Id 0", id)); // Or This way
        

        Values.Remove(itemToDelete);
        return Ok();
    

客户端代码如下:

 private async static Task DeleteValue(int id)
    

        var url = "http://localhost:13628/api/Values/" + id;
        using (var client = new HttpClient())
        
            var response = await client.DeleteAsync(url);
            if (response.IsSuccessStatusCode)
            
                await ReadValues();
            
            else
            
                Console.WriteLine(response.ReasonPhrase);
                Console.WriteLine(response.StatusCode);
            
        
    

以上都不行??

谢谢

【问题讨论】:

你收到response的消息了吗? 一般而言,暴露 Web 服务器的内部工作对良性用户没有用处,但可能会将缺陷暴露给恶意用户。因此,默认值往往是隐藏详细信息。 【参考方案1】:

在您的客户端更改Console.WriteLine(response.ReasonPhrase);

Console.WriteLine(response.Content.ReadAsStringAsync().Result);

它会给出详细的错误信息。

【讨论】:

【参考方案2】:

将以下代码替换为 Web API 删除操作。使用 HttpResponseMessage 作为 api 的返回 tpye 而不是 IHttpActionResult

        [HttpDelete]
        [Route("id:int:min(1)")]
        public async Task<HttpResponseMessage> DeleteAsync(int id)
        
            if(id < 0 )
            
                return await Task.FromResult<HttpResponseMessage>(Request.CreateResponse<string>(HttpStatusCode.BadRequest, "Id should be greater than zero."));
            
            try
            
                var itemToDelete = (from i in Values
                                    where i.Id == id
                                    select i).SingleOrDefault();

                if (itemToDelete == null)
                
                    return await Task.FromResult<HttpResponseMessage>(Request.CreateResponse<string>(HttpStatusCode.NotFound,
                                        string.Format("Unable to find a value for the Id 0", id))); 
                

                Values.Remove(itemToDelete);
                return await Task.FromResult<HttpResponseMessage>(Request.CreateResponse(HttpStatusCode.OK));
            
            catch (Exception ex)
            
                 return Request.CreateResponse<string>(HttpStatusCode.InternalServerError, "Something went wrong."); // Default message if exception occured
            
        

和客户端:

        private async static Task DeleteValue(int id)
        

            var url = "http://localhost:13628/api/Values/" + id;
            using (var client = new HttpClient())
            
                var response = await client.DeleteAsync(url);
                if (response.IsSuccessStatusCode)
                
                    await ReadValues();
                
                else
                
                    var errorMessage = Newtonsoft.Json.JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
                    // Here Newtonsoft.Json Package is used to deserialize response content 
                    Console.WriteLine(errorMessage);
                    Console.WriteLine(response.StatusCode);
                
            
        

上面的代码在我身边工作。

【讨论】:

以上是关于为啥没有将详细的错误消息传递给 HttpClient?的主要内容,如果未能解决你的问题,请参考以下文章

为啥将 ViewModel 传递给 View 时会出现此错误?

我将 QPixmap 传递给 QAbstractButton::setIcon 而不是 QIcon,但我没有收到错误...为啥?

为啥在没有 ref 的情况下将 list 传递给一个类似于通过 ref 传递的函数?

为啥 docker-compose build 没有给我这样的文件或目录错误消息

为啥将 C-Array 传递给函数时 sizeof() 值错误? [复制]

当我们不传递任何命令行参数时,为啥我们不会得到错误?