使用web api在请求正文中获取具有复杂类型参数的请求

时间:2014-01-14 22:37:33

标签: asp.net-web-api integration-testing asp.net-web-api2

我想为以下操作进行集成测试。

如何在集成测试中传递requestDto对象?

GetAsync和SendAsync方法都没有重载参数来将自定义对象传递给服务器。

[Route("{startDate:datetime}")]
[HttpGet]
public HttpResponseMessage Get(DateTime startDate, [FromBody]LessonplannerGetRequest request)
{
    request.StartDate = startDate;
    var lessonplannerResponse = _service.GetPeriodsByWeekStartDate(request);
    return Request.CreateResponse<LessonplannerResponse>(HttpStatusCode.OK, lessonplannerResponse);
}

[Test]
public void Get_Lessons_By_Date()
{
    // Arrange
    var request = new HttpRequestMessage(HttpMethod.Get, _server.BaseAddress + "/api/lessonplanner/2014-01-14");

    var myRequestDto = new LessonplannerGetRequest();

    // Act => QUESTION: HOW do I pass the myRequestDto ???
    var response = _client.SendAsync(request, new CancellationToken()).Result;

    // Assert
    Assert.That(response.StatusCode == HttpStatusCode.OK);
}

更新

正如Darrel Miller所说:“从技术上讲,HTTP表示你可以发送一个正文,它只是说正文并不代表任何东西而且无法使用.HttpClient不会让你发送一个。”

我在这里发布我的集成测试与HttpClient做一个复杂类型的Get请求+ FromBody:

// Arrange
var request = new HttpRequestMessage(HttpMethod.Get, _server.BaseAddress + "/api/lessonplanner/2014-01-14");
var myRequestDto = new LessonplannerGetRequest{ FirstDayOfWeek = DayOfWeek.Sunday, SchoolyearId = 1, StartDate = DateTime.Today};
request.Content = new ObjectContent<LessonplannerGetRequest>(myRequestDto, new JsonMediaTypeFormatter());
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

// Act
var response = _client.SendAsync(request, new CancellationToken()).Result;

// Assert
Assert.That(response.StatusCode == HttpStatusCode.OK);

当然这不是Http方式,有些人可能会考虑通过FromUri / query string不同地发送复杂类型。

2 个答案:

答案 0 :(得分:6)

HTML规范说你不能用身体发送GET。

HTTP规范允许它。

WebAPI允许它,因为它是一个服务/ REST并实现HTTP而不是HTML,但许多客户端和浏览器不会允许它,因为它们实现了两个规范并试图严格。

关于规范(RFC1866,第46页; HTML 4.x第17.13.3节)本身,它指出:

  

如果方法是“get”并且操作是HTTP URI,则用户代理获取action的值,附加“?”然后,使用“application / x-www-form-urlencoded”内容类型附加表单数据集。

(例如,如果您使用GET进行<form>,它将解析所有表单参数并将其设置在查询字符串中?a = b)。

就纯HTTP而言,在REST服务的上下文中,没有什么能阻止这种行为,但并非所有客户端都能够处理它。当涉及到REST / WebAPI不处理来自HttpGet的正文数据时,它主要是最佳实践建议,只有URI数据(相反,POST / action?filter = all通常可以容忍元数据/动作限定符,但这是另一个讨论)

所以是的,即使仅在内部使用,也由您自担风险。由于并非所有客户端都处理它(例如HttpRequestMessage),因此您可能会遇到麻烦。

答案 1 :(得分:0)

你不应该使用HTTPClient传递GET主体。

相关问题