表单数据名称问题
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));
这可行,但问题是 ContentDisposition 的 name。
如果您注意到,它会查找 "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;
}
只是为了涵盖所有基地。它不是最好的,但应该可以正常工作。
我有一个 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));
这可行,但问题是 ContentDisposition 的 name。 如果您注意到,它会查找 "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;
}
只是为了涵盖所有基地。它不是最好的,但应该可以正常工作。