使用ng-file-upload和WebApi上传CustomData

时间:2016-09-15 13:56:06

标签: angularjs asp.net-web-api http-post ng-file-upload

我正在尝试将文件和一些元数据上传到我使用ng-file-upload和Angular创建的WebApi服务。我按预期获取文件名和字节,但我无法获取我传递的元数据。这是我在Angular方面所做的事情

            Upload.upload({
                url: '/api/FileStorage/AddContent' + location.search,
                data: {file: files, year: vm.year }
            })

WebApi方面

       var streamProvider = new CustomMultipartFileStreamProvider();
                IEnumerable<HttpContent> parts = null;
                Task.Factory
                    .StartNew(() => parts = Request.Content.ReadAsMultipartAsync(streamProvider).Result.Contents,
                        CancellationToken.None,
                        TaskCreationOptions.LongRunning, // guarantees separate thread
                        TaskScheduler.Default)
                    .Wait();

                var customData = streamProvider.CustomData;

这里我使用MultiStreamProvider来获取文件,这里是该提供者的主要内容

  public override Task ExecutePostProcessingAsync()
    {
        foreach (var file in Contents)
        {
            var parameters = file.Headers.ContentDisposition.Parameters;
            var filename = GetNameHeaderValue(parameters, "filename");
            var year = GetNameHeaderValue(parameters, "year");
        }

        return base.ExecutePostProcessingAsync();
    }

我可以毫无问题地获取文件名,但我永远无法获得年份。当我查看参数变量

时,这是调试器中的值

enter image description here

正如您所看到的,名称是&#34; name&#34;价值是&#34;年&#34;当我希望这个名字是&#34;年&#34;和价值是&#34; 2016&#34;或者我正在传递的任何内容。我在这里做错了什么以及如何在Api的同一个调用中包含元数据?

1 个答案:

答案 0 :(得分:0)

我们使用与ng-file-upload和WebAPI类似的方法。为了从表单数据中获取值,我们无法使用GetNameHeaderValue。我们不得不做一些手动解析。我们决定使用在http://conficient.wordpress.com/2013/07/22/async-file-uploads-with-mvc-webapi-and-bootstrap/发布的修改版本来动态获取表单并将其卸载到强类型模型。但基本上,这是它在ExecutePostProcessingAsync方法中的作用:

public override async Task ExecutePostProcessingAsync()
{
  var formData = new FormCollection();
  for (int index = 0; index < Contents.Count; index++)
  {
     ContentDispositionHeaderValue contentDisposition = headers.ContentDisposition;
     if (contentDisposition != null)
     {
       HttpContent formContent = Contents[index];
       string formFieldName = UnquoteToken(contentDisposition.Name) ?? String.Empty;

       // Read the contents as string data and add to form data
       string formFieldValue = await formContent.ReadAsStringAsync();
       formData.Add(formFieldName, formFieldValue);
     }

     //For your case
     var filename = formData["filename"];
     var year = formData["year"];

这是使用的UnquoteToken方法:

private static string UnquoteToken(string token)
{
  if (String.IsNullOrWhiteSpace(token))
  {
    return token;
  }

  if (token.StartsWith("\"", StringComparison.Ordinal) && token.EndsWith("\"", StringComparison.Ordinal) && token.Length > 1)
  {
    return token.Substring(1, token.Length - 2);
  }

  return token;
}