.NET 4.5 の async/await 機能に頭を悩ませています。以下のコードを Web API コントローラーで使用して、フォームから複数のファイルを他のフォーム データと共にキャッチしています。フォームやデータの送信方法を制御することはできません。
私がやりたいことは、ファイルを受け取り、フォームからデータを取得し、そのフォーム データに基づいてデータベースを読み取り、ファイルを移動し、別のデータベース テーブルを更新することです。以下のコードを使用すると、ファイルまたはフォーム データを問題なく取得できます。フォーム データで渡された formID に基づいて、データベースからデータを取得します。
問題が発生したのは、データベースに書き戻すためにコードの下部にあるコメントを外したときです。3 つのファイルがあった場合、catch ブロックが例外をキャッチする前に、そのうちの 1 つだけが移動されます。私の問題は、PostFile メソッドが非同期であるという事実に関連していると思います。
このコードが機能するように記述する適切な方法は何ですか?
public async Task<HttpResponseMessage> PostFile()
{
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = GetRootPath();
var provider = new MyMultipartFormDataStreamProvider(root);
string logfile = root + "/form_data_output.txt";
try
{
// Read the form data and return an async task.
await Request.Content.ReadAsMultipartAsync(provider);
string form_id = provider.FormData.Get("FormId");
string driver_id = GetDriverID(form_id); // returns an int as a string
string location = ConfigurationManager.AppSettings["storagePath"];
location += form_id + "\\";
//// make sure the new directory exists
if (!Directory.Exists(location))
{
Directory.CreateDirectory(location);
}
var keys = provider.FormData.Keys.Cast<string>();
foreach (var k in keys.Where(k => k.StartsWith("FormViewer") == true))
{
string filename = provider.FormData.Get(k) + ".pdf";
string type_key = "FormType_" + k.Substring(k.IndexOf('_') + 1);
string type_value = provider.FormData.Get(type_key);
// setup the full path including filename
string path = root + "\\" + filename;
string newFullPath = location + filename;
// move the file
File.Move(path, newFullPath);
if (File.Exists(newFullPath))
{
if (File.Exists(newFullPath))
{
try
{
string conn_str = ConfigurationManager.ConnectionStrings["eMaintenanceConnection"].ConnectionString;
using (SqlConnection conn = new SqlConnection(conn_str))
{
SqlCommand cmd = new SqlCommand("INSERT INTO eSubmittal_Document VALUES (null,@driver_id,@location,@doctype)");
cmd.Parameters.AddWithValue("@driver_id", driver_id);
cmd.Parameters.AddWithValue("@location", location);
cmd.Parameters.AddWithValue("@doc_type", type_value);
conn.Open();
int c = await cmd.ExecuteNonQueryAsync();
conn.Close();
}
}
catch (Exception e)
{
LogEntry(logfile, e.Message);
}
}
}
}
return Request.CreateResponse(HttpStatusCode.OK);
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}