【发布时间】:2019-02-20 16:57:34
【问题描述】:
我有一个 ASP.NET 核心 2.1 MVC 项目,我正在从 Serlilog MSSqlServr Sink 检索数据,该接收器将值作为 XML 数据类型存储在 Properties 字段中。我想将该数据反序列化为视图模型,以便可以在视图中将各个元素呈现为数据。
这是来自数据库日志表中属性字段的 XML 示例。
<properties>
<property key="EventId">
<structure type="">
<property key="Id">404</property>
</structure>
</property>
<property key="ActionId">0592d9e8-f4fd-459f-96b3-2b787d01a754</property>
<property key="ActionName">API.Controllers.CompletionsController.GetCompletion (PS.API)</property>
<property key="RequestId">0HLJ2IL5A9:00000001</property>
<property key="RequestPath">/api/completions/0</property>
<property key="CorrelationId" />
<property key="ConnectionId">0HLJ2IL59</property>
<property key="MachineName">RD0003FF1</property>
<property key="ThreadId">117</property>
</properties>
我为解码设置了一个类,如下所示;
using System.Xml.Serialization;
namespace PS.Models.ApiLogs
{
[XmlRoot("properties")]
public class LogProperties
{
[XmlElement("SourceContext")]
public string SourceContext { get; set; }
[XmlElement("ActionId")]
public string ActionId { get; set; }
[XmlElement("ActionName")]
public string ActionName { get; set; }
[XmlElement("RequestId")]
public string RequestId { get; set; }
[XmlElement("RequestPath")]
public string RequestPath { get; set; }
[XmlElement("CorrelationId")]
public string CorrelationId { get; set; }
[XmlElement("ConnectionId")]
public string ConnectionId { get; set; }
[XmlElement("MachineName")]
public string MachineName { get; set; }
[XmlElement("ThreadId")]
public string ThreadId { get; set; }
}
}
在我的控制器中,我有以下代码;
var serializer = new XmlSerializer(typeof(LogProperties));
LogProperties logProperties;
using (TextReader reader = new StringReader(log.Properties))
{
logProperties = (LogProperties)serializer.Deserialize(reader);
}
但是 logProperties 变量不包含任何内容,所以我假设我在 LogProperties 类中的 XML 属性不正确。
我花了很多时间寻找解决方案,并在输入此问题时查看了所有相关帖子,但我无法找到 XML 使用“property key=”或如何处理的示例带有“key=”属性属性(如果这是正确的术语)
有什么想法吗?
[2/21/19 更新]
我最终使用了@jdweng 的建议,因为它是最简单的并且给了我想要的东西。
我创建了 2 个类(因为我喜欢将我的类文件分开作为个人偏好)。课程如下;
using System.Collections.Generic;
using System.Xml.Serialization;
namespace PS.Models.ApiLogs
{
[XmlRoot("properties")]
public class LogProperties
{
[XmlElement("property")]
public List<LogProperty> Property { get; set; }
}
}
和
using System.Xml.Serialization;
namespace PS.Models.ApiLogs
{
[XmlRoot("property")]
public class LogProperty
{
[XmlAttribute("key")]
public string Key { get; set; }
[XmlText]
public string Value { get; set; }
}
}
然后在我的控制器中,我有以下 Detail 方法;
var response = await _client.GetLogAsync(id, $"api/logs", token);
if (response == null)
{
return NotFound($"Unable to find a record for Log ID [{id}].");
}
var log = _mapper.Map<DetailLogViewModel>(response.Record);
var serializer = new XmlSerializer(typeof(LogProperties));
LogProperties logProperties;
using (TextReader reader = new StringReader(log.Properties))
{
logProperties = (LogProperties)serializer.Deserialize(reader);
}
var logWithProperties = new DetailLogWithPropertiesViewModel
{
Id = log.Id,
Message = log.Message,
TimeStamp = log.TimeStamp,
Exception = log.Exception,
XmlProperties = logProperties
};
return View(logWithProperties);
我的 DetailLogWithPropertiesViewModel 在下面;
public class DetailLogWithPropertiesViewModel
{
public int Id { get; set; }
[Display(Name = "Message")]
public string Message { get; set; }
[Display(Name = "Level")]
public string Level { get; set; }
[Display(Name = "Time Stamp")]
public DateTimeOffset TimeStamp { get; set; }
[Display(Name = "Exception")]
public string Exception { get; set; }
[Display(Name = "Properties")]
public string Properties { get; set; }
public LogProperties XmlProperties { get; set; }
}
我的 Detail.cshtml 的相关部分如下;
<div class="card-body ml3 mr3">
@foreach (var logProperty in Model.XmlProperties.Property)
{
<div class="row">
<div class="col-4 bg-light border border-primary">
<span class="font-weight-bold">@logProperty.Key</span>
</div>
<div class="col-8 bg-secondary border border-left-0 border-primary">
<span>@logProperty.Value</span>
</div>
</div>
}
</div>
由 Serilog 生成并存储在 MS SQL 数据库中的 XML 具有可变数量的属性,我现在理解这些属性表示为键/值对。因此,此方法允许我确保所有提供的属性都显示在网站的日志查看器中。
【问题讨论】:
-
得到了另一个方向!如果您尝试使用您的类使用 XmlSerializer.Serialize() 创建 XML 文件(或带有 XML 的字符串),您将看到您描述的 XML 文档类型。
标签: c# xml xml-parsing xmlserializer asp.net-core-2.1