我知道Json.net有一个属性[JsonRequired];是否有任何XML方法可以做同样的事情?。
我认为没有,所以我已经按照自己的方式这样做,但我已经停止了如何处理反射中的List和T.
如果有人告诉我,这是一个很好的帮助,谢谢。
class Program
{
static void Main(string[] args)
{
string strin = "<TestXML><Fir>f</Fir><TestXML1><TestXML3><For>444</For></TestXML3></TestXML1></TestXML>";
TestXML ttt1 = XmlToModel<TestXML>(strin);
Console.ReadKey();
}
public static T XmlToModel<T>(string xml)
{
StringReader xmlReader = new StringReader(xml);
XmlSerializer xmlSer = new XmlSerializer(typeof(T));
T t = (T)xmlSer.Deserialize(xmlReader);
Type typeT = typeof(T);
IfIsClass<T>(typeT, t);
return t;
}
private static void IfIsClass<T>(Type typeT, T t)
{
foreach (PropertyInfo p in typeT.GetProperties())
{
//here I don't konw how to handle List<T> and T
//if(is List<T> or T)
// IfisClass<T>(typeT,t);
IfIsNull<T>(p, t);
}
}
private static void IfIsNull<T>(PropertyInfo p, T t)
{
var at = p.GetCustomAttribute(typeof(NotNullAttribute));
var pvalue = p.GetValue(t);
if (at != null && string.IsNullOrEmpty(pvalue == null ? "" : pvalue.ToString()))
{
throw new Exception(string.Format("Field {0} not allow null or empty", p.Name));
}
}
}
public class TestXML
{
public string Fir { get; set; }
[NotNull]
public string Sec { get; set; }
[XmlElement("")]
public List<TestXML2> TestXML1 { get; set; }
}
public class TestXML2
{
public string Thir { get; set; }
public TestXML3 TestXML3 { get; set; }
}
public class TestXML3
{
[NotNull]
public string For { get; set; }
}
public class NotNullAttribute : Attribute
{
}
答案 0 :(得分:1)
我不会100%知道你现在正在做什么,而且我也不知道你不想要的是哪些价值观为null,但我确实看到有一种更简单的方法将XML反序列化为对象(参见here以供参考):
[XmlRoot("TestXML")]
public class TestXML
{
[XmlElement("Fir")]
public string Fir { get; set; }
[XmlArray("TestXML1")]
[XmlArrayItem("TestXML3", IsNullable = false)]
public TestXML3[] testxml3 { get; set; }
}
public class TestXML3
{
[XmlElement("For")]
public int For { get; set; }
}
public class Order
{
[XmlElement("number")]
public string Number { get; set; }
}
完成后,您可以使用以下命令在同一文件中的任何位置反序列化xml:
string xml = @"<TestXML><Fir>f</Fir><TestXML1><TestXML3><For>444</For></TestXML3></TestXML1></TestXML>";
StringReader reader = new StringReader(xml);
XmlSerializer ser = new XmlSerializer(typeof(TestXML));
var data = (TestXML)ser.Deserialize(reader);
基本上,您只需在[XmlArrayItem]的括号内添加IsNullable = false
,以确保特定值不会返回null(它将跳过它)。 注意: 我只在[XmlArrayItem]
上对此进行了测试,我不确定它是否适用于其他Xml标记......
如果你真的想要使用C#并抛出异常,如果它是null(这首先破坏了使用[XmlElement]
的意义),你可以做这样的事情(见here):
... //same code as before
var data = (TestXML)ser.Deserialize(reader);
//haven't tested this
foreach(obj dataobj in data){
if(dataobj == null) throw new NullReferenceException();
}
如果你真的想使用像[JsonRequired]这样的东西,那么为什么不用它呢!您可以使用Json.Net将XML数据转换为JSON数据(请参阅here):
string xml = @"<TestXML><Fir>f</Fir><TestXML1><TestXML3><For>444</For></TestXML3></TestXML1></TestXML>";
XmlDocument Test = new XMLDocument();
Test.loadXml(xml);
string json = JsonConvert.SerializeXmlNode(Test);
现在,您可以在string json
中以json格式获取xml数据,并且可以执行任何您想要的操作,包括像使用xml一样设置地图并添加[JsonRequired]
答案 1 :(得分:0)
public static T XmlToModel<T>(string xml)
{
StringReader xmlReader = new StringReader(xml);
XmlSerializer xmlSer = new XmlSerializer(typeof(T));
T t = (T)xmlSer.Deserialize(xmlReader);
Type typeT = typeof(T);
IfIsClass(t);
return t;
}
private static void IfIsClass(object t)
{
var typeT = t.GetType();
foreach (PropertyInfo p in typeT.GetProperties())
{
if (typeof(System.Collections.ICollection).IsAssignableFrom(p.PropertyType))
{
var vValue = p.GetValue(t, null) as System.Collections.ICollection;
foreach(var item in vValue )
{
IfIsClass(item);
}
}
else
{
IfIsNull(p, p.GetValue(t, null));
}
}
}
private static void IfIsNull(PropertyInfo p, object pvalue)
{
var at = p.GetCustomAttribute(typeof(NotNullAttribute));
if (at != null && string.IsNullOrEmpty(pvalue == null ? "" : pvalue.ToString()))
{
throw new Exception(string.Format("field[{0}]not allow null or empty", p.Name));
}
}
答案 2 :(得分:-4)
添加构造函数
public TestXML()
{
Sec = "";
}