我正在编写一段代码,它基本上是.NET核心3.1类库中的API客户端。
我使用的是Visual 2019企业版16.5.5。
我启用了可空引用类型特性,以便在Visual中享受对nulls的编译器警告。这是我的类库项目的csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Flurl" Version="2.8.2" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="System.Text.Json" Version="4.7.2" />
</ItemGroup>
</Project>
在我的代码中,我希望确保响应内容类型实际上是application/json
,这是我的API中预期的reu转身类型:
var responseMediaType = response.Content.Headers.ContentType.MediaType;
通过检查涉及的对象和的类型注释,我可以看到我要取消引用的对象中没有一个是null
(说‘内容在这里不为空’,‘Header不在这里为空’等等)。
对.NET core github repository seems to confirm that calling the getter for property Content
of class HttpResponseMessage
never returns null
的简单检查。通过检查代码,似乎允许将null
值设置为属性,但是当调用getter时,通过??=
运算符将底层字段更改为new EmptyContent()
。
因此,根据我的理解,根据属性类型(非空引用类型)和,该属性的getter永远不会返回空。到现在为止还好。
几次前,我写了一段类似的代码,我们和一位客户一起遇到了一个微妙的错误。由于一个非常长的请求查询字符串,被调用的端点返回一个414 URI too long
响应,该响应具有,没有响应内容。在这种情况下,取消引用Content
属性以检测响应mime类型会导致NullReferenceException
。这发生在.NET核心2.2类库中。
为了避免两次犯相同的错误,我为我全新的.NET核心3.1代码添加了一个单元测试,其中我为被调用的API使用了一个模拟,并以这种方式进行了配置(以便重现与以前相同的场景):
_messageHandlerMock
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>()
)
.Returns(async () =>
{
await Task.Delay(2).ConfigureAwait(false);
return new HttpResponseMessage
{
StatusCode = HttpStatusCode.RequestUriTooLong,
Content = null
};
});
当取消引用NullReferenceException
时,测试失败,因为response.Content
的值是null
。
这对我来说是意外的,因为建议、Content
属性的非空引用类型以及上面链接的HttpResponseMessage
类的源代码。
我错过了什么?
发布于 2020-05-15 15:01:57
你看的代码是8天前才开始的。下面是您可能使用的版本:
如您所见,它返回内容时不进行空检查。
3天前有一次更新,现在可能会使用这段代码,但我不确定。我建议更新或更改代码,使其不将内容设置为null。
https://stackoverflow.com/questions/61808617
复制相似问题