gpt4 book ai didi

c# Web Api - 所有 api 响应的通用包装器类

转载 作者:行者123 更新时间:2023-12-04 13:22:56 25 4
gpt4 key购买 nike

几天以来,我一直在尝试弄清楚如何从我的 web api 通用响应返回 - 一个包装类,其中一个属性将具有动态指向的类型。

下面的代码片段显示了我想要实现的目标:

[RoutePrefix("api")]
public class TestController : ApiController
{
[HttpGet]
[Route("test")]
public HttpResponseMessage Test3()
{
Smth smth = new Smth()
{
Something = "dsfdsfdsfs"
};

object apiResponse = this.GetResponse(true, smth);

return base.Request.CreateResponse(HttpStatusCode.OK, apiResponse);
}

public object GetResponse(bool isSuccess, dynamic responseObject, string[] messages = null)
{
return new
{
is_success = isSuccess,
response_object = responseObject,
messages = messages
};
}
}

不幸的是,这个方法不起作用 - 我仍然得到:

异常消息

无法执行 <>f__AnonymousType0`3[System.Boolean,System.Object,System.String[]] 类型的序列化 ...

异常类型

System.Runtime.Serialization.InvalidDataContractException

堆栈跟踪

System.Runtime.Serialization.DataContract.DataContractCriticalHelper.ThrowInvalidDataContractException(String message, Type type) w System.Runtime.Serialization.DataContract.DataContractCriticalHelper.CreateDataContract(Int32 id, RuntimeTypeHandle typeHandle, Type type) w System.Runtime.Serialization.DataContract.DataContractCriticalHelper.GetDataContractSkipValidation(Int32 id, RuntimeTypeHandle typeHandle, Type type) w System.Runtime.Serialization.DataContractSerializer.GetDataContract(DataContract declaredTypeContract, Type declaredType, Type objectType) w System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) w System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) w System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) w System.Runtime.Serialization.DataContractSerializer.WriteObject(XmlWriter writer, Object graph) w System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content) w System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken) --- Koniec śladu stosu z poprzedniej lokalizacji, w której wystąpił wyjątek --- w System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) w System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) w System.Net.Http.HttpContent.d__49.MoveNext() --- Koniec śladu stosu z poprzedniej lokalizacji, w której wystąpił wyjątek --- w System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) w System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) w System.Web.Http.Owin.HttpMessageHandlerAdapter.d__13.MoveNext()

在我的研究过程中,我在论坛上发现了一些效果很好的例子:

[RoutePrefix("api")]
public class TestController : ApiController
{
[HttpGet]
[Route("test")]
public HttpResponseMessage Test3()
{
Smth smth = new Smth()
{
Something = "dsfdsfdsfs"
};

var apiReponse = new
{
is_success = true,
response_object = smth,
messages = new string[] { "dsfsfdds" }
};

return base.Request.CreateResponse(HttpStatusCode.OK, apiReponse);
}
}

以上示例有效并返回正确格式的数据,但这种方法会导致与命名相关的错误(这样我每次返回时都必须指定响应结构)。

在我看来,这两种方法没有区别,除了第一种情况我们得到匿名类型,第二种情况我们使用对象。

那么问题是:

我的第一种方法是否可行?

最佳答案

注意:虽然这不是您问题的答案,但我想发表评论,以免其他人被误导。

我强烈建议对每个场景都使用 200(OK)响应是不合适的,也是 RESTful 的。

如果响应代码始终为 200(正常),即使出现错误,客户端也必须为每个响应检查 is_success = true,

正如 MDN 引用的:( LINK )

The HTTP response codes should be used properly for e.g. HTTP response status codes indicate whether a specific HTTP request has been successfully completed. Responses are grouped into five classes:

  • 信息回复 (100–199)
  • 成功回复 (200–299)
  • 重定向 (300–399)
  • 客户端错误 (400–499)
  • 服务器错误 (500–599)

例如,

  • 如果请求包含无效数据或不包含所需的您应该返回 400(错误请求)的字段。
  • 如果服务器出现意外错误则使用 500(内部服务器错误)
  • 如果在服务器上创建了新资源,则使用 201(已创建)

我还建议阅读有关正确使用 HTTP 方法的内容。 ( LINK )

至于一般响应,您可以在成功响应中返回类似这样的内容:(这完全是我的结构,可能不是最佳实践)

{
ResponseCode:1,
Message:"User created",
Data:{//Any complex object
purchases:[
{data 1},
{data 2}
]
},
Exception:null
}

如果服务器出错(仅用于开发):

{
ResponseCode:2,
Message:"Caught in Global exception filter",
Data:null,
Exception: {//Do not send this in production
Message: "An error has occurred.",
ExceptionMessage:,
ExceptionType":,
StackTrace: ,
InnerException: {
}
}
}

此处 ResponseCode 是您的自定义代码,可用于更详细地描述问题,例如上面例子中的ResponseCode:2表示错误被全局异常处理器捕获。

关于c# Web Api - 所有 api 响应的通用包装器类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47001587/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com