API - XML 没有得到正确的格式(WebAPI 控制器)

Posted

技术标签:

【中文标题】API - XML 没有得到正确的格式(WebAPI 控制器)【英文标题】:API - XML doesn't get correct format (WebAPI Controller) 【发布时间】:2021-10-31 20:55:05 【问题描述】:

我正在为我的 XML 输出而苦苦挣扎。

我有一个方法接受 PersonalID 并返回 address,以及其中的一些附加信息。

执行 API 请求并将单独的值放入字符串变量中

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;

然后我的 API 使用该方法并应返回 XmlElement“我在这个网站上读到过,我在使用 LoadXml 时不需要指定哪个元素是 Root 和 child 等等”

控制器

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;
        

如果我将它打印到文件中,我可以让它工作,但我不知道如何为 webAPI 制作正确格式的 XML,以便我的 webAPI 的接收者可以使用该格式。

但是当我在 Firefox 或 Chrome 中使用 API 时

它“看起来”很好,但是当我查看页面源并尝试使用它,或者将它添加到 Notepad++ 时,所有内容都只是在一行上,并且没有格式化或结构化。

怎么了?

我可以以某种方式强制 Content-Type 为“text/xml”吗? 我是否使用了错误的返回类型? 是否缺少其他代码?

当朋友在Postman 中使用它时,某些操作值默认设置为任何值 (*),但在某种程度上不是 100%,但当他将其放入 XML 中时,它可以工作。但是,如果XmlElement 不成功,我如何让接收者从一开始就明白它应该是 XML?

【问题讨论】:

不要使用字符串格式来构建 XML。它不安全。 不管怎样,有什么问题?在大多数情况下,XML 文档的“有线格式”并不重要。你真的需要正确格式化字符串吗?如果它被机器消耗,机器不会(可能)关心。 抱歉,目标系统非常敏感。我应该在所有行之间使用 /n 吗?当我使用 XmlLoad 时,这是否是必要的?我想知道答案,但我很愿意使用 String 我不能使用它。我应该用 --> XmlDocument doc = new XmlDocument(); 构建 XML XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null); doc.AppendChild(docNode); XmlNode productsNode = doc.CreateElement("products"); doc.AppendChild(productsNode); 使用XmlDocument API 构建 XML 文档会是更好的选择,是的。 XmlDocument Dosent 工作尝试了相同的结果。输出只有一行。我不认为它的建立......我应该使用什么输出类型?我使用 XmlElement 但那不起作用,字符串只是 wors 有什么我忘记了吗? 【参考方案1】:

我不确定您为什么要以这种方式创建 XML。通常我创建一个对象然后返回它,你可以在你的配置服务中设置它,如果你想这样做,可能值得检查你是否添加了一个 xml 格式化程序。或者您可以使用 ContentResult 将字符串作为 xml 发送,请参见 Return "application/xml" instead of "text/plain" ASP.NET Core Web API。 我也不确定我是否理解这个问题,如果这个答案没有帮助,我深表歉意。我不确定“尝试使用它”时遇到的问题是什么,所以我不知道这是否有帮助,但如果你只是想让它在记事本++中看起来不错,你可以在它出现之前对其进行格式化。这不是很有效,因为您正在使用一个已经可以使用 xml 的字符串来将 xml 转换为 xml 字符串,但它会使它看起来不错(这是我假设问题是如何格式化 xml)。如果那是您的偏好,请随意使用空格而不是制表符。注意:如果您的 xml 很大,我不建议这样做。

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();

【讨论】:

【参考方案2】:

您正在设计的系统似乎有很多改进的机会。 任何处理 XML 的代码都应该能够处理您正在生成的内容,但是在阅读了问题和 cmets 之后,我认为以下更改可能会为您提供所需的内容。

[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();  

这应该可行,因为 Produces 属性将通过响应标头中的 Content-Type 告诉 api 使用者预期的数据类型。

XElement.ToString 打印一个格式化的字符串。如果您需要对格式进行更多控制,可以查看其他选项。

【讨论】:

【参考方案3】:

问题在于它应该是一个 XmlElement 类型应该是一个 HttpResponseMessage 并且在 标记中它应该有

<?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

【讨论】:

【参考方案4】:

如果问题真的是关于缩进您构造的 XML,那么您可以使用具有适当 XmlWriterSettings 的 XmlWriter,然后在将 XmlDocument 上的 PreserveWhitespace 设置为 true 的情况下加载构造的字符串,例如

       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();
        

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

        XmlElement root = doc.DocumentElement;

【讨论】:

【参考方案5】:

你试过吗? 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

听起来您正在尝试定义 MIME 类型?我说的对吗?

【讨论】:

以上是关于API - XML 没有得到正确的格式(WebAPI 控制器)的主要内容,如果未能解决你的问题,请参考以下文章

为啥 phpunit 没有得到 phpunit.xml 中指定的正确 APP_ENV?

在颤动中没有得到正确的 api 响应

杰克逊 XML 到 JSON 没有正确格式化列表

使用时间格式化程序时我没有得到正确的时间

使用 PHP 从亚马逊 MWS API 获取订单数据

文档类型声明包含或指向的标记声明必须格式正确