Опустить xmlns и d4p1 из DotNetXmlSerializer - PullRequest
0 голосов
/ 27 января 2020

Я отправляю веб-запрос, используя

    var request = new RestRequest(string.Format(url, config.ApiLocale), Method.POST)
        {
            RequestFormat = DataFormat.Xml,
            XmlSerializer = new RestSharp.Serializers.DotNetXmlSerializer("")
        };

Мой запрос построен так:

    List<RequestParam> listParams = new List<RequestParam>()
    {
        new RequestParam("Foo1"),
        new RequestParam("Foo2"),
        new RequestParam(12345)
    };

    request.AddBody(new XmlRequest
    {
        MethodName = "api.Testcall",
        ListParams = listParams
    });

Мои классы:

    using RestSharp.Deserializers;
    using System;
    using System.Collections.Generic;
    using System.Xml.Serialization;

    namespace Testcall
    {
        [XmlRoot("methodCall")]
        public class XmlRequest
        {
            [XmlElement(ElementName = "methodName")]
            public string MethodName { get; set; }
            [XmlArray(ElementName = "params")]
            [XmlArrayItem("param")]
            public List <RequestParam> ListParams { get; set; }

        } 

        public class RequestParam
        {
            [XmlElement(ElementName = "value")]
            public ParamFather Value { get; set; }

            public RequestParam() { }
            public RequestParam(String PassValue)
            {
                Value = new StringParam(PassValue);
            }
            public RequestParam(int PassValue)
            {
                Value = new IntParam(PassValue);
            }
            public RequestParam(Boolean PassValue)
            {
                Value = new BoolParam(PassValue);
            }
        }

        [XmlInclude(typeof(StringParam))]
        [XmlInclude(typeof(BoolParam))]
        [XmlInclude(typeof(IntParam))]
        public class ParamFather
        {
            [XmlElement(ElementName = "father")]
            public String Content { get; set; }
        }

        public class StringParam : ParamFather
        {
            [XmlElement(ElementName = "string")]
            public String StringContent { get; set; }
            public StringParam() { }
            public StringParam(String Content)
            {
                StringContent = Content;
            }
        }
    }

Но Сериализатор возвращает XML включая странные d4p1 и xmlns-теги. Те, которые я хочу опустить! Мне просто нужен простой xml без каких-либо тегов.

    <methodCall>
        <methodName>api.Testcall</methodName>
        <params>
            <param>
                <value d4p1:type=\"StringParam\" xmlns:d4p1=\"http://www.w3.org/2001/XMLSchema-instance\">
                    <string>Foo1</string>
                </value>
            </param>
            <param>
                <value d4p1:type=\"StringParam\" xmlns:d4p1=\"http://www.w3.org/2001/XMLSchema-instance\">
                    <string>Foo2</string>
                </value>
            </param>
            <param>
                <value d4p1:type=\"IntParam\" xmlns:d4p1=\"http://www.w3.org/2001/XMLSchema-instance\">
                    <int>12345</int>
                </value>
            </param>
        </params>
    </methodCall>

Я попытался использовать classi c XMLSerializer, но не получилось. Можно ли вообще сделать это с DotNetXmlSerializer?

1 Ответ

0 голосов
/ 30 января 2020

Наконец-то я решил проблему, переключившись на стандартный XmlSerializer.

    [XmlRoot("methodCall")]
    public class XmlRequest
    {
        [XmlElement(ElementName = "methodName")]
        public string MethodName { get; set; }
        [XmlArray(ElementName = "params")]
        [XmlArrayItem("param")]
        public List <RequestParam> ListParams { get; set; }

        public string ToXML()
        {
            using (var stringwriter = new System.IO.StringWriter())
            {
                using (var xmlwriter = XmlWriter.Create(stringwriter, new XmlWriterSettings { OmitXmlDeclaration = true }))
                {
                    XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("", "");
                    new XmlSerializer(this.GetType()).Serialize(xmlwriter, this, ns);
                }
                return stringwriter.ToString();
            }
        }
    }

Я называю это так:

    List<RequestParam> listParams = new List<RequestParam>()
    {
        new RequestParam("user"),
        new RequestParam("password"),
        new RequestParam(true),
        new RequestParam(123) 
    };
    request.Parameters.Clear();

    XmlRequest reqObject = new XmlRequest
    {
        MethodName = "api.Testcall",
        ListParams = listParams
    };
    string rawXml = reqObject.ToXML();
    request.AddParameter("application/xml", rawXml, ParameterType.RequestBody);

Обратите внимание, что я сейчас использую request.AddParameter запроса. AddBody, который я использовал раньше. Так что у меня больше контроля над созданием строки стандартным XmlSerializer. OmitXmlDeclaration подавляет кодировку и стандартный запуск xml -Document. Изменились и мои классы:

    public class RequestParam
    {
        [XmlElement(ElementName = "value")]
        public Alterable Value { get; set; }

        public RequestParam() { }
        public RequestParam(int number)
        {
            Value = new Alterable(number);
        }
        public RequestParam(String str)
        {
            Value = new Alterable(str);
        }
        public RequestParam(Boolean boo)
        {
            Value = new Alterable(boo);
        }
    }

    public class Alterable
    {
        [XmlElement(DataType = "string",Type = typeof(string)),
         XmlElement(DataType = "int",Type = typeof(int)),
         XmlElement(DataType = "boolean",Type = typeof(Boolean))]
         public object Changeable { get; set; }
         public Alterable() { }
         public Alterable(int number)
         {
             Changeable = number;
         }
         public Alterable(string str)
         {
             Changeable = str;
         }
         public Alterable(Boolean boo)
         {
             Changeable = boo;
         }
    }

Мой класс Alterable может принимать строки, целые и логические значения и корректно печатать их в XML. Надеюсь, что это помогает кому-то, имеющему те же проблемы.

Результат:

    <methodCall>
       <methodName>api.Testcall</methodName>
       <params>
          <param>
             <value>
                <string>user</string>
             </value>
          </param>
          <param>
             <value>
                <string>password</string>
             </value>
          </param>
          <param>
             <value>
                <boolean>true</boolean>
             </value>
          </param>
          <param>
             <value>
                <int>123</int>
             </value>
          </param>
       </params>
    </methodCall>
...