Asp.net web api 使用web api在请求正文中使用复杂类型参数获取请求

Asp.net web api 使用web api在请求正文中使用复杂类型参数获取请求,asp.net-web-api,integration-testing,asp.net-web-api2,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

我想为下面的操作做一个集成测试

如何在集成测试中通过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);
}
[路由(“{startDate:datetime}”)]
[HttpGet]
公共HttpResponseMessage获取(DateTime startDate,[FromBody]LessonplannerGetRequest请求)
{
request.StartDate=StartDate;
var lessonplannerResponse=_service.GetPeriodsByWeekStartDate(请求);
返回请求.CreateResponse(HttpStatusCode.OK,lessonplannerResponse);
}
[测试]
公共无效按日期获取课程()
{
//安排
var request=newhttprequestmessage(HttpMethod.Get,_server.BaseAddress+“/api/lessonplanner/2014-01-14”);
var myRequestDto=新LessonplannerGetRequest();
//Act=>问题:如何将myRequestDto传递给???
var response=\u client.sendaync(请求,new CancellationToken()).Result;
//断言
Assert.That(response.StatusCode==HttpStatusCode.OK);
}
更新

正如Darrel Miller所说:“从技术上讲,HTTP说你可以发送一个body,它只是说body没有任何意义,不能使用。HttpClient不会让你发送一个。”

我在这里发布了我与HttpClient的集成测试,使用复杂类型+FromBody执行Get请求:

// 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);
//排列
var request=newhttprequestmessage(HttpMethod.Get,_server.BaseAddress+“/api/lessonplanner/2014-01-14”);
var myRequestDto=newlessonplannergetrequest{FirstDayOfWeek=DayOfWeek.Sunday,SchoolyearId=1,StartDate=DateTime.Today};
Content=newobjectcontent(myRequestDto,newjsonmediatypeformatter());
request.Content.Headers.ContentType=新的MediaTypeHeaderValue(“应用程序/json”);
_client.DefaultRequestHeaders.Accept.Add(新的MediaTypeWithQualityHeaderValue(“应用程序/json”);
//表演
var response=\u client.sendaync(请求,new CancellationToken()).Result;
//断言
Assert.That(response.StatusCode==HttpStatusCode.OK);

当然,这不是HTTP方式,有些人可能会考虑通过FROMURI/查询字符串来发送复杂的类型。

不应该通过HTTPclipse传递一个get体。

< P> HTML规范说,不能用一个主体发送一个get。p> HTTP规范允许这样做

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

至于规范本身(第46页;第17.13.3节),其规定:

如果方法是“get”,操作是一个HTTP URI,那么用户代理将获取操作的值,向其追加一个“?”,然后追加表单数据集,使用“application/x-www-form-urlencoded”内容类型进行编码

(例如,如果使用GET执行a
,它将解析所有表单参数并在查询字符串?a=b中设置它们)

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


所以,是的,这是在你自己的风险,即使只使用内部。由于并非所有客户端都能处理该请求(例如HttpRequestMessage),因此您可能会遇到类似的问题。

如果您发出http请求,则应将requestDto对象序列化,并通过request.body.http语义不允许Get的body。更类似HTTP的方法是在URI和查询字符串中传递请求数据,并使用
[FromUri]
绑定到复杂类型。只是一个想法。@Badri说你可以发送一个身体,它只是说身体没有任何意义,不能使用。HttpClient不允许您发送。@Darreller不正确您所说的我刚刚在与GET+Complex Type+FromBody的集成测试中使用了HttpClient,它工作正常。@Elisa我收到错误“无法发送具有此动词类型的内容正文”。@Elisa抱歉,我误解了您的问题。你想送一具尸体和一个GET。你不能那样做。HTTP说GET消息中的主体没有任何意义。我刚刚通过请求主体+HTTPGET发送了我的复杂类型,它工作正常。当Http规范禁止时,为什么web API允许它?Http规范不禁止它,但HTML规范禁止它。因为大多数客户端和浏览器都支持HTML和HTTP规范,比如HttpClient,所以它们通常对HTML部分要求严格。WebAPI只实现HTTP规范(而MVC同时实现这两个规范,但可能不完全严格,不确定)。请参阅下面我的答案以及HTML规范的链接。