gpt4 book ai didi

c# - 如何将使用键的 XML 反序列化为对象

转载 作者:太空宇宙 更新时间:2023-11-03 12:06:18 24 4
gpt4 key购买 nike

我有一个 ASP.NET core 2.1 MVC 项目,我正在从 Serlilog MSSqlServr Sink 检索数据,该 Sink 将值作为 XML 数据类型存储在 Properties 字段中。我想将该数据反序列化到 View 模型中,以便我可以将各个元素作为 View 中的数据呈现。

这是数据库日志表中属性字段的 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; }

}
}

在我的 Controller 中,我有以下代码;

        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=”属性(如果这是正确的术语)

有什么想法吗?

[2019 年 2 月 21 日更新]

我最终使用了@jdweng 的建议,因为它最不复杂,而且给我的正是我想要的。

我创建了 2 个类(class)(因为我喜欢将我的类(class)文件分开作为个人偏好)。类(class)如下;

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; }
}
}

然后在我的 Controller 中,我有以下 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 具有可变数量的属性,我现在理解它们表示为键/值对。所以这个方法可以让我确保所有提供的属性都显示在网站的日志查看器中。

最佳答案

尝试以下操作:

    [XmlRoot("properties")]
public class LogProperties
{

[XmlElement("property")]
public List<LogProperty> property { get; set; }

}
[XmlRoot("property")]
public class LogProperty
{
[XmlAttribute("key")]
public string key { get; set; }
[XmlText]
public string value { get; set; }
}

关于c# - 如何将使用键的 XML 反序列化为对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54791644/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com