Я десериализовал XML-файл в класс, который делает мой объект запроса мыла. Когда я сериализую класс C #, большинство объектов классов не заполняют выходной XML-файл.

Примере

GetUserReq.Envelope getUser = new GetUserReq.Envelope();
getUserResponse = new GetUserRes.Envelope();
getUser.Body = new GetUserReq.Body();
getUser.Body.GetUser = new GetUserReq.GetUser();
getUser.Body.GetUser.ReturnedTags = new GetUserReq.ReturnedTags();

if (allReturnTags)
{
    getUser.Body.GetUser.ReturnedTags.AssociatedGroups = new GetUserReq.AssociatedGroups();
    getUser.Body.GetUser.ReturnedTags.AssociatedDevices = new GetUserReq.AssociatedDevices();
    getUser.Body.GetUser.ReturnedTags.AssociatedGroups.UserGroup = new GetUserReq.UserGroup() { Name = "", UserRoles = new GetUserReq.UserRoles() };
    getUser.Body.GetUser.ReturnedTags.AssociatedGroups.UserGroup.UserRoles = new GetUserReq.UserRoles() { UserRole = "" };
}

Для каждого элемента, вложенного в «конверт», мне нужно создать новый объект, иначе выходной xml-файл будет пуст по этому тегу.

Есть ли способ сделать итерацию и сделать то, что мне нужно?

Это фрагмент кода, с которого начинается конверт

public class GetUserReq {
[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
        public class Envelope
        {
            [XmlElement(ElementName = "Header", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
            public string Header { get; set; }
            [XmlElement(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
            public Body Body { get; set; }
            [XmlAttribute(AttributeName = "soapenv", Namespace = "http://www.w3.org/2000/xmlns/")]
            public string Soapenv { get; set; }
            [XmlAttribute(AttributeName = "ns", Namespace = "http://www.w3.org/2000/xmlns/")]
            public string Ns { get; set; }
        }

И продолжить с телом, которое содержит другие классы

[XmlRoot(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
    public class Body
    {
        [XmlElement(ElementName = "getUser", Namespace = "http://www.cisco.com/AXL/API/9.1")]
        public GetUser GetUser { get; set; }
    }
1
Orion77 10 Фев 2020 в 21:31

2 ответа

Вы только определяли классы и не имели свойств для классов. Смотрите код ниже:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            GetUserReq userReq = new GetUserReq();
            userReq.Envelope = new Envelope();
            GetUserResponse userResponse = new GetUserResponse();
            userResponse.Envelope = new Envelope();
            userReq.Body = new Body();
            userReq.Body.GetUser = new GetUser();
            userReq.Body.GetUser.ReturnedTags = new ReturnedTags();

            Boolean allReturnTags = true;
            if (allReturnTags)
            {
                userReq.Body.GetUser.ReturnedTags.AssociatedGroups = new AssociatedGroups();
                userReq.Body.GetUser.ReturnedTags.AssociatedDevices = new AssociatedDevices();
                userReq.Body.GetUser.ReturnedTags.AssociatedGroups.UserGroup = new UserGroup() { Name = "", UserRoles = new UserRoles() };
                userReq.Body.GetUser.ReturnedTags.AssociatedGroups.UserGroup.UserRoles = new UserRoles() { UserRole = "" };
            }

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            XmlWriter writer = XmlWriter.Create(FILENAME, settings);

            XmlSerializer serializer = new XmlSerializer(typeof(GetUserReq));
            serializer.Serialize(writer, userReq);
        }
    }
    [XmlRoot(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
    public class Body
    {
        [XmlElement(ElementName = "getUser", Namespace = "http://www.cisco.com/AXL/API/9.1")]
        public GetUser GetUser { get; set; }
    }
    public class GetUser
    {
        public ReturnedTags ReturnedTags { get; set; }
    }
    public class ReturnedTags
    {
        public AssociatedGroups AssociatedGroups { get; set; }
        public AssociatedDevices AssociatedDevices { get; set; }
    }
    public class GetUserReq
    {
        public Envelope Envelope { get; set; }
        public Body Body { get; set; }

    }
    public class GetUserResponse
    {
        public Envelope Envelope { get; set; }

    }
    [XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
    public class Envelope
    {
        [XmlElement(ElementName = "Header", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
        public string Header { get; set; }
        [XmlElement(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
        public Body Body { get; set; }
        [XmlAttribute(AttributeName = "soapenv", Namespace = "http://www.w3.org/2000/xmlns/")]
        public string Soapenv { get; set; }
        [XmlAttribute(AttributeName = "ns", Namespace = "http://www.w3.org/2000/xmlns/")]
        public string Ns { get; set; }
    }
    public class AssociatedGroups
    {
        public UserGroup UserGroup { get; set; }
    }
    public class AssociatedDevices
    {
    }
    public class UserGroup
    {
        public UserRoles UserRoles { get; set; }
        public string Name { get; set; }
    }
    public class UserRoles
    {
        public string UserRole { get; set; }
    }
}
0
jdweng 11 Фев 2020 в 02:05

Я сделал этот код, сделанный из вашего примера и модифицированный для моих нужд

    public T AllReturnTags<T>() => (T)AllReturnTags(typeof(T));

    public object AllReturnTags(Type type)
    {
        var newObj = Activator.CreateInstance(type); // create new instance of your target class

        Func<PropertyInfo, bool> query = q
             => q.PropertyType.IsClass &&         
                q.CanWrite;                  

        foreach (var el in type.GetProperties().Where(query))
        {
            // create new instance of el cascade
            if (el.PropertyType == typeof(string))
            {
                el.SetValue(newObj, "", null);
            }
            if (el.PropertyType == typeof(Int32))
            {
                el.SetValue(newObj, 0, null);
            }
            if (el.PropertyType.IsClass && el.PropertyType != typeof(string) && el.PropertyType != typeof(Int32) && el.PropertyType.IsGenericType == true && el.PropertyType.GetGenericTypeDefinition() == typeof(List<>))
            {
                var elInstance = AllReturnTags(el.PropertyType);
                Type itemType = typeof(List<>).MakeGenericType(elInstance.GetType());
                IList res = (IList)Activator.CreateInstance(itemType);
                res.Add(elInstance);
                try { el.SetValue(newObj, res, null); } catch {  };
            }
            if (el.PropertyType.IsClass && el.PropertyType != typeof(string) && el.PropertyType != typeof(Int32) && el.PropertyType.IsGenericType != true )
            {
                var elInstance = AllReturnTags(el.PropertyType);
                try { el.SetValue(newObj, elInstance, null); } catch { return elInstance; };
            }

        }
        return newObj;
    }

Это похоже на работу с отдельными элементами и списками. Спасибо тебе @AliReza

0
Orion77 18 Фев 2020 в 06:51