【发布时间】:2013-08-24 08:00:53
【问题描述】:
我有一个 MVC web api,它接收表单上的附件,它还需要一个文本和整数字段来上传。这些字段是用于验证上传者的(字符串)userId 和用于将附件连接到数据库中的请求的(int)requestId。 目前它可以工作,但是对于多部分表单数据,我需要从请求中获取字段,而不是作为表单提交中的参数。我的问题是,当保存文件时,我需要使用 requestId(来自表单)和附件 ID(来自数据库)修改文件的名称,因此它读取(requestId)-(attachmentId)-(fileName)。我一直使用的方法涉及下载文件,然后从请求中获取数据,因为在初始化提供程序和下载的文件之前,它总是返回 null,然后在数据库和文件系统中重命名文件。我希望有人可能有更好的方法来做到这一点,这样我就可以一步完成使用适当变量的重命名。
这是我现在为我的控制器准备的东西
public async Task<HttpResponseMessage> PostFormData()
{
const string folderName = "uploads";
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException((HttpStatusCode.UnsupportedMediaType));
}
var rootUrl = Request.RequestUri.AbsoluteUri.Replace(Request.RequestUri.AbsolutePath, String.Empty);
// this is needed to create an attachment and get the attachment id for the file
var value = new Attachment {UserId = "1", RequestId = 1};
value = _dataManager.CreateNewAttachment(value);
string root = HttpContext.Current.Server.MapPath("~/" + folderName);
// this is where the provider gets initialized and also where the file is actually downloaded
// in here I have it set up to rename the file but I can't seem to get the parameters needed for the file name before hand
var provider = new CustomMultipartFormDataStreamProvider(root, value.CreditRequestId, value.Id);
try
{
// this is the command that allows me to get the data from the inputs on the form,
// but it requires the initialized provider which downloaded the file to get it
await Request.Content.ReadAsMultipartAsync(provider);
// and here is wher I actually get the input parameters I needed
foreach (var key in provider.FormData.AllKeys)
{
foreach (var val in provider.FormData.GetValues(key))
{
//Trace.WriteLine(string.Format("{0}: {1}", key, val));
if (key == "requestId")
{
value.CreditRequestId = int.Parse(val);
}
if (key == "userId")
{
value.UserId = val;
}
}
}
// below here is where I have it checking security against the userId, destroying the file if it is determined to be unsafe
// and where I rename the file as well as modify the database with the proper content for the attachment
下面是我初始化以获取文件并更改名称的自定义多部分表单数据流提供程序,但在此之前我无法获取我需要正确执行此操作的参数,而无需重新访问文件并重命名它
public class CustomMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
{
public int RequestId;
public int AttachmentId;
public CustomMultipartFormDataStreamProvider(string path, int requestId, int attachmentId)
: base(path)
{
RequestId = requestId;
AttachmentId = attachmentId;
}
public override string GetLocalFileName(HttpContentHeaders headers)
{
//int requestId = 0;
//int attachmentId = 0;
var name = !string.IsNullOrEmpty(headers.ContentDisposition.FileName)
? RequestId + "-" + AttachmentId + "-" + headers.ContentDisposition.FileName
: RequestId + "-" + AttachmentId + "-NoName";
return name.Replace("\"", string.Empty);
}
我已经搜索了谷歌并因此寻找答案,我想我有一些答案,但它们似乎没有用,我尝试从提供程序中获取数据,但它总是返回 null。 如果有人对此有解决方案,将不胜感激
【问题讨论】:
标签: asp.net-mvc file-upload webforms asp.net-web-api multipartform-data