我使用自定义格式化程序将结果直接嵌入<script>
标记中。格式化程序只是添加一个变量并序列化该实体。这是我的自定义格式化程序的简化实现:
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, System.Net.Http.HttpContent content, System.Net.TransportContext transportContext)
{
return Task.Factory.StartNew(() =>
{
using (StreamWriter sw = new StreamWriter(writeStream))
{
var jsonOutput = JsonConvert.SerializeObject(value, Newtonsoft.Json.Formatting.Indented, new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
sw.Write("var values=" + jsonOutput + ";");
}
});
}
如果我使用$filter
,$select
或$expand
请求资源,这样可以正常工作,但如果我只查询资源本身(例如http://localhost:53662/Categories?$format=jsone
)则不行。然而,格式化程序序列化整个数据库。
以下是http://localhost:53662/Categories?$format=jsone
的错误结果(正如您所看到的,它还会返回产品和标签,但不包含在Odata请求中):
这是一个正确的例子,如果我添加一个Odata查询(这里是http://localhost:53662/Categories?$format=jsone&$select=Name
):
这是没有自定义格式化程序(http://localhost:53662/Categories
)的正确结果:
Web API Controller非常简单:
[EnableQuery]
public IQueryable<Categories> Get(ODataQueryOptions<Categories> qOptions)
{
IQueryable<Categories> result = db.Categories;
return result;
}
[EnableQuery]
public SingleResult<Categories> Get([FromODataUri] int key, ODataQueryOptions<Categories> qOptions)
{
IQueryable<Categories> result = db.Categories.Where(x => x.Id == key);
return SingleResult.Create(result);
}
为什么自定义格式化程序返回完整数据库而不仅仅是请求的资源?
答案 0 :(得分:0)
Well, I'm using Web API with ASP.MVC 4. You're using Web API 2, but it's kind of the same problem
In case you don't need that reference depth at all:
add to your reference list, contained in codefirst model, new attribute [JsonIgnore]
Example:
public class Subgroup
{
public int SubgroupId { get; set; }
public string SubgroupName { get; set; }
//relations
public int GroupId { get; set; }
public Group Group { get; set; }
}
public class Group
{
public int GroupId { get; set; }
public string GroupName { get; set; }
//relations
[JsonIgnore]
public virtual List<Subgroup> Subgroups { get; set; }
}
or you can just make it private (non-virtual).
In case you want to set up return result, try to work with DataContract attribute.
But we want to have a choice. Make it configurable (with own formatters).
And documentation doesn't give proper answer.
JsonFormatter.SerializerSettings.MaxDepth
and JsonFormatter.MaxDepth
do nothing. But no harm in trying:
var jsonOutput = JsonConvert.SerializeObject(value, Newtonsoft.Json.Formatting.Indented, new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
MaxDepth = 1
});
What else can I suggest: you can write your own formatter using JavaScriptSerializer