1

I'm struggling with my XML output.

I have a method that takes in a PersonalID and shall return address, as well as some additional information from it.

Execute a API request and put separate values in string variables

public string ReturnRegistered(String personalID)
{
                string apiurl = apiadress + personalID;
                WebRequest request = WebRequest.Create(apiurl);

                //TILLÄGG FÖR AUTHENTICATION
                request.PreAuthenticate = true;
                request.Credentials = new NetworkCredential(user, pass);
                //TILLÄGG FÖR AUTHENTICATION

                WebResponse respons = request.GetResponse();
                Stream dataStream = respons.GetResponseStream();

                //OBJEKT
                XmlSerializer serializer = new XmlSerializer(typeof(List<PrimaryContact>), new XmlRootAttribute("QueueSlot"));
                var input = (List<PrimaryContact>)serializer.Deserialize(dataStream);

             
                string firstname = input[0].firstname;
                string lastname = input[0].lastname;
                string postalAddress = input[0].postalAddress;
                string zipCode = input[0].zipCode;
                string address = input[0].address;   

     //FÖR ATT KUNNA TA FRAM ENDAST ETT ATTRIBUT BEHÖVER MAN GÖRA OM HELA WEBREQUESTEN OCH NERÅT
                WebRequest request2 = WebRequest.Create(apiurl);

                //TILLÄGG FÖR AUTHENTICATION
                request2.PreAuthenticate = true;
                request2.Credentials = new NetworkCredential(user, pass);
                //TILLÄGG FÖR AUTHENTICATION

                WebResponse respons2 = request2.GetResponse();
                Stream dataStream2 = respons2.GetResponseStream();

                //ENVÄRDE
                XmlDocument doc = new XmlDocument();
                doc.Load(dataStream2);
                XmlNodeList elemList2 = doc.GetElementsByTagName("lastPaymentDate");
                string lastPaymentDate = elemList2[0].InnerText;            


String returnvalue = "<Fields><Field><Name>lastPaymentDate</Name><Value>" + lastPaymentDate + "</Value></Field><Field><Name>Firstname</Name><Value>"+ firstname + "</Value></Field><Field><Name>Lastname</Name><Value>"+ lastname + "</Value></Field><Field><Name>Adress</Name><Value>"+ address + "</Value></Field><Field><Name>ZipCode</Name><Value>"+ zipCode + "</Value></Field><Field><Name>PostalAdress</Name><Value>"+ postalAddress + "</Value></Field></Fields>";
*//I have tryed start with <?xml version="1.0" encoding="UTF-8"?> but no different.*

return returnvalue;
}

Then my API uses that method and shall return a XmlElement. "I have read on this site that I don't need to specify which element is Root and child and so on when using LoadXml"

Controller:

public XmlElement Get(string id)
        {
            Models.TomtkoRegistered tomtko = new Models.TomtkoRegistered();
            String returnvalue = tomtko.ReturnRegistered(id);     
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(returnvalue);
                XmlElement root = doc.DocumentElement;
            return root;
        }

If I print it to file I get it to work, but I don't know how to make the XML in the correct format for a webAPI so the format is usable by the receiver of my webAPI.

But when I use the API in Firefox or Chrome enter image description here

It "looks" fine but when I look at the page source and try to use it, or add it to Notepad++ then everything is just on one line and not formatted or structured.

enter image description here What is wrong??

Can I force the Content-Type to be "text/xml" in some way? Did I use the wrong return type? Is it missing some other code?

When a friend used it in Postman some action value was default set to anyvalue (*) in some way not 100% what it was but when he put it in XML it works. But how to I make the receiver understand from the beginning that it shall be XML if XmlElement doesn't do the trick?

Tu deschizi eu inchid
  • 4,117
  • 3
  • 13
  • 24
Jonas
  • 185
  • 4
  • 16
  • Don't use string formatting to build XML. It's not secure. – AKX Sep 02 '21 at 11:25
  • 1
    Either way, what's the problem? The "wire format" of an XML document doesn't matter in the majority of cases. Do you really need the string to be properly formatted? If it's being consumed by a machine, the machine won't (likely) care. – AKX Sep 02 '21 at 11:28
  • Sorry but the target system is very sensetive. should i use /n between al the lines. Should this even be neessesary when i use XmlLoad? I want to know the answer but it i souldent use String i cant use this. Should i build the XMl with --> XmlDocument doc = new XmlDocument(); XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null); doc.AppendChild(docNode); XmlNode productsNode = doc.CreateElement("products"); doc.AppendChild(productsNode); – Jonas Sep 02 '21 at 11:39
  • Using the `XmlDocument` API to build the XML document would be the better option, yes. – AKX Sep 02 '21 at 11:46
  • XmlDocument Dosent work tryed that one same result. The output is just one line. I dont think its the build up... what output type shall i use? i use XmlElement but that dont work, string is just wors Is there any thing i have forgot? – Jonas Sep 02 '21 at 11:58
  • Use the XmlWriter's indenting mode to write the document to e.g. a MemoryStream, then grab the formatted string from there. – AKX Sep 02 '21 at 12:07
  • @AKX Can you give an example for this data – Jonas Sep 02 '21 at 12:10
  • XElement does seem to work. So try same thing that you did with XmlElement. – jdweng Sep 02 '21 at 14:43
  • @jdweng So if you take page sourse it dosent make it one line? Pleace give example how to use XElement i this code – Jonas Sep 03 '21 at 07:13
  • XElement doc = XElement.Parse (returnvalue); doc.Save(FILENAME); – jdweng Sep 03 '21 at 09:49
  • @jdweng To save it is not a problem then i get the right format. But it seams that it think its a json. How can i set Xmldomcument to contenttype text/xml. I think its automatic do it but looks that it dont. And the problem is not to save the file i can do that and i goes great its to give a webresponse to the one tha tuse the API in XML – Jonas Sep 07 '21 at 14:24
  • Shall i return a resonce in another type? – Jonas Sep 07 '21 at 14:29
  • Looks like you are using a Controller. You send a request and then get back a response. There are many flavors or Controllers. You are sending a request from a client to a server, The server processes the request and send back a response. Some server only send back one type of response (text/xml/json). Other allow the request to specify the type of response as a parameter. I can't tell from the posted code exactly how the response type is being determined. – jdweng Sep 07 '21 at 16:02
  • Yes its a controller. I will add more code to the questian soon. But i dont understand how the start shall affect the end result becouse i create a new XML with taggs. But one person tryed in Postman and when the action was on all, it looks like he gets a json. but when he force the action to be a XML he gets the result back good. How can i set that in the code with the return and the datatype . the XMLDocument should make it a text/xml in it self? There is no way to set the content type in XmlDocument or XmlElement thats the datatype that i return. – Jonas Sep 08 '21 at 06:00
  • there are plugins for notepad++ which let you view a xml: https://stackoverflow.com/questions/3961217/how-do-i-format-xml-in-notepad – Tanque Sep 09 '21 at 10:17
  • Sorry but its the returen / result thats not right. The reciver system dont understand – Jonas Sep 10 '21 at 16:09
  • Confirm if any of this is correct. So what I am hearing is the API you are sending this information to, you want to be sure that it accepts XML? Currently you are unsure or having trouble getting the API to accept your XML? Your friend who used POSTMAN, he used the same XML formatted the same exact way and the API accepted it just fine? – Adam Schneider Sep 14 '21 at 19:55

5 Answers5

1

Im not sure why you are creating your XML that way. Typically i create an object and then just return it, you can set that in your configure services it might be worth checking you have an xml formatter added if you want to do that. Or you could use a ContentResult to just send the string as xml see Return "application/xml" instead of "text/plain" ASP.NET Core Web API. Im also not sure I understand the question so apologies if this answer does not help. Im not sure what the problem you are getting when you 'try to use it' is so i dont know if this will help but if you just want it to look good in notepad++ you could just format it before it comes out. This isnt very efficent because you are taking a string that is already usable xml to turn xml and then back into xml String but it would make it look good(this is me assuming the question is how do you format xml). Feel free to use spaces instead of tab if thats your preference. Note: I would not recommend doing this if your xml is gigantic.

XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);//put your xml string here
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.IndentChars = "\t";//set your inten
using (var stringWriter = new StringWriter())
using (var xmlTextWriter = XmlWriter.Create(stringWriter, settings))
{
    doc.WriteTo(xmlTextWriter);
    xmlTextWriter.Flush();
    returnvalue = stringWriter.GetStringBuilder().ToString();
}
Donald
  • 389
  • 3
  • 10
0

It seems that the system you are designing has many opportunities for improvement. Any code that processes XML ought to be able to handle what you are producing but after reading the question and the comments I think that the following changes may get you what you need.

[Produces("application/xml")]
public XmlElement Get(string id)
{
   Models.TomtkoRegistered tomtko = new Models.TomtkoRegistered();
   String returnvalue = tomtko.ReturnRegistered(id);
   var returnXml = XElement.Parse(returnValue);
   return returnXml.ToString();  
}

This should work because the Produces attribute will tell the api consumer what type of data to expect through the Content-Type in the response header.

The XElement.ToString prints a formatted string. If you need more control over the formatting you can look into other options.

Naylor
  • 752
  • 7
  • 20
0

The problem was that it souldent be a XmlElement the type should be a HttpResponseMessage insted and in the <> tags it sould have

<?xml version=\"1.0\" encoding=\"UTF-8\"?>

public HttpResponseMessage Authenticate()
{
  //process the request 
  .........

  string XML="<note><body>Message content</body></note>";
  return new HttpResponseMessage() 
  { 
    Content = new StringContent(XML, Encoding.UTF8, "application/xml") 
  };
}

WebAPI to Return XML

Jonas
  • 185
  • 4
  • 16
-1

If the problem is really about indenting that XML you construct then you could use an XmlWriter with the proper XmlWriterSettings and later on load the constructed string with PreserveWhitespace on the XmlDocument set to true e.g.

       string returnValue;

        using (StringWriter sw = new StringWriter())
        {
            using (XmlWriter xw = XmlWriter.Create(sw, new XmlWriterSettings() { Indent = true }))
            {
                xw.WriteStartElement("Fields");

                xw.WriteStartElement("Field");
                xw.WriteElementString("Name", "lastPaymentDate");
                xw.WriteElementString("Value", lastPaymentDate);
                xw.WriteEndElement();

                xw.WriteStartElement("Field");
                xw.WriteElementString("Name", "FirstName");
                xw.WriteElementString("Value", firstName);
                xw.WriteEndElement();

                xw.WriteStartElement("Field");
                xw.WriteElementString("Name", "LastName");
                xw.WriteElementString("Value", lastName);
                xw.WriteEndElement();

                xw.WriteStartElement("Field");
                xw.WriteElementString("Name", "Adress");
                xw.WriteElementString("Value", address);
                xw.WriteEndElement();

                xw.WriteStartElement("Field");
                xw.WriteElementString("Name", "ZipCode");
                xw.WriteElementString("Value", zipCode);
                xw.WriteEndElement();

                xw.WriteStartElement("Field");
                xw.WriteElementString("Name", "Adress");
                xw.WriteElementString("Value", postalAddress);
                xw.WriteEndElement();

                xw.WriteEndElement();
            }

            returnValue = sw.ToString();
        }

plus

        XmlDocument doc = new XmlDocument();
        doc.PreserveWhitespace = true;
        doc.LoadXml(returnValue);

        XmlElement root = doc.DocumentElement;
Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
-1

Have you tried this? https://community.postman.com/t/sending-a-request-with-xml-data/8053

const options = {
 'method': 'POST',
 'url': 'httpbin.org/post',
 'header': {
   'Content-Type': 'application/xml'
 },
 body: xmlBody

It sounds like you are trying to define the MIME type? am I correct?

Adam Schneider
  • 163
  • 1
  • 12