Mongo ObjectId를 직렬화하는 동안 JSON.NET 캐스트 오류가 발생했습니다.
나는 MongoDB를 가지고 놀고 있고 mongodb ObjectId가 있는 객체를 가지고 있습니다..NET Json() 메서드로 이를 연재하면 모든 것이 좋습니다(하지만 날짜가 끔찍합니다!).
JSON.NET serializer와 함께 사용하면 개체를 serialize할 때 InvalidCastException이 표시됩니다.아이디
무슨 일이 일어나고 어떻게 이것을 고칠 수 있는지에 대한 아이디어가 있습니까?
using MongoDB.Driver;
using MongoDB.Bson;
using Newtonsoft.Json;
//this is a route on a controller
public string NiceJsonPlease()
{
var q = new TestClass();
q.id = new ObjectId();
q.test = "just updating this";
return JsonConvert.SerializeObject(q);
}
//simple test class
class TestClass
{
public ObjectId id; //MongoDB ObjectID
public string test = "hi there";
}
Exception Details: System.InvalidCastException: Specified cast is not valid.
.NET과 함께 제공되는 serializer를 사용하도록 컨트롤러 방법을 변경하면 정상적으로 작동합니다(그러나 이 방법은 날짜가 추합니다, 파란색).
public JsonResult NiceJsonPlease()
{
var q = new TestClass();
q.id = new ObjectId();
q.test = "just updating this";
return Json(q, JsonRequestBehavior.AllowGet);
}
ObjectId 대신 .NET 문자열 유형을 사용할 수 있습니다. Bson Representation으로 꾸미기만 하면 됩니다.BsonDateTime을 사용하는 경우에도 동일한 변환 문제가 발생합니다.이것은 제 프로젝트의 도메인 클래스로, 장식자를 사용합니다.
public class DocumentMetadata
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public string Name { get; set; }
public string FullName { get; set; }
[BsonDateTimeOptions(Kind = DateTimeKind.Utc)]
public DateTime DownloadTime { get; set; }
}
MongoDB 사용자 그룹의 포인터가 있었습니다.https://groups.google.com/forum/ ?from groups=#!topic/mongodb-csharp/A_DXHuPscnQ
그 대답은.
이것은 Json인 것 같습니다.NET 문제, 하지만 실제로는 아닙니다.여기에는 단순히 모르는 사용자 지정 유형이 있습니다.당신은 Json에게 말해야 합니다.NET ObjectId를 직렬화하는 방법.
그래서 저는 다음 솔루션을 구현했습니다.
ObjectId를 다음으로 장식했습니다.
[JsonConverter(typeof(ObjectIdConverter))]
그런 다음 ObjectId의 GUID 부분을 뱉어내는 사용자 지정 변환기를 작성했습니다.
class ObjectIdConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value.ToString());
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override bool CanConvert(Type objectType)
{
return typeof(ObjectId).IsAssignableFrom(objectType);
//return true;
}
}
쓰기 개체 ID 변환기
public 클래스 ObjectIdConverter : JsonConverter {public override bool CanConvert(Type objectType) {반환 개체유형 ==(ObjectId); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType != JsonToken.String) throw new Exception($"Unexpected token parsing ObjectId. Expected String, got {reader.TokenType}."); var value = (string)reader.Value; return string.IsNullOrEmpty(value) ? ObjectId.Empty : new ObjectId(value); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { if (value is ObjectId) { var objectId = (ObjectId)value; writer.WriteValue(objectId != ObjectId.Empty ? objectId.ToString() : string.Empty); } else { throw new Exception("Expected ObjectId value."); } }
}
글로벌 설정으로 JSON.NET에 글로벌 등록하고 큰 속성으로 모델을 표시할 필요가 없습니다.
var _serializerSettings = new JsonSerializerSettings() { Converters = new List<JsonConverter> { new ObjectIdConverter() } };
큰 조언 - 모델에 ObjectId를 사용하지 마십시오 - 문자열 사용
[Bson 표현(BsonType).ObjectId)] 공용 문자열 Id{get;set; }
JSONOutputMode를 strict로 설정하여 JSON.NET serializer/InvalidCastException 오류와 관련하여 발생한 유사한 문제를 해결했습니다. 이 경우 기본 유형을 변경할 필요가 없습니다.
var jsonWriterSettings = new JsonWriterSettings { OutputMode = JsonOutputMode.Strict };
var json = doc.ToJson(jsonWriterSettings);
자세한 내용은 API: http://api.mongodb.org/csharp/1.8.3/html/d73bf108-d68c-e472-81af-36ac29ea08da.htm 에서 확인할 수 있습니다.
저는 웹 API 프로젝트에서 비슷한 문제에 부딪혔고, 결국 이 스레드를 찾기 전에 몇 시간 동안 키보드에 머리를 부딪쳤습니다.
처음에는 모든 것이 정상적으로 작동했지만, mongoDBC# 드라이버 설명서에서 권장하는 BsonDocument 개체 대신 나만의 사용자 지정 클래스를 사용하도록 코드를 변환한 후 문제가 발생했습니다.
여기서 VB.net 은 위의 솔루션과 동일한 솔루션을 필요로 하는 사용자를 위한 것입니다.
Public Class DocumentMetadata
<BsonId> _
<BsonRepresentation(BsonType.ObjectId)> _
Public Property Id() As String
Public Property Name() As String
Public Property FullName() As String
<BsonDateTimeOptions(Kind := DateTimeKind.Utc)> _
Public Property DownloadTime() As DateTime
End Class
다른 옵션이 있습니다.
object dotnetObject = BsonTypeMapper.MapToDotNetValue(bsonDocument);
// Json mapped to default .Net objects
string json = Newtonsoft.Json.JsonConvert.SerializeObject(dotnetObject);
// Parsing as JObject
var jobject = JObject.Parse(json);
// Deserializing as your custom Type
var myObject = JsonConvert.DeserializeObject<MyType>(json);
저는 이 코드를 VB에서 사용했습니다.net and worked perfect, 클래스에서 objectId를 볼 수 있으며 데이터 유형 DATE에서도 동일한 작업을 수행할 수 있습니다.
Imports MongoDB.Bson
Imports MongoDB.Bson.Serialization.Attributes
Imports MongoDB.Driver
Public Class _default
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim objMongo As New MongoClient("mongodb://192.168.111.5:27017")
Dim objDatabase As IMongoDatabase = objMongo.GetDatabase("local")
Dim objCollection = objDatabase.GetCollection(Of BsonDocument)("Test")
Dim _ret As New List(Of mongo_users)
Dim result = objCollection.Find(New BsonDocument()).ToList()
Dim _json_response = result.ToJson()
If _json_response <> "" Then
_ret = MongoDB.Bson.Serialization.BsonSerializer.Deserialize(Of List(Of mongo_users))(_json_response)
End If
For Each item In _ret
Response.Write(item.name & " " & item.last_name & "</br>")
Next
End Sub
End Class
Public Class mongo_users
<BsonId>
<BsonRepresentation(BsonType.ObjectId)>
Public Property _id() As String
Public Property status As Integer
Public Property name As String
Public Property last_name As String
Public Property colors As List(Of user_colors)
End Class
Public Class user_colors
Public Property color_name As String
End Class
언급URL : https://stackoverflow.com/questions/16651776/json-net-cast-error-when-serializing-mongo-objectid
'code' 카테고리의 다른 글
[routerLink]와 routerLink의 차이점 (0) | 2023.05.23 |
---|---|
MongoDB에서 OneOverfindOneAndUpdate를 통한 업데이트 사용 사례 (0) | 2023.05.23 |
몽구스 프로미스 사용법 - 몽고 (0) | 2023.05.23 |
Git의 디렉터리에 있는 파일을 어떻게 무시합니까? (0) | 2023.05.23 |
응용 프로그램이 실행되는 실행 파일 디렉터리? (0) | 2023.05.18 |