使用XSD驗證對象:重新序列化冗餘還是可以忽略不計?


2

上下文:

我有一個處理請求/響應對象的Web服務。有嚴格的,外部定義的模式,它們限制了請求和響應的結構和內容。我需要驗證所有收到的請求和所有響應,然後再將它們發送回(在網絡的Web服務端)。

我不想在代碼中復制驗證規則,所以我將驗證序列化的請求/響應對象(XML),可能使用XmlReader作為起點(為了提高速度)。如果驗證失敗,它將是1向對象-> XML驗證方法,否則原始對象將用於實際工作。

我正在使用WCF,但是使用XMLSerializer時,因為架構很複雜,我需要其他XSD支持。

問題:

1)是否有一種方法可以避免在對象碰到電線末端時重新序列化它們?理想地我想了解一下XML,然後再將其反序列化,然後再對其進行序列化,然後再進行輸出。

我知道[OnSerializing]和[OnSerialized]批註,但是它們不能與XMLSerializer一起使用。我不認為我應該使用IXmlSerializable來編寫ReadXml()和WriteXml()-模式很複雜並且會隨時更改。

2)鑑於XML文檔非常小(122kb似乎是我擁有的示例數據集中的頂端),我是否正確認為重新序列化的性能影響可以忽略不計?

3)還有更好的主意嗎?

0

Have you thought about using the XSD code-gen tools? They can deserialize/serialize and validate via schema orders of magnitude faster than other techniques in C#. You can use partial classes or wrapper classes to add additional fields or object hierarchy for your domain business logic.

xsd.exe schema.xsd /classes

Some code I lifted from here: http://snipplr.com/view/2660/serializing-and-deserializing-a-class-created-with-xsdexe-using-xml-strings/

public static string SerializeToXmlString(object targetInstance)
{
    string retVal = string.Empty;
    TextWriter writer = new StringWriter();
    XmlSerializer serializer = new XmlSerializer(targetInstance.GetType());
    serializer.Serialize(writer, targetInstance);
    retVal = writer.ToString(); 
    return retVal; 
}

public static object DeserializeFromXmlString(string objectXml, Type targetType)
{
    object retVal = null;
    XmlSerializer serializer = new XmlSerializer(targetType);
    StringReader stringReader = new StringReader(objectXml);
    XmlTextReader xmlReader = new XmlTextReader(StringReader);
    retVal = serializer.Deserialize(xmlReader); 
    return retVal; 
}

If you can't use XSD.exe (as you imply in your comments) then how about writing a few helper class functions that use XmlDocument.Validate right as you receive or send the messages? http://msdn.microsoft.com/en-us/library/ms162371.aspx You wouldn't really be duplicating validation code if it's a shared component.

From their nice example:

XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd");
settings.ValidationType = ValidationType.Schema;

XmlReader reader = XmlReader.Create("contosoBooks.xml", settings);
XmlDocument document = new XmlDocument();
document.Load(reader);

ValidationEventHandler eventHandler = new ValidationEventHandler(ValidationEventHandler);

// the following call to Validate succeeds.
document.Validate(eventHandler);

1

To answer my own question: yes re-serializing would have been redundant.

The answer I was looking for was to use Message Inspectors - job done.