У меня есть проект ASP.NET core 2.1 MVC, и я получаю данные из приемника Serlilog MSSqlServr, который хранит значения в поле Properties в качестве типа данных XML.Я хочу десериализовать эти данные в модель представления, чтобы я мог представить отдельные элементы в виде данных в представлении.
Вот пример XML из поля Properties в таблице журналов базы данных.
<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 ничего не содержит, поэтому я предполагаю, что у меня неверные атрибуты XML в классе LogProperties.
Я потратил довольно много времени на поиск решения, и при вводе этого вопроса я просмотрел все связанные посты, но не смог найти пример, где в XML используется «ключ свойства =» или как справиться сАтрибут «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);
My DetailLogWithPropertiesViewModel isниже;
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>
XML, который генерируется Serilog и хранится в базе данных MS SQL, имеет переменный номерсвойств, которые я теперь понимаю, представлены в виде пар ключ / значение.Таким образом, этот метод позволяет мне убедиться, что все предоставленные свойства отображаются в средстве просмотра журнала на веб-сайте.