C# 踩坑记

XML序列化

三种XML序列化方式

// 用TextWriter写到字符串中
StringBuilder xmlString = new StringBuilder();
using (TextWriter textWriter = new StringWriter(xmlString))
//using (TextWriter textWriter = new StreamWriter("C:/Users/04/Documents/order-textWriter.xml"))

// 用XmlWriter写到文件中
using (XmlWriter xmlWriter = XmlWriter.Create("C:/Users/04/Documents/order-xmlWriter.xml", new XmlWriterSettings() { Encoding = new UTF8Encoding(false) }))
//using (XmlWriter xmlWriter = XmlWriter.Create(xmlString, new XmlWriterSettings() { Encoding = new UTF8Encoding(false) }))

// 用StreamWriter写到流中
using (var memoryStream = new MemoryStream())
//using (var streamWriter = new StreamWriter(memoryStream, Encoding.UTF8))
using (var streamWriter = new StreamWriter(memoryStream, new UTF8Encoding(false)))
{
    var emptyNs = new XmlSerializerNamespaces();
    emptyNs.Add(string.Empty, string.Empty);
    var serializer = new XmlSerializer(data.GetType());
    serializer.Serialize(streamWriter, data, emptyNs);
    serializer.Serialize(textWriter, data, emptyNs);
    serializer.Serialize(xmlWriter, data, emptyNs);
}

每个节点添加命名空间前缀

  1. 在父节点添加命名空间指定命名空间:[XmlElement(Namespace = "http://www.test.com")]
  2. 在序列化时传入命名的前缀
var namespaces = new XmlSerializerNamespaces();
// 每个子节点都将带有test前缀
namespaces.Add("test", "http://www.test.com");
var serializer = new XmlSerializer(data.GetType());
serializer.Serialize(xmlWriter, data, namespaces);

忽略字段

方式一:字段属性[XmlElement(IsNullable = true)],当字段值为null时,字段上加此属性,xml标签会出现nil="true"属性,若不加此属性,则直接不出现xml元素,但是此方式只对string类型起作用,其他int、decimal等类型无效

之后,可使用正则表达式去掉nil="true"这些成分

var regNull = new Regex(@"<(\w+)\sd3p1:nil.*/>");
xmlstr = regNull.Replace(xmlstr, @"<$1></$1>");

方式二:使用规则字段指定何种情况忽略序列化特定字段,规则字段名=目标字段名+Specified,类型为bool,返回false时忽略序列化

public MyClass
{
    public int? a { get; set; }
    [XmlIgnore]
    public bool aSpecified { get { return this.a != null; } }
}

参考

反序列化指定根节点

var serializer = new XmlSerializer(typeof(EventMessage), new XmlRootAttribute("xml"));
var msg = (EventMessage)serializer.Deserialize(inputStream);

RSA加密

编码参考

c#自带的加密工具类只能使用模数和指数初始化,而一般情况我们得到密钥的PKCS#1格式(以-----BEGIN RSA PUBLIC KEY开头),所以需要进行转换,提取出密钥的指数和模数

自动映射两个对象的同名字段

Mapper.CreateMap<T1, T2>();
Mapper.Map<T1, T2>(obj1, obj2);

注意:必须要先使用Mapper.CreateMap<T1, T2>()进行初始化映射器,否则报“missing type map configuration or unsupported mapping”,参考

自实现轻量文件日志

// 初始化日志输出流,若不存在日志文件则会自动创建
StreamWriter _logStream = File.AppendText("log.txt");
// 设置自动刷新,则每次调用一次输出会自动写入文件,否则输出会一直滞留在内存中
_logStream.AutoFlush = true;
// 输出一行日志
_logStream.WriteLine("{0} OrderSigner Init Path:{1}", DateTime.Now, "msg");

abp自定义json序列化:

  1. 自定义ContractResolver:重写CreateProperties方法,最后将其实例赋值给jsonOptions.SerializerSettings.ContractResolver
  1. 自定义JsonConverter:用jsonOptions.SerializerSettings.Converters.Add方法添加其实例

C#无法使用Request.Form获取uni-app的post请求参数

小程序post请求要加'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'请求头

HTTP Error 500.30 - ANCM In-Process Start Failure

升级和移除一些.NET SDK后,asp.net core项目只能使用自包含(self-contained)的方式启动,无法使用IIS Express无法启动,报如下错误

在web.config文件按照下图1和3位置配置了stdout和ancm日志,以及查看操作系统的事件日志(Event Viewer),都没有找到具体的原因,后面看到2位置引用了一些全路径的dll文件,猜测可能是因为我本地没有,遂删除此行,果然成功启动!

经验:

  1. 配置stdout日志后,在vs的下方output选项卡>下拉选择asp.net core web server查看,或者在指定的文件中查看
  2. 操作系统的事件日志查看方式:我的电脑右键>管理>系统工具>事件查看器>Windows日志
  3. 出现莫名其妙的启动错误时,可以考虑是否引用了一些全路径的外部库,在本地不存在

edmx可定义EF的实体映射

使用文本的方式打开,可快速搜索目标实体和数据表的映射关系

Hangfire多队列配置

  1. 使用接口的方式调用
  2. [Queue("queueName")]置于接口方法上,而不是至于实现类方法上
// 使用这种方式入队
BackgroundJob.Enqueue<ISomeWorkerInterface>(x => x.Process(args));

// 不能使用这种方式,否则会报错找不到目标方法
BackgroundJob.Enqueue(() => _someWorkerInterface.Process(args));

Github问题参考

posted @ 2020-12-18 09:55  woncode  阅读(297)  评论(0编辑  收藏  举报