我有一个ASP.NET core 2.1 MVC项目,我正在从Serlilog MSSqlServr接收器检索数据,该数据存储在Properties字段中作为XML数据类型。我想将该数据反序列化到视图模型中,以便可以在视图中将各个元素显示为数据。
这是数据库“日志”表中“属性”字段中XML的示例。
form-group
我为解码设置了一个类,如下所示:
userRepository.find({
where: [
{
email: 'giberish@gmail.com',
},
{
username: 'thisismyusername',
},
]
});
在我的控制器中,我有以下代码;
errmsg:
'Error getting filter : Error getting filter BSON field from doc = [{find user} {filter [[{email giberish@gmail.com}] [{username thisismyusername}]]} {returnKey false} {showRecordId false} {$clusterTime [{clusterTime 6660127540193001473} {signature [{hash [184 253 193 112 111 39 205 239 38 92 178 205 149 85 131 136 252 114 180 30]} {keyId 6637077103550398465}]}]}] : not bson []interface {} [[{email craftball@gmail.com}] [{username thisismyusername}]]\n\tat erh/mongonet/bsonutil.go:122\n\tat 10gen/atlasproxy/bson_util.go:32\n\tat 10gen/atlasproxy/commands_security.go:521\n\tat 10gen/atlasproxy/commands.go:653\n\tat 10gen/atlasproxy/commands.go:563\n\tat 10gen/atlasproxy/session_proxy.go:256\n\tat 10gen/atlasproxy/session_proxy.go:702\n\tat 10gen/atlasproxy/session_proxy.go:526\n\tat erh/mongonet/proxy.go:209\n\tat erh/mongonet/proxy.go:104\n\tat erh/mongonet/session.go:82\n\tat src/runtime/asm_amd64.s:2361',
code: 8000,
codeName: 'AtlasError',
name: 'MongoError'
但是logProperties变量不包含任何内容,因此我假设我在LogProperties类中具有错误的XML属性。
我花了很多时间寻找解决方案,并在输入此问题时查看了所有相关文章,但是我找不到XML使用“ property key =“或如何处理XML的示例。带有“ key =“属性属性(如果这是正确的术语)
有什么想法吗?
[UPDATE 2/21/19]
我最终使用了@jdweng建议,因为它最简单,并且给了我我想要的东西。
我创建了2个班级(因为我想将班级文件分开作为个人偏好)。这些课程在下面;
<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; }
}
}
然后在我的控制器中,我对Detail方法有以下要求;
var serializer = new XmlSerializer(typeof(LogProperties));
LogProperties logProperties;
using (TextReader reader = new StringReader(log.Properties))
{
logProperties = (LogProperties)serializer.Deserialize(reader);
}
我的DetailLogWithPropertiesViewModel在下面;
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; }
}
}
下面是我的Detail.cshtml的相关部分;
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; }
}
}
由Serilog生成并存储在MS SQL数据库中的XML具有可变数量的属性,我现在理解这些属性表示为键/值对。因此,该方法使我可以确保所有提供的属性都显示在网站的日志查看器中。
答案 0 :(得分:1)
尝试以下操作:
[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; }
}
答案 1 :(得分:0)
1)将XML复制到剪贴板...
2)...打开Visual Studio并创建一个空的CS文件...
3)...转到“编辑”>“选择性粘贴”>“ XML到类”(可能需要安装ASP.NET Web开发)...
3)...将产生以下代码:
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class properties
{
private propertiesProperty[] propertyField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("property")]
public propertiesProperty[] property
{
get
{
return this.propertyField;
}
set
{
this.propertyField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class propertiesProperty
{
private propertiesPropertyStructure structureField;
private string[] textField;
private string keyField;
/// <remarks/>
public propertiesPropertyStructure structure
{
get
{
return this.structureField;
}
set
{
this.structureField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTextAttribute()]
public string[] Text
{
get
{
return this.textField;
}
set
{
this.textField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string key
{
get
{
return this.keyField;
}
set
{
this.keyField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class propertiesPropertyStructure
{
private propertiesPropertyStructureProperty propertyField;
private string typeField;
/// <remarks/>
public propertiesPropertyStructureProperty property
{
get
{
return this.propertyField;
}
set
{
this.propertyField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string type
{
get
{
return this.typeField;
}
set
{
this.typeField = value;
}
}
}
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class propertiesPropertyStructureProperty
{
private string keyField;
private ushort valueField;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string key
{
get
{
return this.keyField;
}
set
{
this.keyField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTextAttribute()]
public ushort Value
{
get
{
return this.valueField;
}
set
{
this.valueField = value;
}
}
}
4)是,很多代码o_O。使用XmlDeserializer(typeof(properties))
答案 2 :(得分:0)
如果您制作LogProperties类的示例实例,并像这样序列化它:
var serializer = new XmlSerializer(typeof(LogProperties));
LogProperties logProperties = new LogProperties()
{
SourceContext = "MySourceContext",
ActionId = "MyActionId",
ActionName = "MyActionName"
};
StringBuilder sb = new StringBuilder();
using (StringWriter writer = new StringWriter(sb))
{
serializer.Serialize(writer, logProperties);
}
Console.WriteLine(sb.ToString());
这是您得到的:
<?xml version="1.0" encoding="utf-16"?>
<properties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SourceContext>MySourceContext</SourceContext>
<ActionId>MyActionId</ActionId>
<ActionName>MyActionName</ActionName>
</properties>
因此您拥有的类与您拥有的XML不太匹配。尝试双向进行序列化总是很有用的。
下面是一种将拥有的XML序列化为拥有的类的方法(将对象模型和持久性格式清楚地分开)。它使用System.Xml.Linq命名空间中的XDocument类。
// Must escape all quotes !
string xmlSample = @"
<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>";
StringReader reader = new StringReader(xmlSample);
XDocument xdoc = XDocument.Parse(xmlSample);
LogProperties log = new LogProperties();
foreach (XElement prop in xdoc.Root.Elements())
{
switch (prop.Attribute("key").Value)
{
case "ActionId" : log.ActionId = prop.Value; break;
case "ActionName" : log.ActionName = prop.Value; break;
// and so on
}
}
请注意,使用这种方法: