[英]How to download an image that a client uploaded in ASP.NET?
I have a website where users can upload images (part of some report) and I kinda don't know how to save those images.我有一个网站,用户可以在其中上传图片(某些报告的一部分),但我有点不知道如何保存这些图片。
I think the best way right now is to download those images into a folder of images.我认为现在最好的方法是将这些图像下载到图像文件夹中。
I never really did something like that and everything I tried isn't working.我从来没有真正做过那样的事情,我尝试的一切都不起作用。
Here's my code and markup.这是我的代码和标记。
HTML markup: the web HTML 标记:web
<div class="form-group">
<label asp-for="photoPath" class="control-label"></label>
<input asp-for="photoPath" class="" type="file" onchange="readURL(this);" id="file" accept="image/*" multiple />
<span asp-validation-for="photoPath" class="text-danger"></span>
</div>
<div class="form-group" id="display_image" style="display: none; overflow-y: scroll; height: 400px; width: auto;">
<output id="result" style="overflow-y:scroll; height:400px; width:auto; "></output>
<script>
document.querySelector("#file").addEventListener("change", (e) => {
if (window.File && window.FileReader && window.FileList && window.Blob) {
const files = e.target.files;
const output = document.querySelector("#result");
output.innerHTML = "";
for (let i = 0; i < files.length; i++) {
if (!files[i].type.match("image")) continue;
const picReader = new FileReader();
picReader.addEventListener("load", function (event) {
const picFile = event.target;
console.log(picFile.width)
const div = document.createElement("div");
div.innerHTML = `<img class="form-control" id="thumbnail" src="${picFile.result}" title="${picFile.name}" style="height: 500%;width: 200%;"/>`;
output.appendChild(div);
});
picReader.readAsDataURL(files[i]);
document.getElementById('display_image').setAttribute("style", "display:inline;width:auto");
}
} else {
alert("Your browser does not support File API");
}
});
</script>
C#: model class C#:model class
public class ReportModel
{
/*
Web stuff
*/
[DisplayName("Add photo")]
public List<string> photoPath { get; set; }
/*
More web stuff
*/
}
Well, we need more details as to how and where you plan to save the files.好吧,我们需要有关您计划保存文件的方式和位置的更多详细信息。
Assuming a webforms app?假设一个网络表单应用程序?
Then probably better to start using asp.net controls.那么最好开始使用 asp.net 控件。 They work MUCH better with your code behind.他们在你的代码后面工作得更好。
So, say this simple markup:所以,说这个简单的标记:
<div id="MyUpLoadArea" runat="server">
<asp:FileUpload ID="FileUpLoad1" runat="server" onchange="ShowImagePreview(this);"
AllowMultiple="True" accept="image/*" style="float:left" />
<asp:Image ID="ImgPrv" Width="160px" runat="server" style="float:left"/>
<div style="clear:both;height:20px"></div>
<asp:Button ID="cmdUpLoad" runat="server" Text="Up-Load" CssClass="btn" OnClick="cmdUpLoad_Click" />
<script>
function ShowImagePreview(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#<%=ImgPrv.ClientID%>').prop('src', e.target.result)
};
reader.readAsDataURL(input.files[0]);
}
}
</script>
</div>
So, when we select say 4 files, it displays the first one, and we have this:所以,当我们 select 说 4 个文件时,它显示第一个文件,我们有这个:
So, in above, we have a standard asp.net button we have to click to up-load the files.因此,在上面,我们有一个标准的 asp.net 按钮,我们必须单击以上传文件。
The code for that can say be this:代码可以这样说:
protected void cmdUpLoad_Click(object sender, EventArgs e)
{
string strSQL = "";
SqlCommand cmdSQL;
foreach (HttpPostedFile OneFile in FileUpLoad1.PostedFiles)
{
string strSaveFile = Server.MapPath("~/UpLoadFiles/");
strSaveFile += OneFile.FileName;
OneFile.SaveAs(strSaveFile);
// now add this row to data base
strSQL = "INSERT INTO MyUpLoadFiles (FileName, Size, UpLoadTime, User_ID, SavePath) " +
"VALUES (@FileName, @Size, @UpLoadTime, @User_ID, @SavePath)";
cmdSQL = new SqlCommand(strSQL);
cmdSQL.Parameters.Add("@FileName", SqlDbType.NVarChar).Value = OneFile.FileName;
cmdSQL.Parameters.Add("@Size", SqlDbType.Int).Value = OneFile.ContentLength;
cmdSQL.Parameters.Add("@UpLoadTime", SqlDbType.DateTime).Value = DateTime.Now;
cmdSQL.Parameters.Add("@User_ID", SqlDbType.Int).Value = Session["User_ID"];
cmdSQL.Parameters.Add("@SavePath", SqlDbType.NVarChar).Value = "~/UpLoadFiles/" + OneFile.FileName;
General.MyRstE(cmdSQL);
}
// ALL files saved, display the grid of up-loaded files
strSQL = @"SELECT * FROM MyUpLoadFiles
WHERE User_ID = " + Session["User_ID"].ToString() +
" ORDER BY UpLoadTime DESC ";
cmdSQL = new SqlCommand(strSQL);
DataTable rstFiles = General.MyRstP(cmdSQL);
GridView1.DataSource = rstFiles;
GridView1.DataBind();
MyUpLoadArea.Style.Add("display", "none"); // hide up-load area
MyFileView.Style.Add("display", "normal"); // show file grid
}
so, we send/save all files to the folder MyUpLoadFiles.因此,我们将所有文件发送/保存到文件夹 MyUpLoadFiles。
We save each file into a database - so we can list them out later, and show ONLY the one users file(s).我们将每个文件保存到数据库中 - 这样我们以后可以将它们列出来,并且只显示一个用户文件。
So, right below the above div and markup, I have a gridview, like this:因此,在上述 div 和标记的正下方,我有一个 gridview,如下所示:
<div id="MyFileView" runat="server">
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns = "False" ShowHeaderWhenEmpty="true" CssClass="table"
width="50%" >
<Columns>
<asp:BoundField DataField="FileName" HeaderText="FileName" />
<asp:BoundField DataField="UpLoadTime" HeaderText="UpLoaded" />
<asp:TemplateField HeaderText="Preview" ItemStyle-HorizontalAlign="Center" >
<ItemTemplate>
<asp:Image ID="Image1" runat="server" width="120px"
ImageUrl = '<% # Eval("SavePath") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Download" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Button ID="cmdDownLoad" runat="server" Text="Download" CssClass="btn" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
So, now when I hit up-load button, I get/see this:所以,现在当我点击上传按钮时,我得到/看到这个:
We of course need to wire up a event for the download button.我们当然需要为下载按钮连接一个事件。
Say, this:说这个:
<asp:Button ID="cmdDownLoad" runat="server" Text="Download" CssClass="btn"
OnClick="cmdDownLoad_Click" />
And that code could be:该代码可能是:
protected void cmdDownLoad_Click(object sender, EventArgs e)
{
Button myBut = sender as Button;
GridViewRow gRow = myBut.NamingContainer as GridViewRow;
string strFileOnly = gRow.Cells[0].Text;
string strFile = "";
strFile = Server.MapPath(@"~/UpLoadFiles/" + strFileOnly);
string sMineType = MimeMapping.GetMimeMapping(strFileOnly);
Response.ContentType = sMineType;
Response.AppendHeader("Content-Disposition", "attachment; filename=" + strFileOnly);
Response.TransmitFile(strFile);
Response.End();
}
I also have two helper routines MyRstP and MyRstE - they are just some general code routines I have (became VERY tired of typing code over and over to get a simple conneciton string setup, and then execute some code to return a table, or to execute some sql code. So, those two routines were this:我还有两个辅助例程 MyRstP 和 MyRstE - 它们只是我拥有的一些通用代码例程(非常厌倦一遍又一遍地键入代码以获得简单的连接字符串设置,然后执行一些代码以返回表,或执行一些 sql 代码。所以,这两个例程是这样的:
public static DataTable MyRstP(SqlCommand cmdSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (cmdSQL)
{
cmdSQL.Connection = conn;
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
public static void MyRstE(SqlCommand cmdSQL)
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (cmdSQL)
{
cmdSQL.Connection = conn;
conn.Open();
cmdSQL.ExecuteNonQuery();
}
}
}
Not really much important - but the above two routines are handy, and thus I don't type that code over and over for simple and general data operations.不是很重要——但上面的两个例程很方便,因此我不会一遍又一遍地输入代码来进行简单和通用的数据操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.