新增xml序列化组件

This commit is contained in:
falcon 2022-03-29 16:01:03 +08:00
parent b606113d63
commit 8cb24bc6af
6 changed files with 279 additions and 0 deletions

View File

@ -1,5 +1,6 @@
using Falcon.SugarApi.ApiDefinistions;
using Falcon.SugarApi.DatabaseDefinitions;
using Falcon.SugarApi.XmlSerialize;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
@ -50,5 +51,14 @@ namespace Falcon.SugarApi
services.TryAddEnumerable(ServiceDescriptor.Transient<IApplicationModelProvider, ApiResponseTypeModelProvider>());
return services;
}
/// <summary>
/// 添加xml序列化工厂XmlSerializeFactory该工厂可以创建一个IXmlSerialize实现
/// </summary>
/// <param name="services">服务集合</param>
/// <returns>服务集合</returns>
public static IServiceCollection AddXmlSerializeFactory(this IServiceCollection services) {
return services.AddSingleton<XmlSerializeFactory>(new XmlSerializeFactory());
}
}
}

View File

@ -0,0 +1,25 @@
namespace Falcon.SugarApi.XmlSerialize
{
/// <summary>
/// XML文档序列化接口
/// </summary>
public interface IXmlSerialize
{
/// <summary>
/// 序列化对象
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="obj">对象</param>
/// <returns>序列化字符串</returns>
public string Serialize<T>(T obj);
/// <summary>
/// 反序列化对象
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="str">序列化字符串</param>
/// <returns>对象实例</returns>
public T? Deserialize<T>(string str) where T : class;
}
}

View File

@ -0,0 +1,104 @@
using System;
using System.Xml;
namespace Falcon.SugarApi.XmlSerialize
{
/// <summary>
/// XmlWriter扩展。实现完整的扩展标记
/// </summary>
/// <remarks>接口要求书写完整的结束标记但是默认XmlWriter使用/结束空标记</remarks>
public class MyXmlWriter : XmlWriter, IDisposable
{
/// <summary>
/// 基础XmlWriter
/// </summary>
public XmlWriter BaseWriter { get; set; }
/// <summary>
/// 序列化设置
/// </summary>
public XmlSerializeSettings MySettings { get; set; }
/// <summary>
/// 通过基础序列化器和序列化设置实例化
/// </summary>
/// <param name="writer">基础序列化器</param>
/// <param name="settings">序列化设置</param>
public MyXmlWriter(XmlWriter writer, XmlSerializeSettings settings) {
this.BaseWriter = writer;
this.MySettings = settings;
}
#pragma warning disable CS1591 // 缺少对公共可见类型或成员的 XML 注释
#region XmlWriter实现
public override WriteState WriteState => BaseWriter.WriteState;
public override void Flush() => this.BaseWriter.Flush();
public override string? LookupPrefix(string ns) => BaseWriter.LookupPrefix(ns);
public override void WriteBase64(byte[] buffer, int index, int count) => this.BaseWriter.WriteBase64(buffer, index, count);
public override void WriteCData(string? text) => this.BaseWriter.WriteCData(text);
public override void WriteCharEntity(char ch) => this.BaseWriter.WriteCharEntity(ch);
public override void WriteChars(char[] buffer, int index, int count) => this.BaseWriter.WriteChars(buffer, index, count);
public override void WriteComment(string? text) => this.BaseWriter.WriteComment(text);
public override void WriteDocType(string name, string? pubid, string? sysid, string? subset) => this.BaseWriter.WriteDocType(name, pubid, sysid, subset);
public override void WriteEndAttribute() => this.BaseWriter.WriteEndAttribute();
/// <summary>
/// 写入完整的关闭节点
/// </summary>
public override void WriteEndElement() {
if (this.MySettings.WriteFullEndElement) {
BaseWriter.WriteFullEndElement();
}
else {
BaseWriter.WriteEndElement();
}
}
public override void WriteFullEndElement() => BaseWriter.WriteFullEndElement();
public override void Close() => BaseWriter.Close();
public override void WriteEndDocument() => BaseWriter.WriteEndDocument();
public override void WriteEntityRef(string name) => BaseWriter.WriteEntityRef(name);
public override void WriteProcessingInstruction(string name, string? text) => BaseWriter.WriteProcessingInstruction(name, text);
public override void WriteRaw(string data) => BaseWriter.WriteRaw(data);
public override void WriteRaw(char[] buffer, int index, int count) => BaseWriter.WriteRaw(buffer, index, count);
public override void WriteStartAttribute(string? prefix, string localName, string? ns) => BaseWriter.WriteStartAttribute(prefix, localName, ns);
public override void WriteStartDocument(bool standalone) => BaseWriter.WriteStartDocument(standalone);
public override void WriteStartDocument() => BaseWriter.WriteStartDocument();
public override void WriteStartElement(string? prefix, string localName, string? ns) => BaseWriter.WriteStartElement(prefix, localName, ns);
public override void WriteString(string? text) => BaseWriter.WriteString(text);
public override void WriteSurrogateCharEntity(char lowChar, char highChar) => BaseWriter.WriteSurrogateCharEntity(lowChar, highChar);
public override void WriteWhitespace(string? ws) => BaseWriter.WriteWhitespace(ws);
#endregion
#pragma warning restore CS1591 // 缺少对公共可见类型或成员的 XML 注释
protected override void Dispose(bool disposing) {
if (disposing) {
this.BaseWriter.Dispose();
}
base.Dispose(disposing);
}
}
}

View File

@ -0,0 +1,75 @@
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace Falcon.SugarApi.XmlSerialize
{
/// <summary>
/// XML序列化实现
/// </summary>
public class XmlSerialize : IXmlSerialize
{
/// <summary>
/// 序列化设置
/// </summary>
public XmlSerializeSettings Settings { get; set; }
/// <summary>
/// 使用默认配置的序列化器
/// </summary>
public XmlSerialize() : this(new XmlSerializeSettings()) { }
/// <summary>
/// 使用特定配置的序列化器
/// </summary>
/// <param name="settings">序列化配置</param>
public XmlSerialize(XmlSerializeSettings settings) {
this.Settings = settings;
}
/// <summary>
/// 反序列化对象
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="str">序列化字符串</param>
/// <returns>对象实例</returns>
public T? Deserialize<T>(string str) where T : class {
var serializer = new XmlSerializer(typeof(T));
using var ms = new MemoryStream(Encoding.UTF8.GetBytes(str));
var obj = serializer.Deserialize(ms) as T;
return obj;
}
/// <summary>
/// 序列化对象
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="obj">对象</param>
/// <returns>序列化字符串</returns>
public string Serialize<T>(T obj) {
var xmlSerializer = new XmlSerializer(typeof(T));
using var ms = new MemoryStream();
XmlSerializerNamespaces xmlSerializerNamespaces = new();
if (this.Settings.Namespaces.Count > 0) {
foreach (var item in this.Settings.Namespaces) {
xmlSerializerNamespaces.Add(item.Key, item.Value);
}
}
else {
xmlSerializerNamespaces.Add("", "");
}
var settings = new XmlWriterSettings {
OmitXmlDeclaration = this.Settings.OmitXmlDeclaration,
Encoding =this.Settings.Encoding,
Indent = this.Settings.Indent,
IndentChars = this.Settings.IndentChars,
};
using XmlWriter xmlWriter = new MyXmlWriter(XmlWriter.Create(ms, settings),this.Settings);
xmlSerializer.Serialize(xmlWriter, obj, xmlSerializerNamespaces);
ms.Position = 0;
using var sr = new StreamReader(ms, Encoding.UTF8);
return sr.ReadToEnd();
}
}
}

View File

@ -0,0 +1,28 @@
using System;
namespace Falcon.SugarApi.XmlSerialize
{
/// <summary>
/// xml序列化器工厂
/// </summary>
public class XmlSerializeFactory
{
/// <summary>
/// 使用默认设置创建xml序列化器
/// </summary>
/// <returns>序列化器</returns>
public IXmlSerialize CreateXmlSerialize() {
return new XmlSerialize();
}
/// <summary>
/// 使用特定设置创建xml序列化器
/// </summary>
/// <param name="setter">特定设置</param>
/// <returns>序列化器</returns>
public IXmlSerialize CreateXmlSerialize(Action<XmlSerializeSettings> setter) {
var settings = new XmlSerializeSettings { };
setter(settings);
return new XmlSerialize(settings);
}
}
}

View File

@ -0,0 +1,37 @@
using System.Collections.Generic;
using System.Text;
namespace Falcon.SugarApi.XmlSerialize
{
/// <summary>
/// XML序列化设置
/// </summary>
public class XmlSerializeSettings
{
/// <summary>
/// 编写XML声明。默认false
/// </summary>
public bool OmitXmlDeclaration { set; get; } = false;
/// <summary>
/// XML编码格式。默认Encoding.UTF8
/// </summary>
public Encoding Encoding { set; get; } = Encoding.UTF8;
/// <summary>
/// 是否换行缩进。默认true
/// </summary>
public bool Indent { set; get; } = true;
/// <summary>
/// 缩进使用字符串。默认" "
/// </summary>
public string IndentChars { set; get; } = " ";
/// <summary>
/// XML名字空间。默认空
/// </summary>
public List<KeyValuePair<string, string>> Namespaces { get; set; } = new();
/// <summary>
/// 对空节点使用完整的结束标记。默认true
/// </summary>
public bool WriteFullEndElement { get; set; } = true;
}
}