C# 读取Web Api项目中的CollectionJson内容
我有一个与之类似(几乎相同)的项目,该项目采用了与返回CollectionJson内容的著名项目类似的方法。我很难设置ReadDocument(第30行)的Collection属性,因为它没有任何setter。我可以通过做以下更改来绕过这个问题C# 读取Web Api项目中的CollectionJson内容,c#,json,asp.net-web-api,asp.net-web-api2,collection-json,C#,Json,Asp.net Web Api,Asp.net Web Api2,Collection Json,我有一个与之类似(几乎相同)的项目,该项目采用了与返回CollectionJson内容的著名项目类似的方法。我很难设置ReadDocument(第30行)的Collection属性,因为它没有任何setter。我可以通过做以下更改来绕过这个问题 public CollectionJsonContent(Collection collection) { var serializerSettings = new JsonSerializerSettings {
public CollectionJsonContent(Collection collection)
{
var serializerSettings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
Formatting = Newtonsoft.Json.Formatting.Indented,
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
collection.Version = "1.0";
Headers.ContentType = new MediaTypeHeaderValue("application/vnd.collection+json");
using (var writer = new JsonTextWriter(new StreamWriter(_memoryStream)){CloseOutput = false})
{
//var readDocument = new ReadDocument(); {IReadDocument.Collection = collection};
var serializer = JsonSerializer.Create(serializerSettings);
serializer.Serialize(writer,collection);
writer.Flush();
}
_memoryStream.Position = 0;
}
尽管上面的代码可以编译并在某种程度上解决问题,但我还是会遇到另一个问题,即无法在控制器单元测试中使用JsonCollection内容。考虑下面的单元测试代码片段:
using (var request = CreateRequest())
{
var controller = new TestController(DataService) {Request = request};
var temp = await controller.ListAsync(gridSearchData, sampleSearchData);
if ((temp is NotFoundResult) && (sampleCollection.Any()))
{
Assert.Fail("Controller did not return any result but query did");
}
var json = await temp.ExecuteAsync(cancellationTokenSource);
var readDocument = json.Content.ReadAsAsync<ReadDocument>(new[] {new CollectionJsonFormatter()}, cancellationTokenSource).Result;
}
使用(var request=CreateRequest())
{
var controller=newtestcontroller(DataService){Request=Request};
var temp=await controller.ListAsync(gridSearchData,sampleSearchData);
if((temp为NotFoundResult)&&(sampleCollection.Any())
{
Assert.Fail(“控制器未返回任何结果,但查询返回了”);
}
var json=await temp.ExecuteAsync(cancellationTokenSource);
var readDocument=json.Content.ReadAsAsync(new[]{new CollectionJsonFormatter()},cancellationTokenSource);
}
由于我没有设置ReadDocument的collection属性,ReadDocument始终为空,我无法读取其内容。
在WEB API项目中,如何在客户端异步读取JsonCollection的内容
要清楚了解该方法,请查看
而据我从您的代码中所见,您没有序列化一个
ReadDocument
对象,而只是序列化它的一个属性(集合
),然后您尝试将该值反序列化为一个新的ReadDocument
对象
示例ReadDocument
应该像这样序列化
"{"Collection": [1,2,3,4,5] }"
class SerializableReadDocument
{
public Collection Collection { get; set; }
}
using (var writer = new JsonTextWriter(new StreamWriter(_memoryStream)){CloseOutput = false})
{
var readDocument = new SerializableReadDocument() { Collection = collection };
var serializer = JsonSerializer.Create(serializerSettings);
serializer.Serialize(writer, readDocument);
writer.Flush();
}
但您序列化了集合,所以
"[1,2,3,4,5]"
我建议像这样的序列化使用代理类
"{"Collection": [1,2,3,4,5] }"
class SerializableReadDocument
{
public Collection Collection { get; set; }
}
using (var writer = new JsonTextWriter(new StreamWriter(_memoryStream)){CloseOutput = false})
{
var readDocument = new SerializableReadDocument() { Collection = collection };
var serializer = JsonSerializer.Create(serializerSettings);
serializer.Serialize(writer, readDocument);
writer.Flush();
}
并像这样更新序列化代码
"{"Collection": [1,2,3,4,5] }"
class SerializableReadDocument
{
public Collection Collection { get; set; }
}
using (var writer = new JsonTextWriter(new StreamWriter(_memoryStream)){CloseOutput = false})
{
var readDocument = new SerializableReadDocument() { Collection = collection };
var serializer = JsonSerializer.Create(serializerSettings);
serializer.Serialize(writer, readDocument);
writer.Flush();
}
但是,当您尝试反序列化输出时,这无法解决问题,因为ReadDocument
没有可设置的Collection
属性,反序列化将失败,或者返回带有空集合的ReadDocument
对象
如果您愿意,您可以在单元测试中使用SerializableReadDocument
。我正在研究这一点,并将在本周末提出一个解决方案,这将是使其成为公共setter,或者使setter成为内部的,并具有接受集合的公共ctor
很抱歉给您添麻烦。好的,这已经解决了。集合属性现在可以再次设置
我刚刚推出了这个修复程序,这是一个主要的命名重构,也是对序列化的一个很好的改进,以避免写出空集合
有关更改(尤其是包名称和名称空间已更改时的命名),请参阅。正如我在问题中所述,您也提到“反序列化本身不是实际的问题,但我在使用ReadDocument进行反序列化时遇到问题。因为我无法设置集合属性(以前在旧版本的CollectionJson中有setter,但Glen Block包所有者在新版本中对其进行了修改)我的ReadDocument集合属性为空,我的问题是:如何设置ReadDocument的集合属性,以便我可以拥有json.Content.ReadAsAsAsync(new[]{new CollectionJsonFormatter()},cancellationTokenSource).ResultAs是WebApiContrib.CollectionJson
的0.6.2版,您根本不能。即使您设法使用反射设置Collection
属性,也不能使用newtonsoft json对其进行反序列化,因为它不会设置集合。可能的解决方法是:1-使用以前的版本,2-将集合内容复制到ReadDocument.Collection
,3-使用SerializableReadDocument
。使用SerializableReadDocument
,这是最简单的方法。@如果您使用类似JSON.NET的东西,它应该可以反序列化。只向集合中添加项目没有问题。如果这不起作用,人们根本无法使用该库。@GlennBlock it deserializes在javascript中很好,但在.NET中没有,正如您在中看到的那样。OP正在尝试为unit testsGreat作业和伟大的更新进行反序列化。现在我可以设置ReadDocument集合属性。但有一个问题:我为什么得到:当我运行json.content.ReadAsAsync(new[]{new CollectionJsonFormatter()},cancellationTokenSource)时,没有MediaTypeFormatter可用于从媒体类型为“application/vnd.collection+json”的内容中读取“ReadDocument”类型的对象.Result;如上述单元测试中所述?在测试控制器时,您在单元测试中将MediaTypeFormetter设置在哪里?@MHOOS我回复了您的电子邮件,询问您是否可以发送一些示例代码。单元测试的要点也可以。