我正在制作一个基于请求使用不同EDM模型的Web服务。为了实现这一目标,我的目标是从XML加载模型,但是我的测试表明我的序列化方法似乎丢失了数据(看起来真的很臭)。
我有以下API控制器方法来测试反序列化,写入xml并再次回读
public IHttpActionResult Post()
{
IEnumerable<EdmError> errors;
var model = FromXml(await Request.Content.ReadAsStringAsync(), out errors);
var parts = ToXml(model);
model = FromParts(parts);
var odataProperties = Request.ODataProperties();
odataProperties.Model = model;
return Ok(GetMetadata());
}
public IEdmModel FromXml(string xml, out IEnumerable<EdmError> errors)
{
var readers = new List<XmlReader>();
var disposables = new List<IDisposable>();
try
{
//Have no idea if this is correct but only way I was able to make it work
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
doc.GetElementsByTagName("Schema").Cast<XmlNode>().ToList().ForEach(node =>
{
var stringReader = new StringReader(node.OuterXml);
var xmlReader = XmlReader.Create(stringReader);
readers.Add(xmlReader);
disposables.Add(xmlReader);
disposables.Add(stringReader);
});
IEdmModel model;
CsdlReader.TryParse(readers.AsEnumerable(), out model, out errors);
return model;
}
finally
{
disposables.ForEach(r => r.Dispose());
}
}
//Really don't thing this is right but couldn't write the model
//But passing the model into TryWriteCsdl gives edm error Single file provided but model cannot be serialized into single file
public static List<string> ToXml(IEdmModel model)
{
IEnumerable<EdmError> errors = new List<EdmError>();
var xmlParts = new List<string>();
foreach (var schema in model.SchemaElements)
{
var xmlBuilder = new StringBuilder();
var tempModel = new EdmModel();
tempModel.AddElement(schema);
using (var xmlWriter = XmlWriter.Create(xmlBuilder, new XmlWriterSettings() { Encoding = Encoding.UTF32 }))
{
tempModel.TryWriteCsdl(xmlWriter, out errors);
}
xmlParts.Add(xmlWriter.ToString());
}
return xmlParts;
}
public IEdmModel FromParts(List<string> parts)
{
var readers = new List<XmlReader>();
var disposables = new List<IDisposable>();
EdmEntityContainer entityContainer = null;
try
{
IEdmModel model;
IEnumerable<EdmError> errors;
await
parts.ForEachAsync(f =>
{
var stringReader = new StringReader(f);
var xmlReader = XmlReader.Create(stringReader);
readers.Add(xmlReader);
disposables.Add(xmlReader);
disposables.Add(stringReader);
});
CsdlReader.TryParse(readers, out model, out errors);
return model ;
}
finally
{
disposables.ForEach(r => r.Dispose());
}
}
当我发送以下作为请求正文时
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
<edmx:Reference Uri="http://docs.oasis-open.org/odata/odata/v4.0/os/vocabularies/Org.OData.Core.V1.xml">
<edmx:Include Alias="Core" Namespace="Org.OData.Core.V1"/>
</edmx:Reference>
<edmx:DataServices>
<Schema Namespace="NorthwindModel" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityType Name="Item">
<Key>
<PropertyRef Name="ItemID"/>
</Key>
<Property Name="ItemID" Type="Edm.Int32" Nullable="false">
<Annotation Term="Core.Computed" Bool="true" />
</Property>
<Property Name="ItemName" Type="Edm.String"/>
</EntityType>
</Schema>
<Schema Namespace="ODataWebExperimental.Northwind.Model" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityContainer xmlns:p4="http://schemas.microsoft.com/ado/2009/02/edm/annotation" Name="NorthwindEntities" p4:LazyLoadingEnabled="true">
<EntitySet Name="Items" EntityType="NorthwindModel.Item" />
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
我得到了这个回复
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0"
xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
<edmx:DataServices>
<Schema Namespace="NorthwindModel"
xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityType Name="Item">
<Key>
<PropertyRef Name="ItemID" />
</Key>
<Property Name="ItemID" Type="Edm.Int32" Nullable="false" />
<Property Name="ItemName" Type="Edm.String" />
</EntityType>
</Schema>
<Schema Namespace="ODataWebExperimental.Northwind.Model"
xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityContainer Name="NorthwindEntities">
<EntitySet Name="Items" EntityType="NorthwindModel.Item" />
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
除了<Annotation Term="Core.Computed" Bool="true" />
行消失之外,这几乎是正确的。我需要确保序列化/反序列化
我序列化模型的方式对我来说似乎不对,但不确定我该怎么做