Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# XmlSerializer反序列化失败_C#_Xml_Xmlserializer - Fatal编程技术网

C# XmlSerializer反序列化失败

C# XmlSerializer反序列化失败,c#,xml,xmlserializer,C#,Xml,Xmlserializer,我有来自第三方服务器的wsdl。运行svcutil并最终得到一组 XmlNode AMethod(object Request); 方法。有一个单独的100页pdf,描述每个方法的响应/请求对象 我的想法是包装web方法并使用XmlSerializer返回强类型对象。返回的xml如下所示(我删除了soap头): 看起来很简单。创建了一个类(从文档/连线捕获): 处理时间: //XmlNode node = xml from above XmlSerializer serializer = ne

我有来自第三方服务器的wsdl。运行svcutil并最终得到一组

XmlNode AMethod(object Request);
方法。有一个单独的100页pdf,描述每个方法的响应/请求对象

我的想法是包装web方法并使用XmlSerializer返回强类型对象。返回的xml如下所示(我删除了soap头):

看起来很简单。创建了一个类(从文档/连线捕获):

处理时间:

//XmlNode node = xml from above
XmlSerializer serializer = new XmlSerializer(typeof(MyClass));
XmlNodeReader reader =  new XmlNodeReader(node);
Myclass myclass = serializer.Deserialize(reader) as MyClass
最后一行显示内部异常消息:未识别指定的类型:name='ResponseExt',namespace='',位于

我不知道如何让连载器快乐,以及这两个词到底是什么意思

xsi:type=“ResponseExt” xmlns=”http://www.thirdparty.com/lr/

如往常一样,任何建议和指针都将受到赞赏


编辑:接受下面的答案

我还是有例外,直到我发现这个,希望它能节省一些时间。 我开始反向工作。在线捕获xml。使用正确的属性反序列化到我创建的类:像一个符咒一样工作。从webservice-exception重试。出于某种原因,XmlSerializer无法识别ResponseText

XmlSerializer serializer = new XmlSerializer(typeof(Response));
XmlNode node = (XmlNode)results[0];
XmlDocument doc = new XmlDocument();
doc.LoadXml(node.OuterXml); //reload node
XmlNodeReader reader = new XmlNodeReader(doc.FirstChild); //there is only one node
Response rsp = serializer.Deserialize(reader) as Response; //works

编辑:基础问题wsdl文件不完整。在花了2天时间解决此问题并找到了此(难看的)解决方法后,第三方供应商提供了具有所有类型的完整的wsdl,这些类型都可以反序列化而没有错误。

既然有wsdl,为什么要手动反序列化XML

如果您有WSDL,请使用svcutil.exe工具或WSDL.exe工具,为在线发送和接收的XML消息生成代理类和DTO

web服务工具包或“堆栈”的要点是为您提供这一点,这样您就不必手动编写类和XML序列化代码

您尝试过这个吗?您尝试过通过这些工具之一运行WSDL吗?或者您尝试过在VisualStudio中“添加web引用”吗


更新问题后,我建议您修改WSDL,而不是编写自定义代码。您可以为服务生成自定义WSDL,该WSDL将正确生成您想要的代理类。如果您不需要所有100个方法(或者不管有多少个方法)如果您希望从方法中获得自定义对象,请定义与该对象对应的complexType。这比手动为每个方法编写XML反序列化代码要简单得多,也更可靠


如果您不喜欢这种想法,并且希望继续手动编写XML反序列化代码,那么您需要做两件事:

  • 附上

  • 将类的名称更改为
    ResponseExt
    ,并从名为
    Response
    的类派生它。使用属性装饰该响应类。这将使

  • 在代码中看起来像这样:

    [XmlRoot("Response", Namespace="http://www.thirdparty.com/lr/")]
    public class ResponseExt : Response {
    }
    
    [XmlRoot("Response", Namespace="http://www.thirdparty.com/lr/")]
    [XmlInclude(typeof(ResponseExt))]
    public class Response {
        public string Code {get; set;}
        public string Message {get; set;}
        public string SessionId {get; set;}
    }
    
    public class XsiType
    {
        public static void Main(string[] args)
        {
            try
            {
                string filename = "XsiType.xml";
                XmlSerializer s1 = new XmlSerializer(typeof(Response));
                ResponseExt r = null;
                using(System.IO.StreamReader reader= System.IO.File.OpenText(filename))
                {
                    r= (ResponseExt) s1.Deserialize(reader);
                }
    
                var builder = new System.Text.StringBuilder();
                var xmlws = new System.Xml.XmlWriterSettings { OmitXmlDeclaration = true, Indent= true };
                using ( var writer = System.Xml.XmlWriter.Create(builder, xmlws))
                {
                    //s1.Serialize(writer, r, ns);
                    s1.Serialize(writer, r);
                }
                string xml = builder.ToString();
                System.Console.WriteLine(xml);
    
            }
            catch (System.Exception exc1)
            {
                Console.WriteLine("Exception: {0}", exc1.ToString());
            }
        }
    }
    

    相关:

    当您有WSDL时,为什么要手动反序列化XML

    如果您有WSDL,请使用svcutil.exe工具或WSDL.exe工具,为在线发送和接收的XML消息生成代理类和DTO

    web服务工具包或“堆栈”的要点是为您提供这一点,这样您就不必手动编写类和XML序列化代码

    您尝试过这个吗?您尝试过通过这些工具之一运行WSDL吗?或者您尝试过在VisualStudio中“添加web引用”吗


    更新问题后,我建议您修改WSDL,而不是编写自定义代码。您可以为服务生成自定义WSDL,该WSDL将正确生成您想要的代理类。如果您不需要所有100个方法(或者不管有多少个方法)如果您希望从方法中获得自定义对象,请定义与该对象对应的complexType。这比手动为每个方法编写XML反序列化代码要简单得多,也更可靠


    如果您不喜欢这种想法,并且希望继续手动编写XML反序列化代码,那么您需要做两件事:

  • 附上

  • 将类的名称更改为
    ResponseExt
    ,并从名为
    Response
    的类派生它。使用属性装饰该响应类。这将使

  • 在代码中看起来像这样:

    [XmlRoot("Response", Namespace="http://www.thirdparty.com/lr/")]
    public class ResponseExt : Response {
    }
    
    [XmlRoot("Response", Namespace="http://www.thirdparty.com/lr/")]
    [XmlInclude(typeof(ResponseExt))]
    public class Response {
        public string Code {get; set;}
        public string Message {get; set;}
        public string SessionId {get; set;}
    }
    
    public class XsiType
    {
        public static void Main(string[] args)
        {
            try
            {
                string filename = "XsiType.xml";
                XmlSerializer s1 = new XmlSerializer(typeof(Response));
                ResponseExt r = null;
                using(System.IO.StreamReader reader= System.IO.File.OpenText(filename))
                {
                    r= (ResponseExt) s1.Deserialize(reader);
                }
    
                var builder = new System.Text.StringBuilder();
                var xmlws = new System.Xml.XmlWriterSettings { OmitXmlDeclaration = true, Indent= true };
                using ( var writer = System.Xml.XmlWriter.Create(builder, xmlws))
                {
                    //s1.Serialize(writer, r, ns);
                    s1.Serialize(writer, r);
                }
                string xml = builder.ToString();
                System.Console.WriteLine(xml);
    
            }
            catch (System.Exception exc1)
            {
                Console.WriteLine("Exception: {0}", exc1.ToString());
            }
        }
    }
    

    相关:

    Cheeso,我确实不幸地运行了这些工具。wsdl不包含请求/响应信息。所有方法都接受对象并返回XmlNode。有一个单独的文档描述每个方法。我更新了问题以澄清问题。用名称空间更新了代码,重命名了类。仍然是相同的例外不确定为什么。如果我是你的话我将简化它,并将反序列化与消息传输分离。一旦您可以使用文件系统文件反序列化您认为需要反序列化的类型的消息,然后将该反序列化代码移回WCF代理以从XmlDocument反序列化。一种前进的方法。Cheeso,不幸的是,我确实运行了工具,wsdl没有t包含请求/响应信息所有方法都接受对象并返回XmlNode。有一个单独的文档描述每个方法。我更新了问题以澄清问题。用名称空间更新了代码,重命名了类。仍然是相同的例外不确定为什么。如果我是你,我会简化它并将反序列化与消息tr分离ansfer。一旦您可以使用文件系统文件反序列化您认为需要反序列化的类型的消息,然后将该反序列化代码移回WCF代理以从XmlDocument反序列化。一种前进的方法。好的,我在您更新问题后更新了我的答案。好的,我在您更新问题后更新了我的答案。
    [XmlRoot("Response", Namespace="http://www.thirdparty.com/lr/")]
    public class ResponseExt : Response {
    }
    
    [XmlRoot("Response", Namespace="http://www.thirdparty.com/lr/")]
    [XmlInclude(typeof(ResponseExt))]
    public class Response {
        public string Code {get; set;}
        public string Message {get; set;}
        public string SessionId {get; set;}
    }
    
    public class XsiType
    {
        public static void Main(string[] args)
        {
            try
            {
                string filename = "XsiType.xml";
                XmlSerializer s1 = new XmlSerializer(typeof(Response));
                ResponseExt r = null;
                using(System.IO.StreamReader reader= System.IO.File.OpenText(filename))
                {
                    r= (ResponseExt) s1.Deserialize(reader);
                }
    
                var builder = new System.Text.StringBuilder();
                var xmlws = new System.Xml.XmlWriterSettings { OmitXmlDeclaration = true, Indent= true };
                using ( var writer = System.Xml.XmlWriter.Create(builder, xmlws))
                {
                    //s1.Serialize(writer, r, ns);
                    s1.Serialize(writer, r);
                }
                string xml = builder.ToString();
                System.Console.WriteLine(xml);
    
            }
            catch (System.Exception exc1)
            {
                Console.WriteLine("Exception: {0}", exc1.ToString());
            }
        }
    }