IsMimeMultipartContent 无法处理 Multipart Content-Type header 的类型参数中的附加斜杠
IsMimeMultipartContent cannot handle Additional Slash in Type parameter of Multipart Content-Type header
我有一个 Microsoft ASP.net Web API 项目(使用 .net Framework 4.61),它有 API 方法,应该接受 POST 请求,其中 Post 包含 MIME 多部分消息。
.net Framework 具有方法 HttpContentMultipartExtensions.IsMimeMultipartContent
和 HttpContentMultipartExtensions.ReadAsMultipartAsync
能够自动处理 MIME 多部分消息。
在 WebAPI 控制器中使用以下示例代码:
public class MySampleController : ApiController
{
public IHttpActionResult Post()
{
if(this.Request.Content.IsMimeMultipartContent())
{
return Json("OK");
}
else
{
throw new Exception("No Multipart");
}
}
}
这会为 Post 请求中给定的 Content-Type header 生成以下结果:
multipart/related;type=application/dicom+xml;boundary=MESSAGEBOUNDARY
-> 触发异常
multipart/related;type="application/dicom+xml";boundary=MESSAGEBOUNDARY
-> 输出正常
multipart/related;type=application-dicom+xml;boundary=MESSAGEBOUNDARY
-> 输出正常
似乎 .net 中的多部分处理无法处理出现在 Content-Type header 的 type
参数中的斜杠,除非该值嵌入在双引号,尽管据我了解 RFC,在这种情况下使用双引号是可选的。
- WebAPI 项目或 IIS 中是否有一些设置可以解决这个问题?
- 是否有通过代码解决此问题的方法?
- 或者是行为标准符合并且需要双引号?
作为参考,这是一些简单的代码,您可以使用它从另一个应用程序发送 post 请求:
private void buttonSend_Click(object sender, EventArgs e)
{
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(@"http://localhost/projectname/api/mysample");
myRequest.Method = "POST";
// Server call fails when the double quotes around the type value are removed
myRequest.ContentType = "multipart/related;type=\"application/dicom+xml\";boundary=MESSAGEBOUNDARY";
string body = @"--MESSAGEBOUNDARY
Content-Type: application/dicom+xml
<?xml version=""1.0"" encoding=""UTF-8""?>
<NativeDicomModel>
</NativeDicomModel>
--MESSAGEBOUNDARY--";
var data = Encoding.Default.GetBytes(body);
myRequest.ContentLength = data.Length;
Stream newStream = myRequest.GetRequestStream();
newStream.Write(data, 0, data.Length);
var lResponse = myRequest.GetResponse();
MessageBox.Show("OK");
}
在重读 RFC2045 第 5.1 章(Content-Type Header 字段的语法)时,我发现斜杠字符确实强制使用双引号:
tspecials := "(" / ")" / "<" / ">" / "@" /
"," / ";" / ":" / "\" / <">
"/" / "[" / "]" / "?" / "="
; Must be in quoted-string,
; to use within parameter values
所以,微软的实现是正确的。
我有一个 Microsoft ASP.net Web API 项目(使用 .net Framework 4.61),它有 API 方法,应该接受 POST 请求,其中 Post 包含 MIME 多部分消息。
.net Framework 具有方法 HttpContentMultipartExtensions.IsMimeMultipartContent
和 HttpContentMultipartExtensions.ReadAsMultipartAsync
能够自动处理 MIME 多部分消息。
在 WebAPI 控制器中使用以下示例代码:
public class MySampleController : ApiController
{
public IHttpActionResult Post()
{
if(this.Request.Content.IsMimeMultipartContent())
{
return Json("OK");
}
else
{
throw new Exception("No Multipart");
}
}
}
这会为 Post 请求中给定的 Content-Type header 生成以下结果:
multipart/related;type=application/dicom+xml;boundary=MESSAGEBOUNDARY
-> 触发异常multipart/related;type="application/dicom+xml";boundary=MESSAGEBOUNDARY
-> 输出正常multipart/related;type=application-dicom+xml;boundary=MESSAGEBOUNDARY
-> 输出正常
似乎 .net 中的多部分处理无法处理出现在 Content-Type header 的 type
参数中的斜杠,除非该值嵌入在双引号,尽管据我了解 RFC,在这种情况下使用双引号是可选的。
- WebAPI 项目或 IIS 中是否有一些设置可以解决这个问题?
- 是否有通过代码解决此问题的方法?
- 或者是行为标准符合并且需要双引号?
作为参考,这是一些简单的代码,您可以使用它从另一个应用程序发送 post 请求:
private void buttonSend_Click(object sender, EventArgs e)
{
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(@"http://localhost/projectname/api/mysample");
myRequest.Method = "POST";
// Server call fails when the double quotes around the type value are removed
myRequest.ContentType = "multipart/related;type=\"application/dicom+xml\";boundary=MESSAGEBOUNDARY";
string body = @"--MESSAGEBOUNDARY
Content-Type: application/dicom+xml
<?xml version=""1.0"" encoding=""UTF-8""?>
<NativeDicomModel>
</NativeDicomModel>
--MESSAGEBOUNDARY--";
var data = Encoding.Default.GetBytes(body);
myRequest.ContentLength = data.Length;
Stream newStream = myRequest.GetRequestStream();
newStream.Write(data, 0, data.Length);
var lResponse = myRequest.GetResponse();
MessageBox.Show("OK");
}
在重读 RFC2045 第 5.1 章(Content-Type Header 字段的语法)时,我发现斜杠字符确实强制使用双引号:
tspecials := "(" / ")" / "<" / ">" / "@" /
"," / ";" / ":" / "\" / <">
"/" / "[" / "]" / "?" / "="
; Must be in quoted-string,
; to use within parameter values
所以,微软的实现是正确的。