フォームに添付ファイルを取り込む MVC Web API があり、アップロードにはテキストと整数フィールドも必要です。フィールドは、アップローダーを確認するための (文字列) userId と、添付ファイルをデータベース内の要求に接続するための (int) requestId です。現在は機能していますが、フォーム送信のパラメーターとしてではなく、リクエストからフィールドを取得する必要があるマルチパートフォームデータを使用しています。私の問題は、ファイルを保存するときに、(フォームからの) requestId と (データベースからの) 添付ファイル ID を使用してファイルの名前を変更し、(requestId)-(attachmentId)-(fileName) を読み取る必要があることです。私が使用してきた方法では、ファイルをダウンロードしてからリクエストからデータを取得します。これは、プロバイダーが初期化されてファイルがダウンロードされる前に常に null を返すためです。次に、データベースとファイル システムの両方でファイルの名前を変更します。誰かがこれを行うためのより良い方法を持っていることを望んでいたので、適切な変数で名前を変更することを1つのステップで行うことができます。
Here is what I have right now for my controller
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
Below is my Custom multipart form data stream provider that I initialized to get the file and change the name but before this I am unable to get the parameters I need to do this properly without having to revisit the file and rename it
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);
}
I have searched google and SO looking for an answer to this and I thought I had a few answers but they didn't seem to work, I have tried getting the data from within the provider but it always returns null. Please if anyone has a solution to this it would be greatly appreciated