【问题标题】:need to have child by using DataContractSerializer to populate XML需要通过使用 DataContractSerializer 来填充 XML
【发布时间】:2014-11-12 18:43:00
【问题描述】:

我有一种方法可以将错误消息放入 1 个 xml 并将其发送给客户端。如果出现错误,错误可能是多个,我将返回 XMLErrMessage 中的 pf 错误列表。我想在评论中显示它们,但每个错误都显示为 1 个 xml 子项:

  <comments>
     <comment>XMLErrMessage1</comment>
     <comment>XMLErrMessage2</comment>
    <comment>XMLErrMessage3</comment>
  </comments>

这是我的方法:

    public string ProcessXML(CommonLibrary.Model.TransferData dto, bool Authenticated)
    {
        DataContractSerializer dcs = new DataContractSerializer(typeof(CFCConnectResponse));
        MemoryStream ms = new MemoryStream();
        utility.utilities utl = new utility.utilities();
        List<string> XMLErrMessage =null;

        if (Authenticated)
        {
            if (!string.IsNullOrEmpty(dto.xml))
            {
                XMLErrMessage = utl.validateXML(dto.xml, xsdFilePath, currentSchema);

                if (XMLErrMessage.Count==1)
                {
                    dcs.WriteObject(ms, new CFCConnectResponse() { StatusCode = 101, StatusDescription = "Success" });
                    ms.Position = 0;
                }
                else
                {
                    dcs.WriteObject(ms, new CFCConnectResponse() { StatusCode = 201, StatusDescription = "XML Validation Fails", Comments=XMLErrMessage });
                    ms.Position = 0;
                }
            }
        }
        else
        {
            dcs.WriteObject(ms, new CFCConnectResponse() { StatusCode = 401, StatusDescription = "Authentication Fails" });
           // ms.Position = 0;
        }
        string s = new StreamReader(ms).ReadToEnd();  // xml result
        Console.WriteLine(s);
        return s;
    }

这是合同类:

public class CFCConnectResponse
{
    [DataMember]
    public int StatusCode;
    [DataMember]
    public string StatusDescription;
    [DataMember]
    public List<string> Comments;

【问题讨论】:

标签: c# xml wcf datacontractserializer


【解决方案1】:

CollectionDataContract 属性允许您控制集合元素名称,但是由于它只能针对类或结构,因此您必须使用所需的协定创建 List&lt;T&gt; 的自定义子类,如下所示:

[DataContract(Namespace = "")]
[KnownType(typeof(CommentList))]
public class CFCConnectResponse
{
    [DataMember]
    public int StatusCode;
    [DataMember]
    public string StatusDescription;
    [DataMember(Name="comments")]
    public CommentList Comments;
}

[CollectionDataContract(ItemName = "comment", Namespace="")]
public class CommentList : List<string>
{
    public CommentList()
        : base()
    {
    }

    public CommentList(params string[] strings)
        : base(strings)
    {
    }

    public CommentList(IEnumerable<string> strings)
        : base(strings)
    {
    }
}

然后,进行测试:

public static class TestCFCConnectResponse
{
    static CFCConnectResponse CreateTest()
    {
        return new CFCConnectResponse()
        {
            StatusCode = 101,
            StatusDescription = "here is a description",
            Comments = new CommentList("XMLErrMessage1", "XMLErrMessage2", "XMLErrMessage3"),
        };
    }

    public static void Test()
    {
        var response = CreateTest();

        try
        {
            var xml = DataContractSerializerHelper.GetXml(response);
            Debug.Write(xml);
            var newResponse = DataContractSerializerHelper.GetObject<CFCConnectResponse>(xml);
            Debug.Assert(newResponse != null);
            Debug.Assert(response.StatusCode == newResponse.StatusCode);
            Debug.Assert(response.StatusDescription == newResponse.StatusDescription);
            Debug.Assert(newResponse.Comments.SequenceEqual(response.Comments));
        }
        catch (Exception ex)
        {
            Debug.Assert(false, ex.ToString());
        }
    }
}

这会产生以下输出,没有断言:

<?xml version="1.0" encoding="utf-16"?>
<CFCConnectResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <StatusCode>101</StatusCode>
    <StatusDescription>here is a description</StatusDescription>
    <comments>
        <comment>XMLErrMessage1</comment>
        <comment>XMLErrMessage2</comment>
        <comment>XMLErrMessage3</comment>
    </comments>
</CFCConnectResponse>

更新

如果更改 CFCConnectResponse.CommentList 以获取和设置 CommentList 需要对旧代码进行太多更改,您可以执行以下操作:

[DataContract(Namespace = "")]
[KnownType(typeof(CommentList))]
public class CFCConnectResponse
{
    [DataMember]
    public int StatusCode;

    [DataMember]
    public string StatusDescription;

    [IgnoreDataMember]
    public List<string> Comments { get; set; }

    [DataMember(Name = "comments")]
    private CommentList SerializableComments
    {
        get
        {
            return new CommentList(Comments);
        }
        set
        {
            Comments = value.ToList();
        }
    }
}

这会在序列化和反序列化 CommentList 时保留 List&lt;string&gt; Comments 属性。

【讨论】:

  • 谢谢@dbc,我的问题是这一行:Comments = new CommentList("XMLErrMessage1", "XMLErrMessage2", "XMLErrMessage3"),如何使用正确的代码使其工作:dcs.WriteObject( ms, new CFCConnectResponse() { StatusCode = 201, StatusDescription = "XML Validation Fails", Comments=XMLErrMessage
  • Comments=XMLErrMessage中的XMLErrMessage是什么类型?
  • XMLErrMessage 是字符串列表。列表
  • 你需要做Comments=new CommentList(XMLErrMessage)Comments 属性是否已在您的代码中广泛使用,导致更改变得困难?
  • @nikoom - 如果在任何地方更改 CFCConnectResponse.CommentList 以获取和设置 CommentList 工作量太大,请尝试更新的解决方案。
猜你喜欢
  • 2011-03-24
  • 2010-12-26
  • 2019-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多