C# ViewResult.StatusCode为空,尽管已显式设置
我已经编写了这个控制器方法和这个测试 控制器方法:C# ViewResult.StatusCode为空,尽管已显式设置,c#,asp.net,asp.net-mvc,asp.net-core,xunit,C#,Asp.net,Asp.net Mvc,Asp.net Core,Xunit,我已经编写了这个控制器方法和这个测试 控制器方法: public async Task<IActionResult> Metric(string type, string source) { // Check existence ... var model = await _context .Metrics .FirstAsync(mt => mt.Type == metricType.AsInt() && mt
public async Task<IActionResult> Metric(string type, string source)
{
// Check existence ...
var model = await _context
.Metrics
.FirstAsync(mt => mt.Type == metricType.AsInt() && mt.Source == source);
Response.StatusCode = HttpStatusCode.OK.AsInt();
return View(model);
}
公共异步任务度量(字符串类型,字符串源)
{
//检查是否存在。。。
var模型=等待上下文
.指标
.FirstAsync(mt=>mt.Type==metricType.AsInt()&&mt.Source==Source);
Response.StatusCode=HttpStatusCode.OK.AsInt();
返回视图(模型);
}
测试:
[事实]
公共异步任务metricexistestest()
{
//安排。。。
//表演
var result=await_controller.Metric(Metrics.CpuLoad.ToString(),“source-1”);
//断言
var viewResult=Assert.IsType(结果);
Assert.Equal(HttpStatusCode.OK.AsInt(),viewResult.StatusCode.Value);
var model=Assert.IsAssignableFrom(
viewResult.ViewData.Model
);
}
现在,问题出在这里Assert.Equal(HttpStatusCode.OK.AsInt(),viewResult.StatusCode.Value)代码>。viewResult.StatusCode
实际上是null
。如果我把这句话注释掉,一切都会正常的
我做错了什么?为什么它是空的?我是否正确设置了响应状态代码?那么如何验证状态代码
谢谢大家! 看起来您应该断言结果,而不是查看结果
[Fact]
public async Task MetricExistsTest()
{
// Arrange ...
// Act
var result = await _controller.Metric(Metrics.CpuLoad.ToString(), "source-1");
// Assert
var viewResult = Assert.IsType<ViewResult>(result);
Assert.Equal(HttpStatusCode.OK.AsInt(), result.StatusCode.Value);
var model = Assert.IsAssignableFrom<Metric>(
viewResult.ViewData.Model
);
}
[事实]
公共异步任务metricexistestest()
{
//安排。。。
//表演
var result=await_controller.Metric(Metrics.CpuLoad.ToString(),“source-1”);
//断言
var viewResult=Assert.IsType(结果);
Assert.Equal(HttpStatusCode.OK.AsInt(),result.StatusCode.Value);
var model=Assert.IsAssignableFrom(
viewResult.ViewData.Model
);
}
我终于做到了!
所有帮助我回答和评论的人——我非常感谢
事实证明,我有两个问题-HttpContext
在测试环境中不存在(除非手动设置)和Response。StatusCode
没有对结果ViewResult
对象设置StatusCode
。(这些是我的观察结果,如果我错了,请纠正我)
问题1解决方案:
只需设置defaultHttpContext
即可解决问题。至少,控制器方法不会崩溃,因为Response
不再是null
var controller = new HomeController();
controller.ControllerContext = new ControllerContext();
controller.ControllerContext.HttpContext = new DefaultHttpContext();
问题2解决方案:
事实证明,我需要在ViewResult
对象上显式设置StatusCode
。由于某些原因,ASP.Core不会将StatusCode
从Response
对象镜像到结果IActionObject
。(如果我错了,请纠正我)
下面是解决方案(这是我控制器上的另一种方法,但它清楚地说明了这个想法):
公共异步任务索引()
{
var模型=等待上下文
.指标
.Where(mt=>mt.Type==Metrics.CpuLoad.AsInt())
.ToListAsync();
var结果=视图(模型);
result.StatusCode=(model.Any()?HttpStatusCode.OK:HttpStatusCode.NoContent).AsInt();
返回结果;
}
removeResponse.StatusCode=HttpStatusCode.OK.AsInt()代码>从操作中选择。默认响应(在本例中为视图)应为200OK@Nkosi如果我想设置一个自定义代码,比如204无内容,该怎么办?有@Nkosi的操作结果-终于找到了!看看我的答案。谢谢你的帮助!在我的控制器方法中,Response
是null
。你知道为什么吗?如何正确地设置它?您应该能够模拟HTTPResonse,我能够设置默认响应对象。但是仍然IActionResult
没有.StatusCode
,因此我无法编写result.StatusCode.Value
。很遗憾,模拟对我不起作用,但谢谢你的回答!请注意,204
响应不应具有主体/视图:“204响应被头字段后的第一个空行终止,因为它不能包含消息正文。”@hangy Very true。当您的浏览器拒绝加载204页的内容,甚至没有将URL添加到历史记录中时,不要感到惊讶。
var controller = new HomeController();
controller.ControllerContext = new ControllerContext();
controller.ControllerContext.HttpContext = new DefaultHttpContext();
public async Task<IActionResult> Index()
{
var model = await _context
.Metrics
.Where(mt => mt.Type == Metrics.CpuLoad.AsInt())
.ToListAsync();
var result = View(model);
result.StatusCode = (model.Any() ? HttpStatusCode.OK : HttpStatusCode.NoContent).AsInt();
return result;
}