最近几天我一直在尝试解决如何从我的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);
}
}
上面的例子可以正常工作并返回格式正确的数据,但这种方法会导致与命名相关的错误(因为每次返回数据时都必须指定响应结构)。
在我看来,这两种方法没有区别,除了第一种情况下我们获得匿名类型,而第二种情况下我们使用对象。
所以问题是:
我的第一种方法是否可行?