我正在尝试使用mongoDB为CRUD操作创建API控制器。现在请记住,我不知道这些集合的结构,使用mongoDB的整个想法是我们可以真正利用文档存储选项以及查询功能,而不必担心设计模型。以下是我之前的事情:
// GET api/mongo
public IEnumerable<BsonDocument> Get(String database, String collection)
{
db = server.GetDatabase(database);
return db.GetCollection(collection).FindAll().AsEnumerable();
}
但是上面我得到了这个错误:
{
"Message": "An error has occurred.",
"ExceptionMessage": "The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.",
"ExceptionType": "System.InvalidOperationException",
"StackTrace": null,
"InnerException": {
"Message": "An error has occurred.",
"ExceptionMessage": "Error getting value from '__emptyInstance' on 'MongoDB.Bson.ObjectId'.",
"ExceptionType": "Newtonsoft.Json.JsonSerializationException",
"StackTrace": " at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter writer, Object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, JsonContract& memberContract, Object& memberValue)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IWrappedCollection values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IWrappedCollection values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value)\r\n at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value)\r\n at Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter, Object value)\r\n at System.Net.Http.Formatting.JsonMediaTypeFormatter.<>c__DisplayClassd.<WriteToStreamAsync>b__c()\r\n at System.Threading.Tasks.TaskHelpers.RunSynchronously(Action action, CancellationToken token)",
"InnerException": {
"Message": "An error has occurred.",
"ExceptionMessage": "Common Language Runtime detected an invalid program.",
"ExceptionType": "System.InvalidProgramException",
"StackTrace": " at Get__emptyInstance(Object )\r\n at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)"
}
}
}
MongoCusror有一个方法ToJson()使用我能够得到它:
[
{
"_id": ObjectId("520d4776a9a3f31f54ebdba6"),
"name": "john"
},
{
"_id": ObjectId("520d4b77a9a3f31f54ebdba7"),
"name": "chi",
"nickname": "cdawg"
},
{
"_id": ObjectId("520d4c13a9a3f31f54ebdba8"),
"name": "ak",
"nickname": "afro",
"address": {
"state": "ny"
}
}
]
因此,我可以看到Web API管道在使用可用的格式化程序来序列化ObjectId类型时遇到问题,因为它不是一个简单的类型。即使使用XML格式化程序也是如此。
我重写了我的方法如下:
// GET api/mongo
public JArray Get(String database, String collection)
{
db = server.GetDatabase(database);
return JArray.Parse(db.GetCollection(collection).FindAll().ToJson(new JsonWriterSettings { OutputMode = JsonOutputMode.Strict }));
}
这对我有用,并返回以下内容:
[
{
"_id": {
"$oid": "520d4776a9a3f31f54ebdba6"
},
"name": "john"
},
{
"_id": {
"$oid": "520d4b77a9a3f31f54ebdba7"
},
"name": "chi",
"nickname": "cdawg"
},
{
"_id": {
"$oid": "520d4c13a9a3f31f54ebdba8"
},
"name": "akash",
"nickname": "ak",
"address": {
"state": "ny"
}
}
]
但由于种种原因,我不喜欢这种方法:
我已经阅读了有关使用[BsonId]
或[JsonIgnore]
属性等的内容,但是,我没有强类型模型来应用这些属性。我真的想要一种可以帮助我利用Web API内容协商的方法。
非常感谢您的建议。