如何使用WebClient从WebAPI控制器返回Content-Disposition参数?
How do I get Content-Disposition parameters I returned from WebAPI controller using WebClient?
WebApi控制器
[Route("api/mycontroller/GetFile/{fileId}")] public HttpResponseMessage GetFile(int fileId) { try { var file = GetSomeFile(fileId) HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK); response.Content = new StreamContent(new MemoryStream(file)); response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment"); response.Content.Headers.ContentDisposition.FileName = file.FileOriginalName; /********* Parameter *************/ response.Content.Headers.ContentDisposition.Parameters.Add(new NameValueHeaderValue("MyParameter", "MyValue")); return response; } catch(Exception ex) { return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex); } }客户
void DownloadFile() { WebClient wc = new WebClient(); wc.DownloadDataCompleted += wc_DownloadDataCompleted; wc.DownloadDataAsync(new Uri("api/mycontroller/GetFile/18")); } void wc_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e) { WebClient wc=sender as WebClient; // Try to extract the filename from the Content-Disposition header if (!String.IsNullOrEmpty(wc.ResponseHeaders["Content-Disposition"])) { string fileName = wc.ResponseHeaders["Content-Disposition"].Substring(wc.ResponseHeaders["Content-Disposition"].IndexOf("filename=") + 10).Replace("\"", ""); //FileName ok /****** How do I get "MyParameter"? **********/ } var data = e.Result; //File OK }I我正在从WebApi控制器返回一个文件,我在响应内容标题中附加了文件名,但我还想要返回一个附加值。
I'm returning a file from WebApi controller, I'm attaching the file name in the response content headers, but also I'd like to return an aditional value.
In客户端我能够获取文件名,但如何获取aditional参数?
In the client I'm able to get the filename, but how do I get the aditional parameter?
推荐答案如果您使用的是.NET 4.5或更高版本,请考虑使用 System.Net.Mime.ContentDisposition class:
If you are working with .NET 4.5 or later, consider using the System.Net.Mime.ContentDisposition class:
string cpString = wc.ResponseHeaders["Content-Disposition"]; ContentDisposition contentDisposition = new ContentDisposition(cpString); string filename = contentDisposition.FileName; StringDictionary parameters = contentDisposition.Parameters; // You have got parameters now编辑:
否则,您需要根据它的规范。
otherwise, you need to parse Content-Disposition header according to it's specification.
这是一个执行解析的简单类,接近规范:
Here is a simple class that performs the parsing, close to the specification:
class ContentDisposition { private static readonly Regex regex = new Regex( "^([^;]+);(?:\\s*([^=]+)=((?<q>\"?)[^\"]*\\k<q>);?)*$", RegexOptions.Compiled ); private readonly string fileName; private readonly StringDictionary parameters; private readonly string type; public ContentDisposition(string s) { if (string.IsNullOrEmpty(s)) { throw new ArgumentNullException("s"); } Match match = regex.Match(s); if (!match.Success) { throw new FormatException("input is not a valid content-disposition string."); } var typeGroup = match.Groups[1]; var nameGroup = match.Groups[2]; var valueGroup = match.Groups[3]; int groupCount = match.Groups.Count; int paramCount = nameGroup.Captures.Count; this.type = typeGroup.Value; this.parameters = new StringDictionary(); for (int i = 0; i < paramCount; i++ ) { string name = nameGroup.Captures[i].Value; string value = valueGroup.Captures[i].Value; if (name.Equals("filename", StringComparison.InvariantCultureIgnoreCase)) { this.fileName = value; } else { this.parameters.Add(name, value); } } } public string FileName { get { return this.fileName; } } public StringDictionary Parameters { get { return this.parameters; } } public string Type { get { return this.type; } } }然后你可以在这样:
static void Main() { string text = "attachment; filename=\"fname.ext\"; param1=\"A\"; param2=\"A\";"; var cp = new ContentDisposition(text); Console.WriteLine("FileName:" + cp.FileName); foreach (DictionaryEntry param in cp.Parameters) { Console.WriteLine("{0} = {1}", param.Key, param.Value); } } // Output: // FileName:"fname.ext" // param1 = "A" // param2 = "A"使用此类时唯一需要考虑的是它不处理参数(或文件名)没有双引号。
The only thing that should be considered when using this class is it does not handle parameters (or filename) without a double quotation.
编辑2:
它现在可以处理没有引号的文件名。
It can now handle file names without quotations.
更多推荐
获取Content
发布评论