【发布时间】:2014-08-22 12:51:50
【问题描述】:
TL;DR:我的 OData 请求似乎在每个 OData GET 方法(每个控制器)中只命中了我的自定义 JsonFormatter 一次,这会导致“卡住”(缓存?)自定义格式。
我正在开发一个 Web API 项目,并且已经实现并注册了我自己的 JsonMediaTypeFormatter:
config.Formatters.Clear();
config.Formatters.Add(MyJsonFormatter);
'MyJsonFormatter' 具有以下自定义实现:
`-> SerializerSettings
`-> ContractResolver
`-> CreateProperty
在我的protected override CreateProperty(MemberInfo member, MemberSerialization memberSerialization) 方法中,我根据用户权限限制某些属性被序列化。
这适用于我所有的 API 端点除了,因为我启用了 OData 的 GET 请求。每个控制器都有一个使用对象主键的 GET 方法,以及一个 OData GET 方法,其格式类似于以下内容:
[HttpGet, Route]
public PageResult<Customer> GetOData(ODataQueryOptions<Customer> options)
{
IQueryable qCustomer = options.ApplyTo(_args.Context.Customers);
return new PageResult<Customer>(qCustomer as IEnumerable<Customer>, Request.GetNextPageLink(), Request.GetInlineCount());
}
如果我在覆盖的CreateProperty 方法上设置断点,它会被每个 API 请求命中。但是,它只会在每个控制器每个 OData GET 方法中被命中一次。 因此,来自具有不同权限的不同用户的后续调用会跳过我的代码,并为我提供第一次调用中使用的格式。
如果我重新启动 API,我可以再次命中断点(一次),并为发起调用的用户获取我的格式化权限,但后续调用(无论用户如何)都不会命中我的断点。显然,为每个 OData 请求重新启动 API 并不是我可以接受的解决方案。
我已经花了将近一整天的时间来研究这个问题,并且发现了几个帖子(here、here、here、etc.),这让我相信我需要实现自己的 ODataMediaTypeFormatter。
然而,如果是这样,为什么它会碰到我的 JsonFormatter 断点?似乎它使用了我的格式化程序,以某种方式缓存了我对该控制器的格式权限,并从那时起使用它们。
(其次,创建我自己的 ODataFormatter 似乎不再是一个有效的选择,因为自从 this post - CreateEdmTypeSerializer 不存在以来,代码库显然已经发生了变化。(我正在使用 Microsoft ASP.NET Web API 2.1 OData,版本 5.1.2)。)
问题:有没有办法让 OData 与我的 JsonFormatter 很好地配合,并针对每个请求运行我的自定义 CreateProperty 代码?
如果有人至少可以解释这里发生了什么,它可能会帮助我指出我需要去的方向,但现在我的大脑正在融化。 :P
更新:我发布到 IIS,发现如果我回收应用程序池,格式似乎被刷新了。所以看起来肯定有东西被缓存了,问题是“什么”和“为什么”——PageResults 会自动被缓存吗?如何阻止正在缓存的内容被缓存?
【问题讨论】:
标签: json odata asp.net-web-api mediatypeformatter