我正在尝试为自定义MultipartMemoryStreamProvider
编写测试 - 一个与此MultipartFormDataMemoryStreamProvider.cs非常相似的测试
特别是,我正在尝试测试我自己的GetStream(HttpContent parent, HttpContentHeaders headers)
方法的实现。
它需要一个HttpContent和HttpContentHeaders。
为了实现这一点,我试图创建一个控制器上下文和控制器,然后从该控制器请求中传递适当的属性。
事实上,我已尝试在此(重复)问题上实施答案:Testing a Web API method that uses HttpContext.Current.Request.Files?
我尝试的所有内容都会导致标题上的Content-Disposition
为null
,如下图所示:
知道我缺少什么吗?
为了代码,这里是代码的副本。您会注意到它与另一个问题的答案中的相同。我只是无法通过null content-disposition。
var content = new ByteArrayContent(new Byte[100]);
content.Headers.Add("Content-Disposition", "form-data");
var controllerContext = new HttpControllerContext
{
Request = new HttpRequestMessage
{
Content = new MultipartContent { content }
}
};
var controller = new MockController();
controller.ControllerContext = controllerContext;
MockController很简单:
public class MockController : ApiController { }
答案 0 :(得分:2)
如果您希望Content-Disposition
标题出现在MultipartContent
中,则应该在MultipartContent
而不是ByteArrayContent
上进行设置。
但是,如果您想通过网页模拟文件上传,则需要在Content-Disposition
上设置ByteArrayContent
标题。在这种情况下,要查看Content-Disposition
的值,您需要遍历MultipartContent
的内部内容:
var multipart = await Request.Content.ReadAsMultipartAsync();
foreach (var content in result.Contents)
{
var contentDisposition = content.Headers.ContentDisposition;
}
您可以查看本教程:Sending HTML Form Data in ASP.NET Web API。它可能有点过时,但它显示了这个想法。
编辑:刚刚检查过,它似乎与您在问题中引用的答案中提到的教程相同。
答案 1 :(得分:0)
如果我错了,请纠正我。以下是我对情况的分析:
班级MultipartContent
基本上有一组子HttpContent
个对象(ByteArrayContent
继承自HttpContent
)。它会覆盖WriteNextContentHeadersAsync
方法,并从其子HttpContent
集合中写出标头。它确实有自己的Headers
属性,但它继承自HttpContent
,没有覆盖,没有什么特别之处。
所以,你要做的是,基本上没有以这种方式实现。 MultipartContent
会将标头写入输出,但不会在自己的Headers
集合中反映这些标头。
您可以覆盖此行为。简单而天真的实现可能如下:
public class MyMultipartContent : MultipartContent
{
public override void Add(HttpContent content)
{
base.Add(content);
foreach (var header in content.Headers.ToList())
{
if (!this.Headers.Contains(header.Key))
this.Headers.Add(header.Key, header.Value);
}
}
}
因此,来自孩子HttpContent
的每个标头都会添加到MultipartContent's
Header
集合中。也许这是完全错误的,会导致错误和其他问题:)
另一种选择是枚举HttpContent
中的子MultipartContent
个对象:
foreach (var httpContent in (MultipartContent) controller.Request.Content)
{
var header = httpContent.Headers.ContentDisposition; // here it is
}
另一种选择是使用扩展方法:
public static class MyExtensions
{
public static ContentDispositionHeaderValue MyGetContentDisposition(this HttpContent httpContent)
{
if (httpContent is MultipartContent)
return ((MultipartContent) httpContent).FirstOrDefault(c => c.Headers.ContentDisposition != null)?.Headers.ContentDisposition;
return httpContent.Headers.ContentDisposition;
}
}
如果httpContent
为MultipartContent
,则会从其子ContentDisposition
集合中返回第一个非空HttpContent
标题。
var hereItIs = controller.Request.Content.MyGetContentDisposition();