如何获取使用 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 }我正在从 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 the client I'm able to get the filename, but how do I get the aditional parameter?
推荐答案如果您使用 .NET 4.5 或更高版本,请考虑使用 System.Net.Mime.ContentDisposition 类:
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否则,您需要根据规范解析Content-Disposition标头
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; } } }那么就可以这样使用了:
Then you can use it in this way:
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
发布评论