0

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

问题是文件总是被上传两次,这在我的数据库表中创建了一个副本。当我开始调试模式时,断点向上移动,就好像我点击了两次开始上传按钮一样。

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

编辑 回答 Garrison Neely:页面加载时的代码是

        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();
        }
    }
}
4

1 回答 1

0

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

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

这可以防止您的表格保存重复的文件,这些文件本来会被不同的用户上传,例如。

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

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

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

问候。

于 2013-12-29T22:45:32.477 回答