WebAPI - 为什么某些HttpRequests的HttpRequestMessage为null

时间:2013-10-24 05:24:08

标签: c# asp.net-web-api automapper

我有一个简单的WebAPI控制器。我添加了AutoMapper nuget包,用于在DataModel类型和相应的Dto类型之间进行映射,如下所示:

namespace WebApi.Controllers
{
  public class Contact
  {
    public int ID { get; set; }
    public string Name { get; set; }
  }

  public class ContactDto
  {
    public int ID { get; set; }
    public string Name { get; set; }
  }

  public class ValuesController : ApiController
  {
      public ValuesController()
      {
        SetupMaps();
      }

      private void SetupMaps()
      {  
         Mapper.CreateMap<ContactDto, Contact>();
         Mapper.CreateMap<Contact, ContactDto>()
            .AfterMap((c, d) =>
                {
                    //Need to do some processing here
                    if (Request == null)
                    {
                        throw new ArgumentException("Request was null!");
                    }
                }
        );
      }

      public ContactDto Get(int id)
      {
        Contact c = new Contact { ID = id, Name = "test" };
        ContactDto dto = Mapper.Map<Contact, ContactDto>(c);
        return dto;
      }
   }
 }

我希望在映射完成后运行一些逻辑,并且需要在“AfterMap”中使用HttpRequestMessage对象

当我从Fiddler点击ValuesController时,它会按预期返回Dto的JSON表示。 如果我发出一堆同时请求来模拟加载并命中端点,那么乐趣就开始了; 有些请求成功,有些请求失败,因为HttpController的“Request”属性为null! 问题是为什么Request null?

我也尝试过使用异步控制器方法,行为完全相同:

    private async Task<Contact> GetContact(int id)
    {
        Task<Contact> task = Task.Factory.StartNew<Contact>(
            () => new Contact { ID = id, Name = "test" }
            );
        return await task;
    }
    public async Task<ContactDto> Get(int id)
    {
        Contact c = await GetContact(id);
        ContactDto dto = Mapper.Map<Contact, ContactDto>(c);
        return dto;
    }

我附上了一个Fiddler调用的屏幕截图,指出当HttpRequestMessage为空时,当调用失败时,一些请求成功使用200并且Visual Studio中的调试器中断。

Fiddler calls

Debugger breaking-1

Debugger breaking-2

有关为何会发生这种情况的任何见解?

1 个答案:

答案 0 :(得分:0)

我认为你不应该使用构造函数中的Request属性。可以在上下文可用之前初始化控制器。

尝试将AfterMap委托重构为单独的方法,并在ContactDto dto = Mapper.Map<Contact, ContactDto>(c);调用后调用它。