我需要隐藏ASP.NET和IIS生成的某些标头,并在ASP.NET WebAPI服务的响应中返回.我需要隐藏的标题是:
该服务早先在WCF中托管,并且通过订阅PreSendRequestHeaders和操作HttpContext.Current.Response.Headers在HttpModule中完成隐藏.使用ASP.NET WebAPI,现在所有内容都是基于任务的,因此HttpContext.Current为null.我试图插入一个消息处理程序并操纵返回的HttpResponseMessage,但标题不存在于该阶段.可以在IIS设置中删除X-Powered-By,但是删除其余部分的建议方法是什么?
我们面临着将基于自定义代码的REST服务转换为Web API的任务.该服务具有大量请求并对可能需要一些时间加载的数据进行操作,但一旦加载,它就可以被缓存并用于服务所有传入请求.该服务的先前版本将有一个线程负责加载数据并将其加入缓存.为了防止IIS耗尽工作线程,客户端将获得"稍后回来"响应,直到缓存准备就绪.
我对Web API的理解是它具有通过操作任务而内置的异步行为,因此请求的数量不会与所持有的物理线程数直接相关.
在服务的新实现中,我计划让请求等到缓存准备就绪,然后进行有效的回复.我已经对代码做了一个非常粗略的草图来说明:
public class ContactsController : ApiController
{
private readonly IContactRepository _contactRepository;
public ContactsController(IContactRepository contactRepository)
{
if (contactRepository == null)
throw new ArgumentNullException("contactRepository");
_contactRepository = contactRepository;
}
public IEnumerable<Contact> Get()
{
return _contactRepository.Get();
}
}
public class ContactRepository : IContactRepository
{
private readonly Lazy<IEnumerable<Contact>> _contactsLazy;
public ContactRepository()
{
_contactsLazy = new Lazy<IEnumerable<Contact>>(LoadFromDatabase,
LazyThreadSafetyMode.ExecutionAndPublication);
}
public IEnumerable<Contact> Get()
{
return _contactsLazy.Value;
}
private IEnumerable<Contact> LoadFromDatabase()
{
// This method could be take a long time to execute.
throw …Run Code Online (Sandbox Code Playgroud) 我从nuget.org上的ASP.NET Web API版本(周五RC之前的版本)升级到myget.org上的每晚版本.正如预期的那样,有许多重大变化,其中一个我似乎无法解决:我们有一个场景,我们希望我们的操作返回一个对象并将状态代码设置为201 Created.这之前很容易完成(可能无法编译 - 概念代码来自我的头脑):
Session session = GetSessionInfo(requestMessage);
var response = new HttpResonseMessage(HttpStatusCode.Created);
response.Content = response.CreateContent(session);
return response;
Run Code Online (Sandbox Code Playgroud)
CreateContent实际上是一个位于System.Net.Http.HttpResponseMessageExtensions中的扩展方法,在ObjectContent中调用内部构造函数.随着新版本的发布,HttpResponseMessageExtensions似乎在新版本中消失了,ObjectContent的内部构造函数也是如此.现在看来我必须调用一个ObjectContent构造函数,以下似乎最适合我们的需求:
public class ObjectContent<T> : ObjectContent
{
public ObjectContent(T value, MediaTypeFormatter formatter)
{
}
}
Run Code Online (Sandbox Code Playgroud)
但是,似乎我必须将MediaTypeFormatter传递给它,将内容协商混合到动作的逻辑中.在我们的设置中,内容协商是通用的,并且与控制器完全分离.
有没有人建议解决方案返回一个对象,设置响应状态代码,但不必处理MediaTypeFormatter,媒体类型或任何其他内容协商相关的东西?