3

だから私は次の方法があります:

private int? myIntField
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public int? IntField{
    get {
        return this.myIntField;
    }
    set {
        this.myIntField= value;
    }
 }

現在、投稿からxmlを逆シリアル化しています。何らかの理由で、55444ではなく「ここにintフィールド:55444」などの文字列が表示された場合、応答として返されるエラーは次のとおりです。Input string was not in a correct format.これはあまり具体的ではありません。特に、検証する必要のあるintフィールドが複数あることを考えると。

もともと、私は次のような計画を立てていました。

private string myIntField
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public int? IntField{
    get {
        return this.myIntField.CheckValue();
    }
    set {
        this.myIntField= value;
    }
 }

CheckValueがtry-parseInt32に対してを実行し、失敗した場合はnullを返し、リストにエラーを追加します。ただし、生成されたクラスに対してこの設定を釘付けにすることはできないようです。

ints、DateTimesなどの代わりに文字列を取得している場合に特定のエラーをスローする方法はありますか?

4

3 に答える 3

4

XML用のスキーマがあり、逆シリアル化する前にスキーマに対して検証するのは簡単です。XMLのスキーマがあるとすると、XmlSchemaSetを初期化し、それにスキーマを追加して、次のことができます。

var document = new XmlDocument();
document.LoadXml(xml); // this a string holding the XML
document.Schemas.XmlResolver = null; //if you don't need to resolve every references
document.Schemas.Add(SchemaSet); // System.Xml.Schema.XmlSchemaSet instance filled with schemas
document.Validate((sender, args) => { ... }); //args are of type ValidationEventArgs and hold problem if there is one...            

個人的には、これがより良いアプローチだと思います。デシリアライズする前にXMLを検証し、XMLが正しいことを確認できます。そうしないと、デシリアライザーが何か問題がある場合に例外をスローし、意味のあるフィードバックを表示できなくなる可能性があります。ユーザー...
PSXMLを記述したスキーマを作成することをお勧めします

于 2012-05-09T21:48:35.203 に答える
3

「入力文字列が正しい形式ではありませんでした」というメッセージはSystem.FormatException、の呼び出しによって生成された標準からのint.Parseものであり、逆シリアル化を行う自動生成されたアセンブリに追加されます。それにカスタムロジックを追加することはできないと思います。

1つの解決策は、次のようなことを行うことです。

    [XmlElement("IntField")]
    [Browsable(false)] // not displayed in grids
    [EditorBrowsable(EditorBrowsableState.Never)] // not displayed by intellisense
    public string IntFieldString
    {
        get
        {
            return DoSomeConvert(IntField);
        }
        set
        {
            IntField = DoSomeOtherConvert(value);
        }
    }

    [XmlIgnore]
    public int? IntField { get; set; }

パブリックにアクセスできるため、完全ではありませんIntFieldStringが、少なくとも、「実際の」IntFieldプロパティはプログラムでのみ使用され、XmlSerializer(XmlIgnore)では使用されません。一方、値を前後に保持しているフィールドはプログラマーから隠されています。 (EditorBrowsable)、グリッド(Browsable)など...ただし、からではありませんXmlSerializer

于 2012-05-10T12:34:19.103 に答える
2

私はあなたのために3つのアプローチがあります。

  • データがユーザーによってユーザーインターフェイスに入力されていると仮定して、入力検証を使用してデータが有効であることを確認します。整数である必要があるときにランダムな文字列を入力できるようにするのは奇妙に思えます。

  • 上記で提案したアプローチを正確に使用してください。LINQPadを使用した例を次に示します

    void Main()
    {
        using(var stream = new StringReader(
                  "<Items><Item><IntValue>1</IntValue></Item></Items>"))
        {
            var serializer = new XmlSerializer(typeof(Container));
    
            var items = (Container)serializer.Deserialize(stream);
    
            items.Dump();
        }
    }
    
    [XmlRoot("Items")]
    public class Container
    {
        [XmlElement("Item")]
        public List<Item> Items { get; set; }
    }
    
    public class Item
    {
        [XmlElement("IntValue")]
        public string _IntValue{get;set;}
    
        [XmlIgnore]
        public int IntValue
        {
            get
            {
                // TODO: check and throw appropriate exception
                return Int32.Parse(_IntValue);
            }
        }
    }
    
  • IXmlSerializableを使用してシリアル化を制御します。別の例を次に示します。

    void Main()
    {
        using(var stream = new StringReader(
                  "<Items><Item><IntValue>1</IntValue></Item></Items>"))
        {
            var serializer = new XmlSerializer(typeof(Container));
    
            var items = (Container)serializer.Deserialize(stream);
    
            items.Dump();
        }
    }
    
    [XmlRoot("Items")]
    public class Container
    {
        [XmlElement("Item")]
        public List<Item> Items { get; set; }
    }
    
    public class Item : IXmlSerializable
    {
        public int IntValue{get;set;}
    
        public void WriteXml (XmlWriter writer)
        {
            writer.WriteElementString("IntValue", IntValue.ToString());
        }
    
        public void ReadXml (XmlReader reader)
        {
            var v = reader.ReadElementString();
            // TODO: check and throw appropriate exception
            IntValue = int.Parse(v);
        }
    
        public XmlSchema GetSchema()
        {
            return(null);
        }
    }
    
于 2012-05-10T09:31:23.380 に答える