我为我的Web API http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/use-open-types-in-odata-v4实现了OpenType。我可以为此Property发送回字符串,int,数组等随机值。但是,尝试发送回JObject失败并出现错误 我怎样才能发回JObject?
HTTP/1.1 500 Internal Server Error
Cache-Control: private
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true
Server: Microsoft-IIS/8.0
OData-Version: 4.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RDpcQ29uZmlndXJhdGlvblxDb25maWd1cmF0aW9uU3RvcmVcQ29uZmlndXJhdGlvblNlcnZpY2UuQXBpXGFwaVxTZXJ2aWNlcygnRW5jb2RpbmcnKVxDb25maWd1cmF0aW9ucw==?=
X-Powered-By: ASP.NET
Date: Tue, 02 Dec 2014 14:56:01 GMT
Content-Length: 4046
{
"error":{
"code":"","message":"An error has occurred.","innererror":{
"message":"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; odata.metadata=minimal; odata.streaming=true'.","type":"System.InvalidOperationException","stacktrace":"","internalexception":{
"message":"The given model does not contain the type 'Newtonsoft.Json.Linq.JObject'.","type":"System.InvalidOperationException","stacktrace":" at System.Web.OData.Formatter.Serialization.ODataSerializerContext.GetEdmType(Object instance, Type type)\r\n at System.Web.OData.Formatter.Serialization.ODataEdmTypeSerializer.AppendDynamicProperties(Object source, IEdmStructuredTypeReference structuredType, ODataSerializerContext writeContext, List`1 declaredProperties)\r\n at System.Web.OData.Formatter.Serialization.ODataComplexTypeSerializer.CreateODataComplexValue(Object graph, IEdmComplexTypeReference complexType, ODataSerializerContext writeContext)\r\n at System.Web.OData.Formatter.Serialization.ODataComplexTypeSerializer.CreateODataValue(Object graph, IEdmTypeReference expectedType, ODataSerializerContext writeContext)\r\n at System.Web.OData.Formatter.Serialization.ODataCollectionSerializer.CreateODataCollectionValue(IEnumerable enumerable, IEdmTypeReference elementType, ODataSerializerContext writeContext)\r\n at System.Web.OData.Formatter.Serialization.ODataCollectionSerializer.CreateODataValue(Object graph, IEdmTypeReference expectedType, ODataSerializerContext writeContext)\r\n at System.Web.OData.Formatter.Serialization.ODataEdmTypeSerializer.CreateProperty(Object graph, IEdmTypeReference expectedType, String elementName, ODataSerializerContext writeContext)\r\n at System.Web.OData.Formatter.Serialization.ODataEntityTypeSerializer.CreateStructuralProperty(IEdmStructuralProperty structuralProperty, EntityInstanceContext entityInstanceContext)\r\n at System.Web.OData.Formatter.Serialization.ODataEntityTypeSerializer.CreateStructuralPropertyBag(IEnumerable`1 structuralProperties, EntityInstanceContext entityInstanceContext)\r\n at System.Web.OData.Formatter.Serialization.ODataEntityTypeSerializer.CreateEntry(SelectExpandNode selectExpandNode, EntityInstanceContext entityInstanceContext)\r\n at System.Web.OData.Formatter.Serialization.ODataEntityTypeSerializer.WriteEntry(Object graph, ODataWriter writer, ODataSerializerContext writeContext)\r\n at System.Web.OData.Formatter.Serialization.ODataEntityTypeSerializer.WriteObjectInline(Object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext)\r\n at System.Web.OData.Formatter.Serialization.ODataFeedSerializer.WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, ODataWriter writer, ODataSerializerContext writeContext)\r\n at System.Web.OData.Formatter.Serialization.ODataFeedSerializer.WriteObjectInline(Object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext)\r\n at System.Web.OData.Formatter.Serialization.ODataFeedSerializer.WriteObject(Object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)\r\n at System.Web.OData.Formatter.ODataMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content, HttpContentHeaders contentHeaders)\r\n at System.Web.OData.Formatter.ODataMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.GetResult()\r\n at System.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__1b.MoveNext()"
}
}
}
}
以下是一些可能有用的细节
班级定义
public sealed class Configuration
{
public string ID { get; set; }
public ConfigurationValue[] Values
{
get;
set;
}
}
public sealed class ConfigurationValue
{
public IDictionary<string, object> ScopedValue { get; set; }
}
在控制器中,如果我按如下方式创建对象,则可以正常工作
var config = new Configuration{ ID="1", Values = new [] { new ConfigurationValue { ScopedValue = new Dictionary<string, object> {{"Val","1"}}}}};
但是,如果我执行以下操作就会爆炸
var value=JsonConvert.DeserializeObject(@"{'RetryInterval': 60,'MaxRetryCount': 100}");
var config = new Configuration{ ID="1", Values = new [] { new ConfigurationValue { ScopedValue = new Dictionary<string, object> {{"Val",value}}}}};
答案 0 :(得分:3)
问题根本没有在您发布的代码中,它运行得很完美。问题是OData
无法与您的班级合作。
OData不支持所有类型,更明确地它不支持没有setter和getter的类型。
Dictionary
基本上是KeyValuePair
个对象的列表。 KeyValuePair
使用索引,但没有get;
和set;
。
解决方案是使用包含两个属性的普通类,并将它们放在List
中,而不是使用Dictionary
。
public class ScopedValue
{
public string Key { get; set; }
public object Value { get; set; }
}
public sealed class ConfigurationValue
{
public List<ScopedValue> ScopedValues { get; set; }
}