我正在将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);
}
该测试失败,因为我的dto没有捕获Content-Length
标题。但是,如果我这样做:
[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);
}
测试通过并捕获所有标头。我还尝试了更多:
[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
标题,但是dto1
。我甚至尝试在类似工厂的方法中获取标题,如下所示:
public static ContentDto FromContent<T>(T content) where T : HttpContent
{
// same as the constructor
}
查看关于StringContent
标题的Content-Length
类是否有特殊内容,但无论是否使用构造函数(使用基类{{1})都没有区别})或泛型方法HttpContent
(在这种情况下使用实际的StringContent)结果是相同的。
所以我的问题是:
这是FromContent
的预期行为吗?
是否有一些特定于实际HttpContent.Headers
类型的标题?
我在这里错过了什么?
注意:这是HttpContent
扩展方法的代码:
Flatten
答案 0 :(得分:4)
你的例子不完整。在调用扩展方法之前访问public static void main(String[] args) {
// TODO Auto-generated method stub
boolean status = true;
int numberToStore = status?1:0;
System.out.println(numberToStore);
}
属性时,我只能重新创建您的问题。你的代码中的某个地方(很可能是//其余的设置)你直接或间接地调用那个很可能遵循延迟加载模式的属性,然后当你调用它时它会包含在标题中你的扩展方法,它包含在构造的字符串中。它们不匹配,因为您在访问内容长度属性之前生成了手动字符串。
在HttpContentHeaders.ContentLength
的源代码中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;
}
}
属性并解释不一致的枚举后添加它。
答案 1 :(得分:0)
似乎HttpContent类对headers属性有一个非常奇怪的行为。不知何故,内容长度似乎按照here所述进行计算。它没有具体解决您的问题,但您可以使用与初始类似的新httpContent对象进行测试。我很确定你能够毫无问题地获得内容长度。