仅在Web Service上传文件一次

时间:2013-10-16 19:09:01

标签: c# asp.net ajax web-services webforms

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

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

我使用这个库Simple example of ajax file upload,如果您能解决这个技术问题,我将不胜感激。我搜索了好几个小时,但我还没找到。

修改 要回答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();
        }
    }
}

1 个答案:

答案 0 :(得分:0)

一个解决方案除了试图找出,为什么异步回发两次是保存文件md5校验和。

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

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

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

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

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

问候。