我无法理解 .NET 4.5 中的 async/await 功能。我在 Web API 控制器中使用下面的代码从表单中捕获多个文件以及其他一些表单数据。我无法控制表单或它如何发送数据。
我想要做的是接收文件,从表单中获取数据,基于该表单数据读取数据库,移动文件,并更新另一个数据库表。使用下面的代码,我可以轻松获取文件或表单数据。我根据表单数据中传递的 formID 从数据库中获取数据。
当我取消注释底部附近的代码以写回数据库时,我遇到了问题。如果我有三个文件,那么在 catch 块捕获异常之前,只有其中一个会被移动。我假设我的问题与 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);
}
}