raf*_*ale 44 c# forms wcf http-post
我正在通过HTML表单将文件发布到WCF REST服务,enctype
设置为multipart/form-data
和单个组件:<input type="file" name="data">
.由服务器读取的结果流包含以下内容:
------WebKitFormBoundary
Content-Disposition: form-data; name="data"; filename="DSCF0001.JPG"
Content-Type: image/jpeg
<file bytes>
------WebKitFormBoundary--
Run Code Online (Sandbox Code Playgroud)
问题是我不确定如何从流中提取文件字节.我需要这样做才能将文件写入磁盘.
Oha*_*der 43
很抱歉很晚才加入派对,但有一种方法可以使用Microsoft公共API.
这就是你需要的:
System.Net.Http.dll
System.Net.Http.Formatting.dll
注意 Nuget包附带了更多的程序集,但在撰写本文时,您只需要上面的内容.
一旦引用了程序集,代码就会如下所示(为方便起见使用.NET 4.5):
public static async Task ParseFiles(
Stream data, string contentType, Action<string, Stream> fileProcessor)
{
var streamContent = new StreamContent(data);
streamContent.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType);
var provider = await streamContent.ReadAsMultipartAsync();
foreach (var httpContent in provider.Contents)
{
var fileName = httpContent.Headers.ContentDisposition.FileName;
if (string.IsNullOrWhiteSpace(fileName))
{
continue;
}
using (Stream fileContents = await httpContent.ReadAsStreamAsync())
{
fileProcessor(fileName, fileContents);
}
}
}
Run Code Online (Sandbox Code Playgroud)
至于用法,请说你有以下WCF REST方法:
[OperationContract]
[WebInvoke(Method = WebRequestMethods.Http.Post, UriTemplate = "/Upload")]
void Upload(Stream data);
Run Code Online (Sandbox Code Playgroud)
你可以像这样实现它
public void Upload(Stream data)
{
MultipartParser.ParseFiles(
data,
WebOperationContext.Current.IncomingRequest.ContentType,
MyProcessMethod);
}
Run Code Online (Sandbox Code Playgroud)
Dar*_*rov 32
您可以查看以下博客文章,其中说明了一种可用于multipart/form-data
使用Multipart Parser在服务器上进行解析的技术:
public void Upload(Stream stream)
{
MultipartParser parser = new MultipartParser(stream);
if (parser.Success)
{
// Save the file
SaveFile(parser.Filename, parser.ContentType, parser.FileContents);
}
}
Run Code Online (Sandbox Code Playgroud)
另一种可能性是启用aspnet兼容性和使用,HttpContext.Current.Request
但这不是一种非常WCFish的方式.
Jak*_*ods 25
我有一些基于字符串解析的解析器问题,特别是对于大文件我发现它会耗尽内存而无法解析二进制数据.
为了应对这些问题,我已经开源了在C#中的multipart/form-data的解析器我自己尝试在这里
特征:
限制:
只需使用MultipartFormDataParser类,如下所示:
Stream data = GetTheStream();
// Boundary is auto-detected but can also be specified.
var parser = new MultipartFormDataParser(data, Encoding.UTF8);
// The stream is parsed, if it failed it will throw an exception. Now we can use
// your data!
// The key of these maps corresponds to the name field in your
// form
string username = parser.Parameters["username"].Data;
string password = parser.Parameters["password"].Data
// Single file access:
var file = parser.Files.First();
string filename = file.FileName;
Stream data = file.Data;
// Multi-file access
foreach(var f in parser.Files)
{
// Do stuff with each file.
}
Run Code Online (Sandbox Code Playgroud)
在WCF服务的上下文中,您可以像这样使用它:
public ResponseClass MyMethod(Stream multipartData)
{
// First we need to get the boundary from the header, this is sent
// with the HTTP request. We can do that in WCF using the WebOperationConext:
var type = WebOperationContext.Current.IncomingRequest.Headers["Content-Type"];
// Now we want to strip the boundary out of the Content-Type, currently the string
// looks like: "multipart/form-data; boundary=---------------------124123qase124"
var boundary = type.Substring(type.IndexOf('=')+1);
// Now that we've got the boundary we can parse our multipart and use it as normal
var parser = new MultipartFormDataParser(data, boundary, Encoding.UTF8);
...
}
Run Code Online (Sandbox Code Playgroud)
或者像这样(稍慢但代码更友好):
public ResponseClass MyMethod(Stream multipartData)
{
var parser = new MultipartFormDataParser(data, Encoding.UTF8);
}
Run Code Online (Sandbox Code Playgroud)
当您克隆存储库时,只需导航到,也可以使用文档 HttpMultipartParserDocumentation/Help/index.html
Lor*_*ori 16
我在这里开源了一个C#Http表单解析器.
这比在CodePlex上提到的另一个稍微灵活一些,因为您可以将它用于Multipart和Non-Multipart form-data
,并且它还为您提供在Dictionary
对象中格式化的其他表单参数.
这可以使用如下:
非多
public void Login(Stream stream)
{
string username = null;
string password = null;
HttpContentParser parser = new HttpContentParser(stream);
if (parser.Success)
{
username = HttpUtility.UrlDecode(parser.Parameters["username"]);
password = HttpUtility.UrlDecode(parser.Parameters["password"]);
}
}
Run Code Online (Sandbox Code Playgroud)
多
public void Upload(Stream stream)
{
HttpMultipartParser parser = new HttpMultipartParser(stream, "image");
if (parser.Success)
{
string user = HttpUtility.UrlDecode(parser.Parameters["user"]);
string title = HttpUtility.UrlDecode(parser.Parameters["title"]);
// Save the file somewhere
File.WriteAllBytes(FILE_PATH + title + FILE_EXT, parser.FileContents);
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
121975 次 |
最近记录: |