XmlInclude 또는 SoapInclude 특성을 사용하여 정적으로 알 수 없는 유형을 지정합니다.
일을 할 때 아주 이상한 문제가 생겼습니다.NET의XmlSerializer
.
다음 예제 수업을 듣습니다.
public class Order
{
public PaymentCollection Payments { get; set; }
//everything else is serializable (including other collections of non-abstract types)
}
public class PaymentCollection : Collection<Payment>
{
}
public abstract class Payment
{
//abstract methods
}
public class BankPayment : Payment
{
//method implementations
}
AFAIK, 3가지 다른 해결 방법이 있습니다.InvalidOperationException
그건 연쇄 살인범이 그들의 유형에 대해 알지 못하기 때문에 발생하는 것입니다.Payment
.
1. 추가하기XmlInclude
에게Payment
클래스 정의:
이것은 내가 통제할 수 없는 외부 참조로 모든 클래스가 포함되어 있기 때문에 불가능합니다.
2. 생성 중에 파생된 유형의 유형을 전달합니다.XmlSerializer
사례
안 돼요.
3. 정의하기XmlAttributeOverrides
속성의 기본 직렬화를 재정의하기 위해 대상 속성에 대해(이 SO 게시물에서 설명한 대로)
또한 작동하지 않습니다(XmlAttributeOverrides
초기화는 뒤에 따릅니다.
Type bankPayment = typeof(BankPayment);
XmlAttributes attributes = new XmlAttributes();
attributes.XmlElements.Add(new XmlElementAttribute(bankPayment.Name, bankPayment));
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
overrides.Add(typeof(Order), "Payments", attributes);
적절한XmlSerializer
생성자가 사용됩니다.
메모: 작동하지 않는다는 것은.InvalidOperationException
(예상하지 못했습니다...)가 던져집니다.BankPayment
누가 그 문제를 좀 설명해 줄 수 있습니까?그 문제를 어떻게 해결하고 더 이상 디버그할 것입니까?
효과가 있었습니다.
[XmlInclude(typeof(BankPayment))]
[Serializable]
public abstract class Payment { }
[Serializable]
public class BankPayment : Payment {}
[Serializable]
public class Payments : List<Payment>{}
XmlSerializer serializer = new XmlSerializer(typeof(Payments), new Type[]{typeof(Payment)});
방금 문제를 해결했습니다.한참을 더 뒤적거리다가 똑같은 상황을 다루는 SO 게시물을 발견했습니다.제가 옳은 길을 걷게 해줬습니다.
기본적으로.XmlSerializer
파생 클래스가 추가 유형으로 포함된 경우 기본 네임스페이스를 알아야 합니다.이런 일이 발생해야 하는 정확한 이유는 아직 알 수 없지만, 지금도 직렬화가 작동하고 있습니다.
이를 바탕으로 저는 이를 해결할 수 있었습니다.XmlSerializer
수업을 바꾸는 대신 사용하고 있었습니다.
이와 같은 것을 사용하는 대신(다른 답변에서 제시):
[XmlInclude(typeof(Derived))]
public class Base {}
public class Derived : Base {}
public void Serialize()
{
TextWriter writer = new StreamWriter(SchedulePath);
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Derived>));
xmlSerializer.Serialize(writer, data);
writer.Close();
}
내가 한 짓은
public class Base {}
public class Derived : Base {}
public void Serialize()
{
TextWriter writer = new StreamWriter(SchedulePath);
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Derived>), new[] { typeof(Derived) });
xmlSerializer.Serialize(writer, data);
writer.Close();
}
그냥 베이스에서 하면 어떤 아이라도 코드 클리너 코드를 줄이지 않고 직렬화할 수 있습니다.
public abstract class XmlBaseClass
{
public virtual string Serialize()
{
this.SerializeValidation();
XmlSerializerNamespaces XmlNamespaces = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty });
XmlWriterSettings XmlSettings = new XmlWriterSettings
{
Indent = true,
OmitXmlDeclaration = true
};
StringWriter StringWriter = new StringWriter();
XmlSerializer Serializer = new XmlSerializer(this.GetType());
XmlWriter XmlWriter = XmlWriter.Create(StringWriter, XmlSettings);
Serializer.Serialize(XmlWriter, this, XmlNamespaces);
StringWriter.Flush();
StringWriter.Close();
return StringWriter.ToString();
}
protected virtual void SerializeValidation() {}
}
[XmlRoot(ElementName = "MyRoot", Namespace = "MyNamespace")]
public class XmlChildClass : XmlBaseClass
{
protected override void SerializeValidation()
{
//Add custom validation logic here or anything else you need to do
}
}
이렇게 하면 상황에 상관없이 하위 클래스에서 Serialize를 호출하고 개체 Serialize 전에 필요한 작업을 수행할 수 있습니다.
비즐에 동의합니다.
[XmlInclude(typeof(ParentOfTheItem))]
[Serializable]
public abstract class WarningsType{ }
또한 만약 당신이 이 포함된 클래스를 객체 아이템에 적용해야 한다면 그렇게 할 수 있습니다.
[System.Xml.Serialization.XmlElementAttribute("Warnings", typeof(WarningsType))]
public object[] Items
{
get
{
return this.itemsField;
}
set
{
this.itemsField = value;
}
}
추가했습니다.[System.Xml.Serialization.XmlAttributeAttribute()]
재산에 관해서는 저를 위해 해결했습니다.
언급URL : https://stackoverflow.com/questions/11886290/use-the-xmlinclude-or-soapinclude-attribute-to-specify-types-that-are-not-known
'programing' 카테고리의 다른 글
PowerShell에서 $Error를 삭제하는 방법은 무엇입니까? (0) | 2023.09.17 |
---|---|
하는 를 지원하는 브라우저 하는 를 지원하는 브라우저 하는 를 지원하는 브라우저 ??? (0) | 2023.09.17 |
ID가 다른 MySQL 선택 * (0) | 2023.09.17 |
Angular CLI에서 피어 종속성을 설치하려면 어떻게 해야 합니까? (0) | 2023.09.17 |
RMySQL에서 결과 집합을 닫는 방법은? (0) | 2023.09.17 |