【问题标题】:Attachment does not get uploaded to .mdb but no errors occur whatsoever附件不会上传到 .mdb,但不会发生任何错误
【发布时间】:2019-11-15 21:04:31
【问题描述】:

我需要将附件上传到 MS Access .mdb,但代码一直运行到最后,但没有任何更新。

查看查询语法并检查代码中使用的 OleDbType。

protected void Button1_Click(object sender, EventArgs e)
{
    mdlTrab mdl = new mdlTrab();
    mdl.nome = txtNome.Text;
    mdl.trab = titTrab.Text;
    mdl.campo = FileUpload1.FileBytes;

    if (FileUpload1.HasFile)
    {
        try
        {
            string fileExtension = Path.GetExtension(FileUpload1.FileName);
            if (fileExtension.ToLower() == ".doc" || fileExtension.ToLower() == ".docx" || fileExtension.ToLower() == ".pdf")
            {
                if (FileUpload1.PostedFile.ContentLength > 1024000)
                {
                    StatusLabel.ForeColor = System.Drawing.Color.Red;
                    StatusLabel.Text = "Status do upload: O arquivo deve ter menos de 1000 kb!";
                }
                else
                {
                    string conexaoAccess = ConfigurationManager.ConnectionStrings["conexaoAccess"].ToString();
                    using (OleDbConnection conexaodb = new OleDbConnection(conexaoAccess))
                    {
                        conexaodb.Open();
                        OleDbCommand cmd = new OleDbCommand("UPDATE tbl_reg SET Campo1 = @campo, titulo_trab = @trab WHERE nome_user = @nome", conexaodb);

                        cmd.Parameters.Add("@campo", OleDbType.LongVarBinary).Value = mdl.campo;
                        cmd.Parameters.Add("@trab", OleDbType.LongVarChar).Value = mdl.trab;
                        cmd.Parameters.Add("@nome", OleDbType.LongVarChar).Value = mdl.nome;

                        int rowsChanged = cmd.ExecuteNonQuery();
                        StatusLabel.ForeColor = System.Drawing.Color.Green;
                        StatusLabel.Text = "Arquivo carregado!";
                    }

                }
            }
            else
            {
                StatusLabel.ForeColor = System.Drawing.Color.Red;
                StatusLabel.Text = "Status do upload: Somente arquivos .doc, .docx e .pdf são aceitos!";
            }
        }
         catch (InvalidOperationException ex)
        {
            StatusLabel.ForeColor = System.Drawing.Color.Red;
            StatusLabel.Text = "Status do upload: Erro ao carregar arquivo, ocorreu o seguinte erro: " + ex.Message;
        }
        catch (OleDbException ex)
        {
            StatusLabel.ForeColor = System.Drawing.Color.Red;
            StatusLabel.Text = "Status do upload: Erro ao atualizar banco de dados, erro oorrido: " + ex.Message;
        }

        catch (Exception ex)
        {
            Console.WriteLine("Erro: ", ex.Message);
        }
    }
}

模型

public class mdlTrab
{
    public int codigo { get; set; }
    public string nome { get; set; }
    public string trab { get; set; }
    public byte[] campo { get; set; }
}

预期:上传数据库中的文件。 实际结果:没有结果

【问题讨论】:

  • 空的 catch 块是一个非常糟糕的主意。此外,你的空 if 块是一个相当糟糕的主意。在未来的几年里,有人会使用这个代码并说“为什么这个 f*%]*} 文件不上传?”他们必须阅读代码才能发现它被限制在 1 MB 以内。出于对理智的热爱,至少在其中放置一些日志记录或消息
  • and no error,您的评论可能是真的,也可能不是 - softwareengineering.stackexchange.com/questions/291283/…
  • 你忘了ExecuteNonQuery这个命令。
  • 你的代码吞下了 Excetpions。所有例外。 没有办法让您知道尝试中是否有任何地方,感谢catch (Exception ex) { } 先修复该部分。这是我经常链接的关于正确异常处理的两篇文章:blogs.msdn.microsoft.com/ericlippert/2008/09/10/… | codeproject.com/Articles/9538/…
  • 不,ifs 和 catch 是故意为空的,只是为了让它更小,以便在此处发布..

标签: c# asp.net


【解决方案1】:

您需要调用ExecuteNonQuery 才能有效地执行命令,但还有另一个错误需要修复。在 OleDb 中,参数不是通过它们的名称来识别的,而是通过它们在命令文本中的位置来识别的。

您需要按照它们在命令中出现的确切顺序添加参数,因此,请按此顺序重新排列代码行

cmd.Parameters.Add("@campo", OleDbType.LongVarBinary).Value = mdl.campo;
cmd.Parameters.Add("@trab", OleDbType.LongVarChar).Value = mdl.trab;
cmd.Parameters.Add("@nome", OleDbType.LongVarChar).Value = mdl.nome;

最后调用

int rowsChanged = cmd.ExecuteNonQuery();

当然,上面所有关于空try/catch的cmets都非常重要。如果您不处理异常(例如写入日志文件或显示消息),则最好删除 try/catch 块。
您应该考虑的另一点是连接对象的处置。该对象在内部保留非托管资源,您需要尽快释放它们。所以你应该使用using statement

string conexaoAccess = ".....";
using(OleDbConnection conexaodb = new OleDbConnection(conexaoAccess))
{  
    conexaodb.Open();

    ... create the command, add parameters and execute the command

} // Here the connection will be closed and disposed

【讨论】:

  • 因为连接对象在使用里面,我不需要 conexaodb.Close()?它会在关闭 } 时自动处理?
  • 是的,完全正确。 using 语句将为您完成。 using 语句在编译时被替换为总是在退出时调用 Dispose 方法的代码。 Dispose 在连接对象上调用 Close。这是一个问题的链接,该问题解释了编译时哪些代码将替换 using 语句:stackoverflow.com/questions/946999/…
  • 感谢史蒂夫的帮助,如果我能投票给你,我会的。谢谢!
  • 我认识史蒂夫,对不起。我在上面发布了解决方案,您给了我非常有用的提示,但它们并没有帮助我解决问题的根源。
【解决方案2】:

通过在字段中插入文件的超链接来解决,因为我正在寻找它是最好的方法,DAO 只是不会满足我的需求: Pasting a hyperlink value from C# to Access

感谢您的帮助。谢谢各位!

【讨论】:

    猜你喜欢
    • 2021-09-18
    • 2013-12-14
    • 1970-01-01
    • 2017-02-16
    • 1970-01-01
    • 2014-05-20
    • 1970-01-01
    • 2023-04-08
    • 2020-04-10
    相关资源
    最近更新 更多