是这样蒙戈C#驱动程序的toJSON()日期时间
我在蒙戈数据:是这样蒙戈C#驱动程序的toJSON()日期时间
"trd" : ISODate("2003-12-08T00:00:00Z")
现在,我做正从蒙戈数据作为BsonDocument这样的:
var builder = Builders<BsonDocument>.Filter;
var filter = builder.Eq("wsid", id);
var mongoListBatch = _client.GetManyByFilter(filter, "directory");
JsonWriterSettings settings = new JsonWriterSettings();
settings.OutputMode = JsonOutputMode.Strict;
var lists = mongoListBatch.ToJson(settings);
的问题是,我期待得到DateTime对象这样的JSON内:
"transactiedatum": "23-02-1993"
而是即时得到:
"transactiedatum": {
"$date": 1070841600000
}
首先,它的unix时间格式,第二,json结构有变化。我该如何处理?
我们有类似的问题。这听起来很复杂,但它不是那么重要。
所以,首先,这里是链接到蒙戈C#驱动器在GitHub上: MongoC#Driver
对你来说,这些都是有两个重要环节:
我们希望实现的是我们不希望Json字符串中的表示法采用unix时间戳格式,因此我们将这些类复制到了我们的项目中,并使用了不同的名称,因此,这里是所有这些类:
扩展类:
using System;
using System.IO;
using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;
using MongoDB.Bson;
namespace Fishing.MongoDB.Serializers
{
public static class MyJsonWriterSettings
{
/// <summary>
/// Serializes an object to a BSON byte array.
/// </summary>
/// <typeparam name="TNominalType">The nominal type of the object.</typeparam>
/// <param name="obj">The object.</param>
/// <param name="serializer">The serializer.</param>
/// <param name="writerSettings">The writer settings.</param>
/// <param name="configurator">The serialization context configurator.</param>
/// <param name="args">The serialization args.</param>
/// <returns>A BSON byte array.</returns>
public static byte[] ToBson<TNominalType>(
this TNominalType obj,
IBsonSerializer<TNominalType> serializer = null,
BsonBinaryWriterSettings writerSettings = null,
Action<BsonSerializationContext.Builder> configurator = null,
BsonSerializationArgs args = default(BsonSerializationArgs)
)
{
return ToBson(obj, typeof(TNominalType), writerSettings, serializer, configurator, args);
}
/// <summary>
/// Serializes an object to a BSON byte array.
/// </summary>
/// <param name="obj">The object.</param>
/// <param name="nominalType">The nominal type of the object..</param>
/// <param name="writerSettings">The writer settings.</param>
/// <param name="serializer">The serializer.</param>
/// <param name="configurator">The serialization context configurator.</param>
/// <param name="args">The serialization args.</param>
/// <returns>A BSON byte array.</returns>
/// <exception cref="System.ArgumentNullException">nominalType</exception>
/// <exception cref="System.ArgumentException">serializer</exception>
public static byte[] ToBson(
this object obj,
Type nominalType,
BsonBinaryWriterSettings writerSettings = null,
IBsonSerializer serializer = null,
Action<BsonSerializationContext.Builder> configurator = null,
BsonSerializationArgs args = default(BsonSerializationArgs))
{
if (nominalType == null)
{
throw new ArgumentNullException("nominalType");
}
if (serializer == null)
{
serializer = BsonSerializer.LookupSerializer(nominalType);
}
if (serializer.ValueType != nominalType)
{
var message = string.Format("Serializer type {0} value type does not match document types {1}.", serializer.GetType().FullName, nominalType.FullName);
throw new ArgumentException(message, "serializer");
}
using (var memoryStream = new MemoryStream())
{
using (var bsonWriter = new BsonBinaryWriter(memoryStream, writerSettings ?? BsonBinaryWriterSettings.Defaults))
{
var context = BsonSerializationContext.CreateRoot(bsonWriter, configurator);
args.NominalType = nominalType;
serializer.Serialize(context, args, obj);
}
return memoryStream.ToArray();
}
}
/// <summary>
/// Serializes an object to a BsonDocument.
/// </summary>
/// <typeparam name="TNominalType">The nominal type of the object.</typeparam>
/// <param name="obj">The object.</param>
/// <param name="serializer">The serializer.</param>
/// <param name="configurator">The serialization context configurator.</param>
/// <param name="args">The serialization args.</param>
/// <returns>A BsonDocument.</returns>
public static BsonDocument ToBsonDocument<TNominalType>(
this TNominalType obj,
IBsonSerializer<TNominalType> serializer = null,
Action<BsonSerializationContext.Builder> configurator = null,
BsonSerializationArgs args = default(BsonSerializationArgs))
{
return ToBsonDocument(obj, typeof(TNominalType), serializer, configurator, args);
}
/// <summary>
/// Serializes an object to a BsonDocument.
/// </summary>
/// <param name="obj">The object.</param>
/// <param name="nominalType">The nominal type of the object.</param>
/// <param name="serializer">The serializer.</param>
/// <param name="configurator">The serialization context configurator.</param>
/// <param name="args">The serialization args.</param>
/// <returns>A BsonDocument.</returns>
/// <exception cref="System.ArgumentNullException">nominalType</exception>
/// <exception cref="System.ArgumentException">serializer</exception>
public static BsonDocument ToBsonDocument(
this object obj,
Type nominalType,
IBsonSerializer serializer = null,
Action<BsonSerializationContext.Builder> configurator = null,
BsonSerializationArgs args = default(BsonSerializationArgs))
{
if (nominalType == null)
{
throw new ArgumentNullException("nominalType");
}
if (obj == null)
{
return null;
}
if (serializer == null)
{
var bsonDocument = obj as BsonDocument;
if (bsonDocument != null)
{
return bsonDocument; // it's already a BsonDocument
}
var convertibleToBsonDocument = obj as IConvertibleToBsonDocument;
if (convertibleToBsonDocument != null)
{
return convertibleToBsonDocument.ToBsonDocument(); // use the provided ToBsonDocument method
}
serializer = BsonSerializer.LookupSerializer(nominalType);
}
if (serializer.ValueType != nominalType)
{
var message = string.Format("Serializer type {0} value type does not match document types {1}.", serializer.GetType().FullName, nominalType.FullName);
throw new ArgumentException(message, "serializer");
}
// otherwise serialize into a new BsonDocument
var document = new BsonDocument();
using (var bsonWriter = new BsonDocumentWriter(document))
{
var context = BsonSerializationContext.CreateRoot(bsonWriter, configurator);
args.NominalType = nominalType;
serializer.Serialize(context, args, obj);
}
return document;
}
/// <summary>
/// Serializes an object to a JSON string.
/// </summary>
/// <typeparam name="TNominalType">The nominal type of the object.</typeparam>
/// <param name="obj">The object.</param>
/// <param name="writerSettings">The JsonWriter settings.</param>
/// <param name="serializer">The serializer.</param>
/// <param name="configurator">The serializastion context configurator.</param>
/// <param name="args">The serialization args.</param>
/// <returns>
/// A JSON string.
/// </returns>
public static string ToMyJson<TNominalType>(
this TNominalType obj,
JsonWriterSettings writerSettings = null,
IBsonSerializer<TNominalType> serializer = null,
Action<BsonSerializationContext.Builder> configurator = null,
BsonSerializationArgs args = default(BsonSerializationArgs))
{
return ToMyJson(obj, typeof(TNominalType), writerSettings, serializer, configurator, args);
}
/// <summary>
/// Serializes an object to a JSON string.
/// </summary>
/// <param name="obj">The object.</param>
/// <param name="nominalType">The nominal type of the objectt.</param>
/// <param name="writerSettings">The JsonWriter settings.</param>
/// <param name="serializer">The serializer.</param>
/// <param name="configurator">The serialization context configurator.</param>
/// <param name="args">The serialization args.</param>
/// <returns>
/// A JSON string.
/// </returns>
/// <exception cref="System.ArgumentNullException">nominalType</exception>
/// <exception cref="System.ArgumentException">serializer</exception>
public static string ToMyJson(
this object obj,
Type nominalType,
JsonWriterSettings writerSettings = null,
IBsonSerializer serializer = null,
Action<BsonSerializationContext.Builder> configurator = null,
BsonSerializationArgs args = default(BsonSerializationArgs))
{
if (nominalType == null)
{
throw new ArgumentNullException("nominalType");
}
if (serializer == null)
{
serializer = BsonSerializer.LookupSerializer(nominalType);
}
if (serializer.ValueType != nominalType)
{
var message = string.Format("Serializer type {0} value type does not match document types {1}.", serializer.GetType().FullName, nominalType.FullName);
throw new ArgumentException(message, "serializer");
}
using (var stringWriter = new StringWriter())
{
using (var bsonWriter = new JsonWriterMine(stringWriter, writerSettings ?? JsonWriterSettings.Defaults))
{
var context = BsonSerializationContext.CreateRoot(bsonWriter, configurator);
args.NominalType = nominalType;
serializer.Serialize(context, args, obj);
}
return stringWriter.ToString();
}
}
}
}
所以basicaly,从GitHub全班复制到自己的类,将2种方法名字:的toJSON()到你的一个。在这里你可以看到我的是ToJsonMine()。
现在,第二类,你需要:
JsonWriter
using MongoDB.Bson.IO;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using MongoDB.Bson;
namespace Fishing.MongoDB.Serializers
{
public class JsonWriterMine : BsonWriter
{
// private fields
private TextWriter _textWriter;
private JsonWriterSettings _jsonWriterSettings; // same value as in base class just declared as derived class
private InternalJsonWriterContext _context;
// constructors
/// <summary>
/// Initializes a new instance of the JsonWriter class.
/// </summary>
/// <param name="writer">A TextWriter.</param>
public JsonWriterMine(TextWriter writer)
: this(writer, JsonWriterSettings.Defaults)
{
}
/// <summary>
/// Initializes a new instance of the JsonWriter class.
/// </summary>
/// <param name="writer">A TextWriter.</param>
/// <param name="settings">Optional JsonWriter settings.</param>
public JsonWriterMine(TextWriter writer, JsonWriterSettings settings)
: base(settings)
{
if (writer == null)
{
throw new ArgumentNullException("writer");
}
_textWriter = writer;
_jsonWriterSettings = settings; // already frozen by base class
_context = new InternalJsonWriterContext(null, ContextType.TopLevel, "");
State = BsonWriterState.Initial;
}
/// <summary>
/// Writes a BSON DateTime to the writer.
/// </summary>
/// <param name="value">The number of milliseconds since the Unix epoch.</param>
public override void WriteDateTime(long value)
{
if (Disposed) { throw new ObjectDisposedException("JsonWriter"); }
if (State != BsonWriterState.Value && State != BsonWriterState.Initial)
{
ThrowInvalidState("WriteDateTime", BsonWriterState.Value, BsonWriterState.Initial);
}
WriteNameHelper(Name);
switch (_jsonWriterSettings.OutputMode)
{
case JsonOutputMode.Strict:
var utcDateTimeFirst = BsonUtils.ToDateTimeFromMillisecondsSinceEpoch(value);
_textWriter.Write($"\"{utcDateTimeFirst.ToString("yyyy-MM-ddTHH:mm:ss.FFFZ")}\"");
break;
case JsonOutputMode.Shell:
default:
// use ISODate for values that fall within .NET's DateTime range, and "new Date" for all others
if (value >= BsonConstants.DateTimeMinValueMillisecondsSinceEpoch &&
value <= BsonConstants.DateTimeMaxValueMillisecondsSinceEpoch)
{
var utcDateTime = BsonUtils.ToDateTimeFromMillisecondsSinceEpoch(value);
_textWriter.Write("ISODate(\"{0}\")", utcDateTime.ToString("yyyy-MM-ddTHH:mm:ss.FFFZ"));
}
else
{
_textWriter.Write("new Date({0})", value);
}
break;
}
State = GetNextState();
}
}
}
这就是奇迹发生。将整个JsonWriter类从GitHub复制到你自己的并给它一个新名称(扩展BsonWriter
nad实现所有方法)。现在,在这里你可以操纵你想如何序列化日期。相应地更改WriteDateTime(long value)
。正如你所看到的,在case JsonOutputMode.Strict:
我改变了它,以我需要的方式格式化了DateTime对象。
最后,由于MongoSerializer具有名为JsonWriterContext
的内部类,您需要创建自己的并在JsonWriter
(步骤2)中使用它。
这是它的外观与我(你可以将它复制整):
using MongoDB.Bson.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Fishing.MongoDB.Serializers
{
public class InternalJsonWriterContext
{
// private fields
private InternalJsonWriterContext _parentContext;
private ContextType _contextType;
private string _indentation;
private bool _hasElements = false;
// constructors
internal InternalJsonWriterContext(InternalJsonWriterContext parentContext, ContextType contextType, string indentChars)
{
_parentContext = parentContext;
_contextType = contextType;
_indentation = (parentContext == null) ? indentChars : parentContext.Indentation + indentChars;
}
// internal properties
internal InternalJsonWriterContext ParentContext
{
get { return _parentContext; }
}
internal ContextType ContextType
{
get { return _contextType; }
}
internal string Indentation
{
get { return _indentation; }
}
internal bool HasElements
{
get { return _hasElements; }
set { _hasElements = value; }
}
}
}
后你拥有了一切,你会在MongoCursorJsonConverter(第一步)看到,在第二ToJsonMine()
的方法,我有这条线:
using (var bsonWriter = new JsonWriterMine(stringWriter, writerSettings ?? JsonWriterSettings.Defaults))
你应该只与您在步骤2中创建自己的自定义类代替它,它会像一个魅力。
而在最后,您只要致电:
var lists = mongoListBatch.ToJson(settings);
和像你这样的内部WriteDate(long value)
工程就像一个魅力,谢谢补充它会序列日期! –