c#Web Api-所有Api响应的通用包装类
几天以来,我一直在试图弄清楚如何从web api通用响应返回—一个包装类,其中一个属性将具有动态指向的类型 下面的代码片段显示了我想要实现的目标:c#Web Api-所有Api响应的通用包装类,c#,generics,asp.net-web-api,dynamic,wrapper,C#,Generics,Asp.net Web Api,Dynamic,Wrapper,几天以来,我一直在试图弄清楚如何从web api通用响应返回—一个包装类,其中一个属性将具有动态指向的类型 下面的代码片段显示了我想要实现的目标: [RoutePrefix("api")] public class TestController : ApiController { [HttpGet] [Route("test")] public HttpResponseMessage Test3() { Smth smth = new Smth()
[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(字符串
消息,类型)w
System.Runtime.Serialization.DataContract.DataContractCriticalHelper.CreateDataContract(Int32
id,RuntimeTypeHandle类型句柄,类型类型)w
System.Runtime.Serialization.DataContract.DataContractCriticalHelper.GetDataContractSkipValidation(Int32
id,RuntimeTypeHandle类型句柄,类型类型)w
System.Runtime.Serialization.DataContractSerializer.GetDataContract(DataContract
declaredTypeContract,类型declaredType,类型objectType)w
System.Runtime.Serialization.DataContractSerializer.InternalWriteObject内容(XmlWriterDelegator
写入程序,对象图,DataContractResolver(DataContractResolver)w
System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator
写入程序,对象图,DataContractResolver(DataContractResolver)w
System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator
写入程序,对象图,DataContractResolver(DataContractResolver)w
System.Runtime.Serialization.DataContractSerializer.WriteObject(XmlWriter
编写器,对象图)w
System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStream(类型
类型、对象值、流写入流、HttpContent(内容)w
System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStreamAsync(类型
类型、对象值、流writeStream、HttpContent、,
TransportContext TransportContext,CancellationToken
取消代币)——康涅克·拉杜·斯托苏z poprzedniej lokalizacji,w
克托雷杰·怀斯特·皮耶杰·怀特克——w
System.Runtime.CompilerServices.TaskWaiter.ThrowForNonSuccess(任务
任务)w
System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务
任务)w
System.Net.Http.HttpContent.d__49.MoveNext()
---科尼科拉杜·斯托苏·洛卡利扎吉,w której wystąpiłwyjątek---w
System.Runtime.CompilerServices.TaskWaiter.ThrowForNonSuccess(任务
任务)w
System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务
任务)w
System.Web.Http.Owin.HttpMessageHandlerAdapter.d_u13.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);
}
}
上面的示例可以正常工作并返回正确格式的数据,但这种方法会导致与命名相关的错误(这样,每次返回时我都必须指定响应结构)
从我的观点来看,这两种方法并没有区别,除了在第一种情况下我们得到匿名类型,在第二种情况下我们使用对象
所以问题是:
可以让我的第一种方法工作吗?基本上是将对象序列化为字符串json表示,并返回内容类型“application/json” 返回
{"is_success":true,"response_object":{"Something":"dsfdsfdsfs"},"messages":null}
注意:虽然这不是你问题的答案,但我想发表评论,以免其他人被误导 我强烈建议,对每个场景使用200(OK)响应是不合适的,也不是RESTful的 如果响应代码始终为200(OK),即使在出现错误的情况下,客户端也必须检查每个响应的
is_success=true,
作为MDN引号:()
HTTP响应代码应正确用于HTTP响应等
状态代码指示是否已发送特定HTTP请求
已成功完成。回答分为五类:
- 信息性回复(100-199)
- 成功响应(200-299)
- 重定向(300-399)
- 客户端错误(400–499)
- 服务器错误(500–599)
- 如果请求包含无效数据或不包含所需的 字段,您应该返回400(错误请求)
- 如果服务器上出现意外错误,则使用500(内部服务器错误)
- 如果在服务器上创建了新资源,则使用201(已创建)
这里的
ResponseCode
是您的自定义代码,可用于更详细地描述问题,例如,在上面的示例中ResponseCode:2
表示错误在全局异常处理程序中捕获。您得到了什么错误?我添加了异常详细信息,但切断了异常消息的片段-它不是尝试使用json将动态对象序列化为字符串。如果失败了,那就把整个该死的东西序列化吧,我可不这么想。非常感谢。
{"is_success":true,"response_object":{"Something":"dsfdsfdsfs"},"messages":null}
{
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: {
}
}
}