下面是我的Web服务的响应和等效服务合同的示例格式。
<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>
现在,UI团队正在寻求新功能,他们希望在这些功能中对服务中不同字段进行分组逻辑。例如,在新暴露的“ groupBy”字段中的输入请求中,他们可以发送可以发送字段名称“ Sport”,然后他们希望以“ Sport”分组的Player元素作为响应,并且“ 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>
从数据库中检索字段后,对字段进行分组没有问题,但是我不知道如何为动态服务响应定义服务协定,因为响应结构会在分组后发生变化。出于某些非常奇怪(也许很愚蠢)的原因UI团队不想进行此分组,因此必须在服务中完成。 也许我以错误的方式解决了这个问题。感谢您的帮助。
答案 0 :(得分:0)
我认为您应该使用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>
答案 1 :(得分:0)
我找到了方法。 基本上,我创建了一个通用的嵌套实体,该实体根据Player实体动态地对玩家实体进行分组。
<Group>
<Type>SportType</Type>
<Value>TeamGame</Value>
<GroupSummary/> <!-- Aggregation summary of group -->
<Group>
<Type>Sport</Type>
<Value>Cricket</Value>
<ListOfEntities>
<Player1/>
<Player2/>
</ListOfEntities>
<Group/>
<Group/>
<ListOfEntites/>
<Group/>
然后,我们可以使用this答案中存在的GroupBy编写简单递归调用来创建嵌套的分组实体