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