表单数据名称问题

Issue with form-data name

我有一个 angular 应用程序正在使用我的 API 上传文件。 我有一些代码如下所示:

var url = __env.apiUrl + 'documents/' + containerName + '/' + reference;
var formData = new FormData();            
var request = {
    method: 'POST',
    url: url,
    data: formData,
    headers: {
        'Content-Type': undefined
    }
};

formData.append('file', file);
formData.append('metadata', JSON.stringify(metadata));

return $http(request).then(function (response) {
    SimpleCache.remove(__env.apiUrl + '/documents');
    listDirectiveService.refresh('document');
    ngNotify.set('Your document was created.');
}, notifications.handleError).finally(function () {                
    onComplete();
});

在我的 API 这边,用于获取文件的 c# 如下所示:

if (!request.Content.IsMimeMultipartContent("form-data")) throw new HttpResponseException(request.CreateResponse(HttpStatusCode.UnsupportedMediaType));
Valiate(containerName, directoryName);

var filesReadToProvider = await request.Content.ReadAsMultipartAsync();

// We assume that the form data name is file and metadata respectively
var fileStream = filesReadToProvider.Contents.SingleOrDefault(m => m.Headers.ContentDisposition.Name.Equals("\"file\"", StringComparison.OrdinalIgnoreCase));
var metaDataStream = filesReadToProvider.Contents.SingleOrDefault(m => m.Headers.ContentDisposition.Name.Equals("\"metadata\"", StringComparison.OrdinalIgnoreCase));

if (fileStream == null) throw new ArgumentNullException(nameof(fileStream));
if (metaDataStream == null) throw new ArgumentNullException(nameof(metaDataStream));

这可行,但问题是 ContentDispositionname。 如果您注意到,它会查找 "file" 而不是 file。 有谁知道为什么它有额外的引号?

我从来没有发现为什么会这样,所以我只是把我的功能变成这样:

public async Task<string> CreateAsync(HttpRequestMessage request, string containerName, string directoryName, string existingUrl = "")
{
    if (!request.Content.IsMimeMultipartContent("form-data")) throw new HttpResponseException(request.CreateResponse(HttpStatusCode.UnsupportedMediaType));
    Valiate(containerName, directoryName);

    var filesReadToProvider = await request.Content.ReadAsMultipartAsync();

    // We assume that the form data name is file and metadata respectively
    var fileStream = filesReadToProvider.Contents.SingleOrDefault(m => 
        m.Headers.ContentDisposition.Name.Equals("\"file\"", StringComparison.OrdinalIgnoreCase) ||
        m.Headers.ContentDisposition.Name.Equals("file", StringComparison.OrdinalIgnoreCase));
    var metaDataStream = filesReadToProvider.Contents.SingleOrDefault(m =>
        m.Headers.ContentDisposition.Name.Equals("\"metadata\"", StringComparison.OrdinalIgnoreCase) ||
        m.Headers.ContentDisposition.Name.Equals("metadata", StringComparison.OrdinalIgnoreCase));

    if (fileStream == null) throw new ArgumentNullException(nameof(fileStream));
    if (metaDataStream == null) throw new ArgumentNullException(nameof(metaDataStream));

    // Upload our file
    var fileBytes = await fileStream.ReadAsByteArrayAsync();
    var mediaType = fileStream.Headers.ContentType.MediaType;
    var friendlyFileName = fileStream.Headers.ContentDisposition.FileName.Replace("\"", string.Empty);
    var fileName = $"{Guid.NewGuid()}{Path.GetExtension(friendlyFileName)}";
    var directory = GetDirectory(containerName, directoryName);
    var fileUrl = await Upload(directory, fileName, mediaType, fileBytes);

    // Add our metadata
    var metadata = await GetMetadataFromMemoryStreamAsync(metaDataStream);
    metadata.Add("fileName", friendlyFileName);
    metadata.Add("directory", directoryName);
    metadata.Add("created", DateTime.UtcNow.ToString(CultureInfo.InvariantCulture));
    await AddFileMetaDataAsync(fileUrl, metadata);

    // Delete any existing file
    if (!string.IsNullOrEmpty(existingUrl) && fileUrl != existingUrl) await DeleteAsync(containerName, directoryName, existingUrl);

    return fileUrl;
}

只是为了涵盖所有基地。它不是最好的,但应该可以正常工作。