asp.net

位置:IT落伍者 >> asp.net >> 浏览文章

Asp.net直接保存文件到客户端


发布日期:2023年06月17日
 
Asp.net直接保存文件到客户端

在我们的系统的编写过程中应该有很多的时候需要客户下载文件我第一次的做法(应该也是大部分人的做法吧?)是:


HttpResponse response = HttpContextCurrentResponse;

string js = <script language=javascript>windowopen({});</script>;

js = stringFormat(js url);

responseWrite(js);

但是有个问题了就是会被广告拦截软件直接拦截掉另我非常的头痛于是寻找更好的解决方法看了用ResponseBinaryWrite写文件流一文之后觉得确实可以如此修改代码如下:

/**//**//**//// <summary>

/**//// 下载文件

/**//// </summary>

/**//// <param name=filename>文件物理地址</param>

protected void DownloadFile(string filename)

{

string saveFileName = testxls;

int intStart = filenameLastIndexOf(\)+;

saveFileName = filenameSubstring(intStartfilenameLengthintStart);

FileStream MyFileStream;

long FileSize;

MyFileStream = new FileStream(filenameFileModeOpen);

FileSize = MyFileStreamLength;

byte[] Buffer = new byte[(int)FileSize];

MyFileStreamRead(Buffer (int)FileSize);

MyFileStreamClose();

ResponseAddHeader(ContentDisposition attachment;filename=+saveFileName);

ResponseContentEncoding = SystemTextEncodingGetEncoding(GB);

ResponseContentType = application/vndmsexcel;

ResponseBinaryWrite(Buffer);

ResponseFlush();

ResponseClose();

ResponseEnd();

}

但是有个严重的问题就是文件格式这样只是将流输出且无法正确识别格式还好能人层出不穷 柚子Nan 提出了能否不考虑文件的类型直接把文件显示到浏览器(Response) 的想法正好切中我的要害所在于是急忙研究了柚子Nan的想法修改出最后代码

/**//**//**//// <summary>

/**//// 下载文件

/**//// </summary>

/**//// <param name=filename>文件物理地址</param>

protected void DownloadFile(string filename)

{

string saveFileName = testxls;

int intStart = filenameLastIndexOf(\)+;

saveFileName = filenameSubstring(intStartfilenameLengthintStart);

ResponseClear();

ResponseCharset = utf;

ResponseBuffer= true;

thisEnableViewState = false;

ResponseContentEncoding = SystemTextEncodingUTF;

ResponseAppendHeader(ContentDispositionattachment;filename= + saveFileName);

ResponseWriteFile(filename);

ResponseFlush();

ResponseClose();

ResponseEnd();

}

使用昨天直接保存文件到客户端 中的方法经过我的反复测试各式文档都运行完全正常于是昨晚修改了现有代码修改了下载方法以解决一直困扰自己的窗口拦截问题

早上本来还沾沾自喜这下再也不用老跟客户解释为什么窗口会没掉了可惜啊人算不如天算

早上客户就反映下载的文件全是乱码立马在本机进行测试没问题再同事的机器上试验同样没问题

那应该是客户端的问题才是只好让客户NetMeeting演示一下她的操作过程下载〉保存〉打开这么简单的流程不会做错吧?

正在郁闷之际突然脑光一闪终于发现不一样的地方立马试验果然如此!

到底有什么区别呢?请看操作图:

客人操作图

我的操作图

各位应该看出不同之处了吧?还看不出来?

这件事情的罪魁祸首就是:

解决方法:使用lovecherry 的如何从注册表读取文件的ContentType 一文的方法

修正代码:

/**//// <summary>

/// 下载文件

/// </summary>

/// <param name=filename>文件物理地址</param>

protected void DownloadFile(string filename)

{

string saveFileName = testxls;

int intStart = filenameLastIndexOf(\\)+;

saveFileName = filenameSubstring(intStartfilenameLengthintStart);

SystemIOFileInfo fi=new SystemIOFileInfo(filename);

string fileextname=fiExtension;

string DEFAULT_CONTENT_TYPE = application/unknown;

RegistryKey regkeyfileextkey;

string filecontenttype;

try

{

regkey=RegistryClassesRoot;

fileextkey=regkeyOpenSubKey(fileextname);

filecontenttype=fileextkeyGetValue(Content TypeDEFAULT_CONTENT_TYPE)ToString();

}

catch

{

filecontenttype=DEFAULT_CONTENT_TYPE;

}

ResponseClear();

ResponseCharset = utf;

ResponseBuffer= true;

thisEnableViewState = false;

ResponseContentEncoding = SystemTextEncodingUTF;

ResponseAppendHeader(ContentDispositionattachment;filename= + saveFileName);

ResponseContentType=filecontenttype;

ResponseWriteFile(filename);

ResponseFlush();

ResponseClose();

ResponseEnd();

}

最后得出结论:要实现柚子Nan提出的能否不考虑文件的类型直接把文件显示到浏览器(Response)有一种方法让客户端都不要隐藏已知的扩展名但是这种方法是无法适应大部分电脑使用者的(一般只有比较熟悉电脑的人才会这样做吧?)

bbs 看中的方法还没有试用不知道有没有作用

Private Sub Page_Load(ByVal sender As SystemObject ByVal e As SystemEventArgs) _

Handles MyBaseLoad

在此处放置初始化页的用户代码

定义是否是 SQL Server 数据库这里为False

Dim blnIsSQLServer As SystemBoolean = False

Dim strSQL As String

Dim objDataset As New DataSet()

Dim objConn As Object

Dim strCnn As String

If blnIsSQLServer Then

strCnn = User ID=sa;Initial Catalog=Northwind;Data Source=\NetSDK;

objConn = New SystemDataSqlClientSqlConnection(strCnn)

objConnOpen()

Dim objAdapter As New SystemDataSqlClientSqlDataAdapter()

strSQL = Select * from customers where country=USA

objAdapterSelectCommand = New SystemDataSqlClientSqlCommand(strSQL objConn)

objAdapterFill(objDataset)

Else

strCnn = Provider=MicrosoftJetOLEDB;Data Source= + ServerMapPath(Testmdb)

objConn = New SystemDataOleDbOleDbConnection(strCnn)

objConnOpen()

Dim objAdapter As New SystemDataOleDbOleDbDataAdapter()

strSQL = Select Top Title From Document

objAdapterSelectCommand = New SystemDataOleDbOleDbCommand(strSQL objConn)

objAdapterFill(objDataset)

End If

Dim oView As New DataView(objDatasetTables())

DataGridDataSource = oView

DataGridDataBind()

objConnClose()

objConnDispose()

objConn = Nothing

If RequestQueryString(bExcel) = Then

ResponseContentType = application/vndmsexcel

从ContentType header中去除charset设置

ResponseCharset =

关闭 ViewState

MeEnableViewState = False

Dim tw As New SystemIOStringWriter()

Dim hw As New SystemWebUIHtmlTextWriter(tw)

获取control的HTML

DataGridRenderControl(hw)

把HTML写回浏览器

ResponseWrite(twToString())

ResponseEnd()

End If

End Sub

               

上一篇:Asp.Net 建立一个在线 RSS 新闻聚合器

下一篇:Asp.net中处理一个站点不同Web应用共享Session的问题