gpt4 book ai didi

c# - HttpContent header 不一致的枚举

转载 作者:可可西里 更新时间:2023-11-01 09:13:33 28 4
gpt4 key购买 nike

我正在将 HttpContent 转换为以下 dto:

public class ContentDto 
{
public string ContentType {get; set;}
public string Headers {get; set; }
public object Data { get; set; }

public ContentDto(HttpContent content)
{
Headers = content.Headers.Flatten();
// rest of the setup
}
}

并且正在对它运行一些单元测试:

[Fact]
public void CanBuild()
{
var content = new StringContent("some json", Enconding.UTF8, "application/json");
var dto = new ContentDto(content);

var contentHeaders = content.Headers.Flatten();

Assert.Equal(contentHeaders, dto.Headers);
}

并且该测试失败,因为 Content-Length header 未在我的 dto 上捕获。但是,如果我这样做:

[Fact]
public void CanBuild()
{
var content = new StringContent("some json", Enconding.UTF8, "application/json");

var contentHeaders = content.Headers.Flatten();

var dto = new ContentDto(content);

Assert.Equal(contentHeaders, dto.Headers);
}

测试通过并捕获所有 header 。甚至更多我也试过这个:

 [Fact]
public void CanBuild()
{
var content = new StringContent("some json", Enconding.UTF8, "application/json");

var dto = new ContentDto(content);

var contentHeaders = content.Headers.Flatten();

var dto1 = new ContentDto(content);

Assert.Equal(contentHeaders, dto.Headers);
Assert.Equal(contentHeaders, dto1.Headers);
}

它失败了,因为 dto 没有 Content-Length header ,但是 dto1 有。我什至尝试将 header 放入一个类似工厂的方法中,如下所示:

 public static ContentDto FromContent<T>(T content) where T : HttpContent
{
// same as the constructor
}

查看关于 Content-Length header 的 StringContent 类是否有什么特别之处,但无论我是否使用构造函数(哪个使用基类 HttpContent) 或通用方法 FromContent(在本例中使用实际的 StringContent)结果是一样的。

所以我的问题是:

这是 HttpContent.Headers 的预期行为吗?
是否有一些特定于实际 HttpContent 类型的 header ?
我在这里错过了什么?

注意:这是Flatten扩展方法的代码:

 public static string Flatten(this HttpHeaders headers)
{
var data = headers.ToDictionary(h => h.Key, h => string.Join("; ", h.Value))
.Select(kvp => $"{kvp.Key}: {kvp.Value}");

return string.Join(Environment.NewLine, data)
}

最佳答案

您的示例不完整。在调用扩展方法之前访问 ContentLength 属性时,我只能重现您的问题。在您的代码中的某处(很可能是//rest of setup) 您直接或间接调用了该属性,该属性很可能遵循延迟加载模式,然后在您下次调用时将其包含在 header 中您的扩展方法,它包含在构造的字符串中。它们不匹配,因为您在访问内容长度属性之前生成了手动字符串。

HttpContentHeaders.ContentLength 的源代码中

public long? ContentLength
{
get
{
// 'Content-Length' can only hold one value. So either we get 'null' back or a boxed long value.
object storedValue = GetParsedValues(HttpKnownHeaderNames.ContentLength);

// Only try to calculate the length if the user didn't set the value explicitly using the setter.
if (!_contentLengthSet && (storedValue == null))
{
// If we don't have a value for Content-Length in the store, try to let the content calculate
// it's length. If the content object is able to calculate the length, we'll store it in the
// store.
long? calculatedLength = _calculateLengthFunc();

if (calculatedLength != null)
{
SetParsedValue(HttpKnownHeaderNames.ContentLength, (object)calculatedLength.Value);
}

return calculatedLength;
}

if (storedValue == null)
{
return null;
}
else
{
return (long)storedValue;
}
}
set
{
SetOrRemoveParsedValue(HttpKnownHeaderNames.ContentLength, value); // box long value
_contentLengthSet = true;
}
}

您可以看到,如果您没有显式设置内容长度,那么当您第一次尝试访问它时,它将(延迟加载)添加到标题中。

这证明了我关于在生成/展平字符串然后访问 ContentLength 属性后添加它的原始理论,并解释了不一致的枚举。

关于c# - HttpContent header 不一致的枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38554489/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com