Net SOAP Service - Fun with XML Namespaces

แชร์
ฝัง
  • เผยแพร่เมื่อ 12 ม.ค. 2025

ความคิดเห็น • 6

  • @marjukerazi1089
    @marjukerazi1089 ปีที่แล้ว

    how i add name space like xmlns:tem, xmlns:at,xmlns:goa?

    • @thepragmaticprogrammer
      @thepragmaticprogrammer  ปีที่แล้ว

      You can add namespaces at any level of the xml: e.g.
      public class GetWeatherForecastResponse
      {
      [XmlNamespaceDeclarations]
      public XmlSerializerNamespaces? ns = new XmlSerializerNamespaces();
      public GetWeatherForecastResponse()
      {
      ns.Add(SOAPResponseBody.DefaultNamespacePrefix, SOAPResponseBody.DefaultNamespace);
      }
      to add them at the root of the XML document this is what this code does in your SOAP controller class
      public override SOAPResponseEnvelope CreateSOAPResponseEnvelope()
      {
      var env = base.CreateSOAPResponseEnvelope();
      env.ns.Add(SOAPResponseBody.DefaultNamespacePrefix, SOAPResponseBody.DefaultNamespace);
      return env;
      }
      so for you something like this should work:
      public override SOAPResponseEnvelope CreateSOAPResponseEnvelope()
      {
      var env = base.CreateSOAPResponseEnvelope();
      env.ns.Add("tem", "your_custom_namespace");
      return env;
      }

    • @marjukerazi1089
      @marjukerazi1089 ปีที่แล้ว

      @@thepragmaticprogrammer thank you so much

  • @marjukerazi1089
    @marjukerazi1089 10 หลายเดือนก่อน

    how i hide default xsi xsd namespace?

    • @thepragmaticprogrammer
      @thepragmaticprogrammer  10 หลายเดือนก่อน

      Try this in your program.cs. Uses middleware to manipulate the response body with a regex to remove those namespaces.
      app.Use(async (context, next) =>
      {
      // Set the response stream to a Stream we can manipulate
      using (var buffer = new MemoryStream())
      {
      var stream = context.Response.Body;
      context.Response.Body = buffer;
      // Carry on with the request pipeline
      await next.Invoke(context);
      //Read the response stream into a string
      buffer.Seek(0, SeekOrigin.Begin);
      var reader = new StreamReader(buffer);
      using (var bufferReader = new StreamReader(buffer))
      {
      string body = await bufferReader.ReadToEndAsync();
      //remove the XSI and XSD namespaces
      body = Regex.Replace(body, @"xmlns:(?:xsi|xsd)=""[a-zA-Z:\/\.0-9-]*""", "");
      //create a new UTF8 encoded output stream
      var outputStream = new MemoryStream(Encoding.UTF8.GetBytes(body));
      //set content Length and copy to HttpResponse Stream
      context.Response.ContentLength = outputStream.Length;
      await outputStream.CopyToAsync(stream);
      //reset response to original stream
      context.Response.Body = stream;
      }
      }
      });
      app.MapControllers();

    • @thepragmaticprogrammer
      @thepragmaticprogrammer  10 หลายเดือนก่อน

      That gives you free reign over the payload to do what you want.
      Alternatively and maybe cleaner, you could, create your own XML Output Formatter:
      using System.Xml;
      using System.Xml.Serialization;
      namespace SOAP.Mvc.Formatters;
      public class XmlSerializerOutputFormatter : Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerOutputFormatter
      {
      protected override void Serialize(XmlSerializer xmlSerializer, XmlWriter xmlWriter, object? value)
      {
      XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
      ns.Add("", "");
      xmlSerializer.Serialize(xmlWriter, value, ns);
      }
      }
      Then wire this in in program.cs
      builder.Services.AddControllers(options =>
      {
      options.OutputFormatters.Insert(0, new SOAP.Mvc.Formatters.XmlSerializerOutputFormatter());
      })
      The addition of the blank prefix and namespace passed into the serializer is a well know 'feature' that removes the default namespaces.