方法来处理异步接收的表单数据

本文关键字:表单 数据 处理 异步 方法 | 更新日期: 2023-09-27 18:09:41

我很难理解。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);
    }
}

方法来处理异步接收的表单数据

asyncawait为异步代码提供了自然程序流程。所以在大多数情况下,你可以按照通常的方式来思考代码:

当我取消注释底部附近的代码以写回数据库时,我遇到了问题。如果有三个文件,在catch块捕获异常之前,只移动其中一个文件。

这是我从中得到的:

  • 你的数据库代码抛出了一个异常。
  • 当抛出异常时,它离开foreach循环进入catch处理程序。

在不知道异常的情况下很难提供很大帮助,但是在异步方法中执行同步数据库操作对我来说似乎是一个坏主意。试着把你的代码改成:

int c = await cmd.ExecuteNonQueryAsync();