Asp.net core 如何从要由客户端代码解析的API传递特定于域的错误

Asp.net core 如何从要由客户端代码解析的API传递特定于域的错误,asp.net-core,asp.net-core-webapi,Asp.net Core,Asp.net Core Webapi,我正在使用ASP.NETCore创建一个API。该API不公开;它的目的是由我们正在开发的特定B2B/B2E移动应用程序单独使用 我需要准确地告诉移动应用程序发生了什么样的错误,以便它能够显示有用的错误消息。状态代码本身不足以实现这一点,因为相同的状态代码可以覆盖几个不同的特定于域的错误,这些错误应该在应用程序中加以区分。因此,实现这一点的唯一方法似乎是发送神奇的字符串,最好在API和移动应用程序项目引用的共享项目中定义。到目前为止,一切顺利 我第一次使用ASP.NET Web API 2(不是

我正在使用ASP.NETCore创建一个API。该API不公开;它的目的是由我们正在开发的特定B2B/B2E移动应用程序单独使用

我需要准确地告诉移动应用程序发生了什么样的错误,以便它能够显示有用的错误消息。状态代码本身不足以实现这一点,因为相同的状态代码可以覆盖几个不同的特定于域的错误,这些错误应该在应用程序中加以区分。因此,实现这一点的唯一方法似乎是发送神奇的字符串,最好在API和移动应用程序项目引用的共享项目中定义。到目前为止,一切顺利

我第一次使用ASP.NET Web API 2(不是核心),在那里我的控制器返回了
IHttpActionResult
,我可以简单地
返回这个.ResponseMessage(新的HttpResponseMessage{StatusCode=myStatusCode,ReasonPhase=MyReasonPhase})
(我将此创建委托给控制器上的一个简单助手方法,因此操作非常简洁)。但是,
ResponseMessageResult
似乎没有在ASP.Net Core中定义

我以前没有使用ASP.Net Core的经验,似乎在任何地方都找不到我的用例的答案,因此我想知道如何最好地解决这个问题。我想到了一些可能的解决方案:

  • 在控制器中创建带有特定原因短语的错误响应。这是我以前所做的,看起来相当干净和简单
  • 在控制器中抛出异常(或者,最好是来自控制器的依赖项),并使用异常筛选器将其转换为带有特定原因短语的错误响应。我不确定我是否喜欢这样,因为这可能需要我定义尽可能多的自定义异常,作为我想要返回的原因码
  • 对于上述任何一种情况,与其将字符串放在原因短语中,不如将其放在响应正文中的对象中。似乎在原因短语中看到一个神奇的字符串就足够了。尽管我可能会为每个控制器的正常API响应添加一个
    Error
    属性,并简单地返回一个
    ObjectResult
    在所有情况下均有效
我不知道其中哪一种,或者可能完全是另一种解决方案,可能是从ASP.Net核心API传递特定于域的错误的明智方法

如何通过客户端代码解析的ASP.Net Core REST API干净、可靠地传达特定于域的错误?如何做到:

public class SerializableMessage {
    public SerializableMessage(string message)
    {
        Message = message;
    }

    public string Message { get; set; }
}
在我的控制器中

try
{
    // something that throws
} catch (ExpectedException e)
{
    return BadRequest(new SerializableMessage("You messed up");
}
然后,当客户端收到一个非2xx响应时,它会读出(例如,如果内容类型是json)
response.message

在我看来,客户端知道将要发生什么,所以它所需要做的就是失败,或者可能显示一条关于出错原因的消息,因为大多数错误是用户干预无法恢复的

对于modelstate错误,我在
SerializableErrorMessage
类中将它们序列化为
errors
属性,类似于asp.net core已经执行的方式。这提供了指定额外消息错误字符串的选项。对于未捕获的异常,我只允许全局筛选器发送500响应并记录异常ion正在使用某些东西(应用程序洞察)

看看控制器类上可用的方法。Intellisense(不记得实际名称)文档对asp.net核心库非常有用。可能会给你灵感


底线是,拥有一个可序列化的类,该类包含您认为有用的属性。不要依赖神奇的动态对象,我会避免上下文属性(例如endpoint1返回错误endpoint2返回错误消息和错误)记住所需属性时的维护噩梦!

谢谢,这很有帮助。关于“在记住所需属性时,我将避免上下文属性(例如endpoint1返回错误endpoint2返回错误消息和错误)维护噩梦”的评论–如果这是一个反对在响应对象中包含错误属性的论点,我不确定我是否同意。响应对象将在API和客户端之间共享,因此所有内容都将是强类型的。哦,不,我的意思是定义一个具有已知属性的错误对象。而不是一个返回字符串,一个返回字符串错误列表!让两者都返回一个具有错误列表的errors属性的公共对象,例如:)这正是我决定这样做的方式,您可能会想出一些对您和您的团队更有意义的方法,并且效果更好。因此,您认为,拥有
Error
属性可以吗(例如,枚举)在每个响应对象上?例如,
SignInResponse上的
SignError
GetTodoError
上的
GetToError
,等等。然后,我可以反序列化响应,而不依赖于实际的状态代码,这可以稍微简化客户端代码。一个描述符,让您知道对象的pe不是一个坏主意,不!比我们的系统需要的更复杂。但是,如果您需要使用错误返回的数据执行某些操作,这无疑会使错误处理更容易