我正在尝试将此功能分为传统的3层模式,但遇到一些困难。
数据访问不是我经常使用的东西,我想要一些指导。
我从code from this blog开始,到目前为止我所做的工作如下。我正在将返回类型转换为SqlDataReader
,现在我已经注释掉了需要分离的代码。
// This is the DAL layer:
public SqlDataReader DownloadFile(int fileId)
{
//int id = int.Parse((sender as LinkButton).CommandArgument);
//byte[] bytes;
//string fileName, contentType;
//string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
//using (SqlConnection con = new SqlConnection(constr))
//{
cmd.CommandText = "SELECT [fileId],[fileName],[fileData],[postedBy] FROM [dbo].[FilesLibrary] where fileId=@Id";
cmd.Parameters.AddWithValue("@Id", fileId);
cmd.Connection = cmd.Connection;
try
{
cmd.Connection.Open();
using (SqlDataReader sdr = cmd.ExecuteReader())
{
//sdr.Read();
//bytes = (byte[])sdr["Data"];
//contentType = sdr["ContentType"].ToString();
//fileName = sdr["Name"].ToString();
return sdr;
}
}
catch (Exception ex)
{
cmd.Connection.Close();
throw;
}
//}
//Response.Clear();
//Response.Buffer = true;
//Response.Charset = "";
//Response.Cache.SetCacheability(HttpCacheability.NoCache);
//Response.ContentType = contentType;
//Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName);
//Response.BinaryWrite(bytes);
//Response.Flush();
//Response.End();
}
// The BL is below:
public SqlDataReader GetFileDownload(int fileId)
{
try
{
dsGetFiles files = new dsGetFiles();
return files.DownloadFile(fileId);
}
catch (Exception ex) { throw ex; }
}
// The code file is as follows:
protected void DownloadFile(object sender, EventArgs e)
{
int id = int.Parse((sender as LinkButton).CommandArgument);
byte[] bytes;
string fileName, contentType;
GetFiles fileInfo = new GetFiles();
fileInfo.GetFileDownload(id);
// Here I don't know what to do with the fileInfo object and how to get data out of it.
//sdr.Read();
//bytes = (byte[])sdr["fileData"];
//contentType = sdr["ContentType"].ToString();
//fileName = sdr["fileName"].ToString();
Response.Clear();
Response.Buffer = true;
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = contentType;
Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName);
Response.BinaryWrite(bytes);
Response.Flush();
Response.End();
}
答案 0 :(得分:1)
// This is the DAL layer:
public DataSet DownloadFile(int fileId)
{
//I don't know from where you are taking your command and connection, but I will assume that this is working correctly, I don't like this method ! Also close a connection only on catch block? Your are using only one connection ? If you tell me that this method is not working I will re write it too.
cmd.CommandText = "SELECT [fileId],[fileName],[fileData],[postedBy] FROM [dbo].[FilesLibrary] where fileId=@Id";
cmd.Parameters.AddWithValue("@Id", fileId);
cmd.Connection = cmd.Connection;
try
{
cmd.Connection.Open();
DataSet dst = new DataSet();
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
{
adapter.Fill(dst, "FilesLibary");
}
return dst;
}
catch (Exception ex)
{
cmd.Connection.Close();
throw;
}
}
// The BL is below:
public byte[] GetFileDownload(int fileId)
{
try
{
DataSet fileDst = new DownloadFile();// method from DA layer
return (byte[])fileDst.Tables[0].Rows[0]["fileData"];
}
catch (Exception ex) { throw ex; }
}
protected void DownloadFile(object sender, EventArgs e)
{
int id = int.Parse((sender as LinkButton).CommandArgument);
byte[] bytes = fileInfo.GetFileDownload(id);
//Now do your magic, if you want to have fileName in the business logic you should take GetFileDownload should return DataSet. After that take byte[] and fileName. I will write the fileName to be test for this case to not re write everything here !
Response.Clear();
Response.Buffer = true;
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = contentType;
Response.AppendHeader("Content-Disposition", "attachment; filename=Test");
Response.BinaryWrite(bytes);
Response.Flush();
Response.End();
}
请注意:您的DataAccess层非常糟糕。你应该重写它。就像我在DataLayer中更改方法后看到的那样,您甚至不需要BO逻辑方法,因为您的数据层将重新运行所需的DataSet,您可以调用protected void DownloadFile(object sender, EventArgs e)
在这个问题中,我写了一些完整的数据层类,如果你想要的话可以检查: checking user name or user email already exists
PS。很抱歉打开和结束括号格式化问题!