Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#Web Api-所有Api响应的通用包装类_C#_Generics_Asp.net Web Api_Dynamic_Wrapper - Fatal编程技术网

c#Web Api-所有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()

几天以来,我一直在试图弄清楚如何从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(字符串 消息,类型)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(已创建)
我还建议阅读有关正确使用HTTP方法的内容。()

对于一般的回答,您可以在成功的回答中返回如下内容:(这完全是我的结构,可能不是最佳做法)

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


这里的
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: {
     }
   }
}