简体   繁体   中英

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

        <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

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. 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:

在此处输入图像描述

So, in above, we have a standard asp.net button we have to click to up-load the files.

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.

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 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:

    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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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