Разработка динамической группировки атрибутов ответа сервиса wcf на основе входного запроса c # - PullRequest
0 голосов
/ 01 декабря 2018

Ниже приведен пример формата ответа и эквивалентный сервисный контракт моего веб-сервиса выглядит следующим образом.

<Players>
 <Player>
     <Name>Sachin</Name>
     <Sport>Cricket</Sport>
     <SportType>Team Game</SportType>
 </Player>
 <Player>
     <Name>Ronaldo</Name>
     <Sport>Football</Sport>
     <SportType>Team Game</SportType>
 </Player>
 <Player>
     <Name>Alfred</Name>
     <Sport>Shooting</Sport>
     <SportType>Individual</SportType>
 </Player>
</Players>

Теперь команда пользовательского интерфейса запрашивает новую функцию, в которой они хотят, чтобы логика группировки различных полей в службе.Например, во входном запросе во вновь открытое поле «groupBy», которое они могут отправить, можно отправить имя поля «Sport», а затем они хотят, чтобы элемент Player сгруппировался по «Sport» в ответ, и то же самое возможно для «SportType».

<SportTypes>
    <SportType>
        <Type>Team Game</Type>
        <Players>
            <Player>
                <Name>Sachin</Name>
                <Sport>Cricket</Sport>
            </Player>
            <Player>
                <Name>Ronaldo</Name>
                <Sport>Football</Sport>
            </Player>
        </Players>
    </SportType>
    <SportType>
        <Type>Individual</Type>
        <Players>
            <Name>Alfred</Name>
            <Sport>Shooting</Sport>
        </Players>
    </SportType>
</SportTypes>

У меня нет проблем с группировкой полей после извлечения их из базы данных, но я не знаю, как определить контракт на обслуживание для динамического ответа на сервис, поскольку структура ответа изменится после группировки. По некоторым очень странным (возможно, глупым) причинамПользовательский интерфейс команды не хочет делать эту группировку, поэтому это должно быть сделано в сервисе.Возможно я подхожу к проблеме неправильно. Любая помощь приветствуется.

1 Ответ

0 голосов
/ 01 января 2019

Я думаю, что вы должны изменить свой datacontract, используя CollectionDataContract.Например,

 [DataContract]
public  class Player
{
    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public string Sport { get; set; }
}
[DataContract]
public class SportType
{
    [DataMember]
    public string Type { get; set; }
    [DataMember]
    public List<Player> Players { get; set; }
}
              // name is the root xml element, itemName is the name of item xml element
[CollectionDataContract(Name = "SportTypes", ItemName = "SportType")]
public class SportTypeCollection : IEnumerable<SportType>
{
    public IList<SportType> SportTypes { get;private set; }
    public IEnumerator<SportType> GetEnumerator()
    {
        return this.SportTypes.GetEnumerator();
    }
    public SportTypeCollection(params SportType[] sportTypes)
    {
        if (null == sportTypes)
        {
            this.SportTypes = new List<SportType>();
        }
        else
        {
            this.SportTypes = sportTypes;
        }
    }
    public SportTypeCollection()
    {
        this.SportTypes = new List<SportType>();
    }
    public void Add(SportType sportType)
    {
        this.SportTypes.Add(sportType);
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.SportTypes.GetEnumerator();
    }
}

Мой тест.

 static void Main(string[] args)
    {
        SportTypeCollection sportTypes = new SportTypeCollection();
        sportTypes.Add(new SportType { Type = "a", Players = new List<Player> { new Player { Name = "p", Sport = "s" } } });
        sportTypes.Add(new SportType { Type = "b", Players = new List<Player> { new Player { Name = "p", Sport = "v" } } });
        Serialize<SportTypeCollection>(sportTypes, "d:\\message.xml", null, null);
    }
    public static void Serialize<T>(T instance, string fileName, IDataContractSurrogate dataContractSurrogate, params Type[] knownTypes)
    {



        DataContractSerializer serializer = new DataContractSerializer(typeof(T), knownTypes, int.MaxValue, false, false, dataContractSurrogate);
        using (XmlWriter writer = new XmlTextWriter(fileName, Encoding.UTF8))
        {
            serializer.WriteObject(writer, instance);
        }
        Process.Start(fileName);
    }

Результат.

<SportTypes xmlns:i="http://www.w3.org/2001/XMLSchema-instance"           xmlns="http://schemas.datacontract.org/2004/07/ServiceInterface.Models">
<SportType>
<Players>
<Player><Name>p</Name><Sport>s</Sport></Player>
</Players>
<Type>a</Type>
</SportType>

<SportType>
<Players>
<Player><Name>p</Name><Sport>v</Sport></Player>
</Players>
<Type>b</Type>
</SportType>
</SportTypes>
...