none
c# object to XML RRS feed

  • Question

  • Trying to make a simple app to convert my c# object to XML. I have an API that takes in XML and sends out XML. I want to build the objects as c# objects and then convert them to XML. Its working fine no errors but the XML conversion is not correct or at least I don't think my object is correct. I used a tool online to convert my XML to an object but I don't think it built it correctly:

    XML:

    <FlexFacadeObject xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Columns>
        <cst_key>861a06c6-f210-406c-a0c7-0002a1353d73</cst_key>
        <allAHA_Primary>1</allAHA_Primary>
    </Columns>
    </FlexFacadeObject>

    This is what I need to build in c#

    object:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Xml.Serialization;
    
    namespace Object_To_XML
    {
        [XmlRoot(ElementName = "FlexFacadeObject")]
        public class FlexFacadeObject
        {
            [XmlElement(ElementName = "Columns")]
            public Columns Columns { get; set; }
    
            [XmlAttribute(AttributeName = "i", Namespace = "http://www.w3.org/2000/xmlns/")]
            public string I { get; set; }
        }
    
        [XmlRoot(ElementName = "Columns")]
        public class Columns
        {
            [XmlElement(ElementName = "cst_key")]
            public string Cst_key { get; set; }
    
            [XmlElement(ElementName = "allAHA_Primary")]
            public string AllAHA_Primary { get; set; }
        }
    }

    To me this looks wrong but not sure how to adjust it

    Here is my code for the tool:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.Xml;
    using System.Xml.Serialization;
    
    namespace Object_To_XML
    {
        public partial class Form1 : Form
        {
            private FlexFacadeObject obj = new FlexFacadeObject();
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void btnConvertObject_Click(object sender, EventArgs e)
            {
    
                string XML = GetXMLFromObject(obj);
    
                MessageBox.Show(XML);
            }
    
            public static string GetXMLFromObject(object o)
            {
                StringWriter sw = new StringWriter();
                XmlTextWriter tw = null;
                try
                {
                    XmlSerializer serializer = new XmlSerializer(o.GetType());
                    tw = new XmlTextWriter(sw);
                    serializer.Serialize(tw, o);
                }
                catch (Exception ex)
                {
                    //Handle Exception Code
                }
                finally
                {
                    sw.Close();
                    if (tw != null)
                    {
                        tw.Close();
                    }
                }
                return sw.ToString();
            }
        }
    }

    Here is the returned string:

    <?xml version=\"1.0\" encoding=\"utf-16\"?><FlexFacadeObject xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" />

    It should match the XML at the top but its not. So I assume my object is wrong. 

    Monday, May 13, 2019 6:31 PM

All replies

  • Not sure why I'm getting an exception:

    System.NullReferenceException: 'Object reference not set to an instance of an object.'

    I adjusted the code a little:

    private void btnConvertObject_Click(object sender, EventArgs e)
            {
                obj.Columns.Cst_key = "861a06c6-f210-406c-a0c7-0002a1353d73";
                obj.Columns.AllAHA_Primary = "1";
    
                string XML = GetXMLFromObject(obj);
    
                MessageBox.Show(XML);
            }

    Monday, May 13, 2019 7:25 PM
  • I think this solves it?

    private void btnConvertObject_Click(object sender, EventArgs e)
            {
                FlexFacadeObject obj = new FlexFacadeObject();
    
                obj.Columns = new Columns();
                obj.Columns.Cst_key = "861a06c6-f210-406c-a0c7-0002a1353d73";
                obj.Columns.AllAHA_Primary = "1";
    
                string XML = GetXMLFromObject(obj);
    
                MessageBox.Show(XML);
            }

    Monday, May 13, 2019 7:31 PM
  • Couple issues Im running into now:

    output:

    <?xml version=\"1.0\" encoding=\"utf-16\"?>
    <FlexFacadeObject xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">
    <Columns>
    <cst_key>861a06c6-f210-406c-a0c7-0002a1353d73</cst_key>
    <allAHA_Primary>1</allAHA_Primary>
    </Columns>
    </FlexFacadeObject>

    1. Its outputting this line: "<?xml version=\"1.0\" encoding=\"utf-16\"?>"

    This line can not be in there, the API wants to reject it if I have this line in the code.

    2. Since its converting to a string \" does not work for the API call.

    I think it needs to be a straight XML code. Not sure how to resolve these issues. Normally when I make calls to an API its JSON format. This API requires XML format. 

    I just need to format my objects to XML and make the calls to the API with the converted object. 

     

    Monday, May 13, 2019 7:48 PM
  • Copy the sample XML to the clipboard. Then in Visual Studio in a .cs file use Edit | Paste Special | Paste XML as Classes.

    I get:

    // NOTE: Generated code may require at least .NET Framework 4.5 or .NET Core/Standard 2.0.
    /// <remarks/>
    [System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
    public partial class FlexFacadeObject
    {
    
        private FlexFacadeObjectColumns columnsField;
    
        /// <remarks/>
        public FlexFacadeObjectColumns Columns
        {
            get
            {
                return this.columnsField;
            }
            set
            {
                this.columnsField = value;
            }
        }
    }
    
    /// <remarks/>
    [System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    public partial class FlexFacadeObjectColumns
    {
    
        private string cst_keyField;
    
        private byte allAHA_PrimaryField;
    
        /// <remarks/>
        public string cst_key
        {
            get
            {
                return this.cst_keyField;
            }
            set
            {
                this.cst_keyField = value;
            }
        }
    
        /// <remarks/>
        public byte allAHA_Primary
        {
            get
            {
                return this.allAHA_PrimaryField;
            }
            set
            {
                this.allAHA_PrimaryField = value;
            }
        }
    }

    Doing that will get code that is more likely to be compatible with .Net and such.



    Sam Hobbs
    SimpleSamples.Info


    Monday, May 13, 2019 8:26 PM
  • I got it figured out going a different direction but now I need help adding basic auth to my header. I have searched google and found a example but it did not work, gave syntax error. Here is new code for my function:

    public string PostXML(object obj, string URI)
            {
                string webresponse = string.Empty;            
    
                WebRequest req = WebRequest.Create("https://myurl");
                //todo add basic auth header
                req.Method = "POST";
                req.ContentType = "text/xml";
    
                using (Stream dataStream = req.GetRequestStream())
                {
                    XmlSerializer ser = new XmlSerializer(typeof(FlexFacadeObject));
                    ser.Serialize(dataStream, obj);
                }
    
                using (WebResponse response = req.GetResponse())
                {
                    string status = ((HttpWebResponse)response).StatusDescription;
                    using (Stream responseStream = response.GetResponseStream())
                    {
                        using (StreamReader reader = new StreamReader(responseStream))
                        {
                            XmlSerializer serr = new XmlSerializer(typeof(Query));
                            Query rsp = (Query)serr.Deserialize(reader);
                            webresponse = rsp.SchemaQuery;
                        }
                    }                
                }            
    
                return webresponse;
            }

    I don't know if this will work or not but I know i will need to add basic auth tot he header for it to work or at least test it. This sample code below gives syntax error:

    req.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes($"{yourusername}:{yourpwd}")));

    Severity Code Description Project File Line Suppression State
    Error CS1061 'WebRequest' does not contain a definition for 'DefaultRequestHeaders' and no accessible extension method 'DefaultRequestHeaders' accepting a first argument of type 'WebRequest' could be found (are you missing a using directive or an assembly reference?) Object_To_XML C:\Users\mholmes\Source\repos\Object_To_XML\Object_To_XML\Form1.cs 71 Active


    • Edited by old_School Monday, May 13, 2019 9:05 PM back tracking to previous post
    Monday, May 13, 2019 8:51 PM
  • Now I get an error:

    System.Net.WebException
      HResult=0x80131509
      Message=The underlying connection was closed: An unexpected error occurred on a send.
      Source=System
      StackTrace:
       at System.Net.HttpWebRequest.GetResponse()
       at Object_To_XML.Form1.PostXML(Object obj, String URI, String username, String password) in C:\Users\mholmes\Source\repos\Object_To_XML\Object_To_XML\Form1.cs:line 83
       at Object_To_XML.Form1.btnConvertObject_Click(Object sender, EventArgs e) in C:\Users\mholmes\Source\repos\Object_To_XML\Object_To_XML\Form1.cs:line 38
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at Object_To_XML.Program.Main() in C:\Users\mholmes\Source\repos\Object_To_XML\Object_To_XML\Program.cs:line 19
    
    Inner Exception 1:
    IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
    
    Inner Exception 2:
    SocketException: An existing connection was forcibly closed by the remote host

    Code:

    public string PostXML(object obj, string URI, string username, string password)
            {
                string webresponse = string.Empty;            
    
                WebRequest req = WebRequest.Create(URI);
                req.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes(username + ":" + password));
                req.Method = "POST";
                req.ContentType = "text/xml";
    
                using (Stream dataStream = req.GetRequestStream())
                {
                    XmlSerializer ser = new XmlSerializer(typeof(FlexFacadeObject));
                    ser.Serialize(dataStream, obj);
                }
    
                using (WebResponse response = req.GetResponse())
                {
                    string status = ((HttpWebResponse)response).StatusDescription;
                    using (Stream responseStream = response.GetResponseStream())
                    {
                        using (StreamReader reader = new StreamReader(responseStream))
                        {
                            XmlSerializer serr = new XmlSerializer(typeof(Query));
                            Query rsp = (Query)serr.Deserialize(reader);
                            webresponse = rsp.SchemaQuery;
                        }
                    }                
                }            
    
                return webresponse;
            }

    Ideas?



    • Edited by old_School Monday, May 13, 2019 9:04 PM i think the answer is my object maybe? back tracking a litle
    Monday, May 13, 2019 8:57 PM
  • Copy the sample XML to the clipboard. Then in Visual Studio in a .cs file use Edit | Paste Special | Paste XML as Classes.

    I get:

    // NOTE: Generated code may require at least .NET Framework 4.5 or .NET Core/Standard 2.0.
    /// <remarks/>
    [System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
    public partial class FlexFacadeObject
    {
    
        private FlexFacadeObjectColumns columnsField;
    
        /// <remarks/>
        public FlexFacadeObjectColumns Columns
        {
            get
            {
                return this.columnsField;
            }
            set
            {
                this.columnsField = value;
            }
        }
    }
    
    /// <remarks/>
    [System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    public partial class FlexFacadeObjectColumns
    {
    
        private string cst_keyField;
    
        private byte allAHA_PrimaryField;
    
        /// <remarks/>
        public string cst_key
        {
            get
            {
                return this.cst_keyField;
            }
            set
            {
                this.cst_keyField = value;
            }
        }
    
        /// <remarks/>
        public byte allAHA_Primary
        {
            get
            {
                return this.allAHA_PrimaryField;
            }
            set
            {
                this.allAHA_PrimaryField = value;
            }
        }
    }

    Doing that will get code that is more likely to be compatible with .Net and such.



    Sam Hobbs
    SimpleSamples.Info


    Are you suggesting the issue is my class?
    Monday, May 13, 2019 9:03 PM
  • Are you suggesting the issue is my class?

    I do not know. I am suggesting you use the classes generated from Visual Studio. That might solve the problem(s) or it might make the diagnosis and/or solution easier.

    You said you generated the classes online. It helps to know we can do it using VS.



    Sam Hobbs
    SimpleSamples.Info

    Monday, May 13, 2019 9:29 PM