C# 从MVC6/WepApi控制器返回错误字符串

C# 从MVC6/WepApi控制器返回错误字符串,c#,asp.net,asp.net-web-api,asp.net-core-mvc,C#,Asp.net,Asp.net Web Api,Asp.net Core Mvc,MVC6/WebApi中的模板WebApi控制器实现了一个操作,该操作返回Get方法的集合,如下所示: [HttpGet] public IEnumerable<MyEntity> Get() { //my code to return entities } [HttpGet] 公共IEnumerable Get() { //返回实体的代码 } 假设返回结果的代码抛出异常,如何向使用者返回错误消息 据我所知,一个异常将导致HTTP 500。这很好,但我想给打电话的人一个信

MVC6/WebApi中的模板WebApi控制器实现了一个操作,该操作返回Get方法的集合,如下所示:

[HttpGet]
public IEnumerable<MyEntity> Get()
{
    //my code to return entities
}
[HttpGet]
公共IEnumerable Get()
{
//返回实体的代码
}
假设返回结果的代码抛出异常,如何向使用者返回错误消息


据我所知,一个异常将导致HTTP 500。这很好,但我想给打电话的人一个信息,告诉他出了什么问题。由于模板操作的签名,我无法捕获异常并返回一些Http***或
ObjectResult
实例

就像您希望保持任何程序运行一样

try {
    ...
} catch (Exception e) {
    return errorMessageView;
}

或者,您可以使用。

您需要自己添加一些代码来处理错误并返回消息

一个选项是使用异常过滤器,并将其全局添加或添加到选定的控制器上,尽管此方法仅涵盖来自控制器操作方法的异常。例如,只有当请求接受为application/json时,以下过滤器才会返回一个json对象(否则它会让异常通过,例如可以由全局错误页面处理):

另一个选项是您可以更改签名,以使提供响应更灵活。然后,您可以像平常一样处理错误,然后返回一条用户友好的错误消息。

public IActionResult Get(){
试一试{
可数结果;
//…结果已填充
返回新的HttpOkObjectResult(结果);
}捕获(例外情况除外){
//你应该处理这个错误
HandleError(ex);//不是实际的方法。请创建自己的方法。
//然后,您可以创建自己的错误,以避免泄漏
//内部信息。
var错误=新
{ 
message=“输入用户友好的错误消息”,
status=Microsoft.AspNetCore.Http.StatusCodes.Status500InternalServerError
};
Context.Response.StatusCode=error.status;
返回新的ObjectResult(错误);
}
}

将方法更改为

[HttpGet]
[ResponseType(typeof(IEnumerable<MyEntity>))]
public IHttpActionResult Get()
{
    //when ok
    return Ok(response); // response is your IEnumerable<MyEntity>

    //when error
    throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.WhateverStatusCodeSuitable)
            {
                ReasonPhrase = "your message"
            });

}
[HttpGet]
[责任类型(类型(IEnumerable))]
public IHttpActionResult Get()
{
//什么时候可以
返回Ok(response);//response是您的IEnumerable
//出错时
抛出新的HttpResponseException(新的HttpResponseMessage(HttpStatusCode.WhateverStatusCodeSuitable)
{
ReasonPhrase=“您的邮件”
});
}

您可以处理异常,但我觉得我们不应该再这样想了。这似乎是MVC6的禅:

    [HttpGet("{id}")]
    [ProducesResponseType(typeof(IEnumerable<string>), 200)]
    [ProducesResponseType(typeof(void), 404)]
    public IActionResult Get(int id)
    {
        Product product = null;
        if (!this.productRepository.TryGet(id, out product))
        {
            return NotFound();
        }

        return Ok(product);
    }
[HttpGet(“{id}”)]
[产品响应类型(typeof(IEnumerable),200)]
[产品响应类型(typeof(void),404)]
公共IActionResult Get(int id)
{
Product=null;
if(!this.productRepository.TryGet(id,out product))
{
返回NotFound();
}
返回Ok(产品);
}

对于anserw来说可能有点晚了,但是现在使用自定义代码获得自定义错误的最佳方法似乎是使用StatusCode方法

` [HttpGet("{id}")]
[ProducesResponseType(typeof(IEnumerable<string>), 200)]
[ProducesResponseType(typeof(void), 404)]
public IActionResult Get(int id)
{
    Product product = null;
    if (!this.productRepository.TryGet(id, out product))
    {
        return StatsusCode(500, "NotFound");
    }

    return Ok(product);
}`
`[HttpGet(“{id}”)]
[产品响应类型(typeof(IEnumerable),200)]
[产品响应类型(typeof(void),404)]
公共IActionResult Get(int id)
{
Product=null;
if(!this.productRepository.TryGet(id,out product))
{
返回StatusCode(500,“未找到”);
}
返回Ok(产品);
}`

谢谢,但我想我还不够清楚。我正在编写一个API,所以我不想返回一个视图。客户端应该检查Http OK(200)或500(内部错误)。如果客户得到500,他应该能够显示一条错误消息。如何从异常处理程序向客户端获取此错误消息?搜索HandleErrorAttribute时,我找到了HttpResponseException,但MVC 6中似乎不支持它。您能否返回JSON
{'result':'error','status',500}
?仅当我更改return语句时返回,但这感觉不自然,因为控制器模板总是使用返回的集合创建Get操作。从其他人的建议来看,最好的方法似乎是让异常失效,并实现一个过滤器或错误中间件。看看问题的答案看起来不错,但正如本文中所解释的,HttpResponseException不再可用。加上您提供的链接,有三种可能的实现方法。我看看什么最合适。我会接受你的回答!如果只是关于找到或没有找到,那就好了。但是,在现实场景中发生的所有实际异常,比如数据库损坏、嵌套服务不可用以及程序员引入的bug,又如何呢。我同意IActionResult会给我返回所需内容的自由,但这意味着我必须捕获每个控制器方法中的异常,以便将其转换为类似“发生错误,请咨询…”(至少)。无论您是否喜欢,所有这些异常都会转换为某种形式的HTTP结果。在我看来,这只是捕获了这个范例,而不是给人一种假象,认为某个异常实际上被传递回了客户机。我同意你关于这个范例的看法,并且我在我的大多数方法中使用了与你类似的代码。另一方面,看看Nkosi答案中的第二个代码片段。我真的不想在我的每个控制器中都有这样的代码。我的问题是,默认异常处理程序只向客户端返回代码500,而没有任何错误文本。这就是为什么我喜欢CustomExceptionFilter解决方案。
    [HttpGet("{id}")]
    [ProducesResponseType(typeof(IEnumerable<string>), 200)]
    [ProducesResponseType(typeof(void), 404)]
    public IActionResult Get(int id)
    {
        Product product = null;
        if (!this.productRepository.TryGet(id, out product))
        {
            return NotFound();
        }

        return Ok(product);
    }
` [HttpGet("{id}")]
[ProducesResponseType(typeof(IEnumerable<string>), 200)]
[ProducesResponseType(typeof(void), 404)]
public IActionResult Get(int id)
{
    Product product = null;
    if (!this.productRepository.TryGet(id, out product))
    {
        return StatsusCode(500, "NotFound");
    }

    return Ok(product);
}`