简体   繁体   English

如何下载客户端在ASP.NET中上传的图像?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM