只需在 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();
}
}
}
除了试图弄清楚为什么异步回发两次之外,还有一个解决方案是保存文件 md5 校验和。
在数据库中,创建一个名为校验和的额外列并保存 MD5(数据),然后在数据库中保存文件时,执行先前的检查,检查是否已经存在具有相同校验和的文件。
这可以防止您的表保存重复的文件,例如,这些文件无论如何都会由不同的用户上传。
您可以使用以下代码计算哈希:
MD5 md5Hash = MD5.Create();
byte[] hash = md5Hash.ComputeHash(bytes);
string checksum = Convert.ToBase64String(hash);
在数据库中插入校验和,并使用它来执行以前的文件存在性检查。
问候。