我正在编写代码来进行Xml序列化.具有以下功能.
public static string SerializeToXml(object obj)
{
XmlSerializer serializer = new XmlSerializer(obj.GetType());
using (StringWriter writer = new StringWriter())
{
serializer.Serialize(writer, obj);
return writer.ToString();
}
}
Run Code Online (Sandbox Code Playgroud)
如果参数是没有无参数构造函数的类的实例,它将抛出异常.
未处理的异常:System.InvalidOperationException:CSharpConsole.Foo无法序列化,因为它没有无参数构造函数.System.Xml.Serialization.ModelScope.GetTypeModel的System.Xml.Serialization.TypeScope.GetTypeDesc(Type type,MemberInfo sourc e,Boolean directReference,Boolean throwOnError)中的System.Xml.Serialization.TypeDesc.CheckSupported()处于类型类型, System.Xml.Serialization上的System.Xml.Serialization.XmlSerializer..ctor(Type type,String defaultName space)中System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type,XmlRootAttribute root,String defaultNamespace)的布尔直接引用. XmlSerializer..ctor(类型类型)
为什么必须有一个无参数构造函数才能使xml序列化成功?
编辑:感谢cfeduke的回答.无参数构造函数可以是私有的或内部的.
在C#中,我有一个类,它有一个派生属性,应该通过XML序列化.但是,XML序列化(默认情况下)不会序列化read = only属性.我可以通过定义一个空的setter来解决这个问题:
public virtual string IdString
{
get { return Id.ToString("000000"); }
set { /* required for xml serialization */ }
}
Run Code Online (Sandbox Code Playgroud)
但是,除了编写自己的ISerializable实现之外,还有一种更清晰,语义更正确的方法吗?
有没有办法在C#中使用内部setter序列化属性?
我知道这可能有问题 - 但如果有办法 - 我想知道.
例:
[Serializable]
public class Person
{
public int ID { get; internal set; }
public string Name { get; set; }
public int Age { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
序列化类Person实例的代码:
Person person = new Person();
person.Age = 27;
person.Name = "Patrik";
person.ID = 1;
XmlSerializer serializer = new XmlSerializer(typeof(Person));
TextWriter writer = new StreamWriter(@"c:\test.xml");
serializer.Serialize(writer, person);
writer.Close();
Run Code Online (Sandbox Code Playgroud)
结果(缺少ID属性):
<?xml version="1.0" encoding="utf-8"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>Patrik</Name>
<Age>27</Age>
</Person>
Run Code Online (Sandbox Code Playgroud) 我创建了一个部分类文件,以便为我的Entity-Framework生成的模型添加新属性.
我使用的是WebAPI + OData,$元数据没有列出我的新/自定义属性,因此它返回的JSON不包含我的新/自定义属性.
例如,假设我的实体是"人"
"Person"有一个Database属性; NumSpouses; 一个在$元数据中返回的int,如下所示:
<Property Name="NumSpouses" Type="Edm.Int32"/>
这很好,但是我将这样的属性添加到一个单独的文件中,并带有一个部分类:
public partial class Person {
...
public string MarriedStatus {
get { return this.NumSpouses==0 ? "Single" : "Married"; }
}
...
}
Run Code Online (Sandbox Code Playgroud)
如何在我的OData响应中获得此属性?
<Property Name="MarriedStatus" Type="Edm.String"/>
目前,如果我问MarriedStatus的$expand(就好像它是一个NavigationProperty ....它不是[我想我会尝试$不管怎么说扩大,因为如果它神奇地提供自定义属性]),我得到的消息是这样的:
{
"odata.error":{
"code":"","message":{
"lang":"en-US","value":"The query specified in the URI is not valid. Could not find a property named 'MarriedStatus' on type 'fakeDataModels.Person'."
},"innererror":{
"message":"Could not find a property named 'MarriedStatus' on type 'fakeDataModels.Person'.","type":"Microsoft.Data.OData.ODataException","stacktrace":" …Run Code Online (Sandbox Code Playgroud) 我打算用序列化做克隆.我必须让我的课程ISerializable.但是它的超级类和所有引用的变量类呢?我需要将它们全部变为ISerializable吗?
如果我使用ISerializable.我必须实现GetObjectData(),我应该放在该方法中?把它留空是好的吗?
我有一个类DocumentMetaData,我正在尝试序列化为XML.它是一个公共类,其中的所有元素都是公共的,但有一个元素不会出现在XML输出中,但应该是.(另一个用XmlIgnore标记.)我试图找出为什么跳过这个元素.
public class DocumentMetaData
{
[XmlElement(ElementName="docType")]
public string DocType { get; set; }
[XmlElement(ElementName = "companyName")]
public string CompanyName { get; set; }
[XmlElement(ElementName = "countryName")]
public string CountryName { get; set; }
[XmlElement(ElementName = "clientName")]
public string ClientName { get; set; }
[XmlElement(ElementName = "manufacturer")]
public string Manufacturer { get; set; }
[XmlIgnore]
public DateTime ConversionDate { get; set; }
[XmlElement(ElementName = "conversionDate")]
public string ConversionDateString
{
get { return ConversionDate.ToShortDateString(); }
}
Run Code Online (Sandbox Code Playgroud)
}
生成的XML如下所示:
<docMeta>
<docType>Text</docType>
<companyName>Text</companyName>
<countryName>Text</countryName> …Run Code Online (Sandbox Code Playgroud)