只需在 Web 服务中上传文件一次

本文关键字:文件 一次 Web 服务 | 更新日期: 2023-09-27 18:35:36

我需要通过 WebService (.asmx) 从 asp.net Web 表单应用程序上传一个文件,并将其转换为字节并保存到数据库中。

问题是该文件总是上传两次,这会在我的数据库表中创建重复项。当我启动调试模式时,断点会向上移动,就像我单击了两次开始上传按钮一样。

我使用这个库 ajax 文件上传的简单示例,如果您能找到这个技术问题的答案,我将不胜感激。我已经搜索了很多小时,但还没有找到。

编辑回答加里森·尼利:页面加载时的代码是

        protected override void OnInit(EventArgs e)
    {
        this.ScriptManager1.AsyncPostBackTimeout = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["AsyncPostBackTimeout"]);
        this.ParentRepeaterBind();
        base.OnInit(e);
    }
    protected void Page_Load(object sender, EventArgs e)
    {
    }

上传按钮上的代码是:

/// <summary>
/// Summary description for WebService
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
[System.Web.Script.Services.ScriptService]
public class WebService : System.Web.Services.WebService
{
    [WebMethod, ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public string HelloWorld()
    {
        byte[] bytes;
        if (Context.Request.Files[0] != null && Context.Request.Files[0].InputStream != null)
        {
            bytes = ReadStream(Context.Request.Files[0].InputStream);
            // Read the file and convert it to Byte Array
            string filePath = Context.Request.Files[0].FileName;
            string filename = Path.GetFileName(filePath);
            string ext = Path.GetExtension(filename);
            string contenttype = String.Empty;
            //Set the contenttype based on File Extension
            switch (ext)
            {
                case ".doc":
                    contenttype = "application/vnd.ms-word";
                    break;
                case ".docx":
                    contenttype = "application/vnd.ms-word";
                    break;
                case ".xls":
                    contenttype = "application/vnd.ms-excel";
                    break;
                case ".xlsx":
                    contenttype = "application/vnd.ms-excel";
                    break;
                case ".jpg":
                    contenttype = "image/jpg";
                    break;
                case ".png":
                    contenttype = "image/png";
                    break;
                case ".gif":
                    contenttype = "image/gif";
                    break;
                case ".pdf":
                    contenttype = "application/pdf";
                    break;
            }
            if (contenttype != String.Empty)
            {
                Stream fs = Context.Request.Files[0].InputStream;
                BinaryReader br = new BinaryReader(fs);
                //insert the file into database
                string strQuery = "insert into dbo.FileUpload(Name, ContentType, Data) values (@Name, @ContentType, @Data)";
                SqlCommand cmd = new SqlCommand(strQuery);
                cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = filename;
                cmd.Parameters.Add("@ContentType", SqlDbType.VarChar).Value = contenttype;
                cmd.Parameters.Add("@Data", SqlDbType.Binary).Value = bytes;
                InsertUpdateData(cmd);
            }
            else
            {
            }
        }
        return "Hello World";
    }
    public static byte[] ReadStream(Stream input)
    {
        byte[] buffer = new byte[16 * 1024];
        using (MemoryStream ms = new MemoryStream())
        {
            int read;
            while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, read);
            }
            return ms.ToArray();
        }
    }
    private Boolean InsertUpdateData(SqlCommand cmd)
    {
        String strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["default"].ConnectionString;
        SqlConnection con = new SqlConnection(strConnString);
        cmd.CommandType = CommandType.Text;
        cmd.Connection = con;
        try
        {
            con.Open();
            cmd.ExecuteNonQuery();
            return true;
        }
        catch (Exception ex)
        {
            //Response.Write(ex.Message);
            return false;
        }
        finally
        {
            con.Close();
            con.Dispose();
        }
    }
}

只需在 Web 服务中上传文件一次

除了试图弄清楚为什么异步回发两次之外,还有一个解决方案是保存文件 md5 校验和。

在数据库中,

创建一个名为校验和的额外列并保存 MD5(数据),然后在数据库中保存文件时,执行先前的检查,检查是否已经存在具有相同校验和的文件。

这可以防止您的表保存重复的文件,例如,这些文件无论如何都会由不同的用户上传。

您可以使用以下代码计算哈希:

MD5 md5Hash = MD5.Create();
byte[] hash = md5Hash.ComputeHash(bytes);
string checksum = Convert.ToBase64String(hash);

在数据库中插入校验和,并使用它来执行以前的文件存在性检查。

问候。