多附件上傳控制項

来源:http://www.cnblogs.com/lxc89/archive/2016/06/13/5580181.html
-Advertisement-
Play Games

以前寫過一篇《單頁面多類型的多附件上傳》的文章,但是在實際項目中,這樣的並不多見,相比之下,多附件上傳卻經常用到。 而每次使用都要複製粘貼相關的代碼,雖然不麻煩,但用起來卻不太方便,一旦忘記某段代碼沒複製過來,頁面就會報錯。 於是,就想把現在用的這些代碼,變成一個用戶自定義控制項,這樣再次使用的時候就 ...


以前寫過一篇《單頁面多類型的多附件上傳》的文章,但是在實際項目中,這樣的並不多見,相比之下,多附件上傳卻經常用到。

而每次使用都要複製粘貼相關的代碼,雖然不麻煩,但用起來卻不太方便,一旦忘記某段代碼沒複製過來,頁面就會報錯。

於是,就想把現在用的這些代碼,變成一個用戶自定義控制項,這樣再次使用的時候就方便多了。

話不多說,先看下界面吧。

設計時

運行後

先介紹下控制項界面,上下一共有兩個repeater,分別用於編輯和查看時使用。上面的repeater,帶有刪除按鈕,用於編輯時可以刪除不需要的附件;下麵的repeater,用於查看時使用,如果沒有上傳附件,則後臺代碼會給控制項Literal賦值空格符( ),用於解決瀏覽器相容問題(因為有些瀏覽器在表格行沒有數據時,邊框線不顯示)。

中間的上傳控制項,不用多說,用於上傳附件;後面的“添加”按鈕,點擊後,會調用JS代碼動態創建上傳控制項,以便能夠上傳多個附件;下麵的隱藏控制項,前期用於記錄創建的上傳控制項個數,點擊“提交”按鈕後用於保存上傳的附件路徑,以便數據保存失敗時刪除附件。

 

下麵我們來看下前臺的html代碼。

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="AttaUpload.ascx.cs"
    Inherits="WEB.webcontrols.AttaUpload" %>
<script src="../js/AttaUpload.js" type="text/javascript"></script>
<div id="tabEdit" runat="server">
    <asp:Repeater ID="rpFileE" runat="server" OnItemCommand="rpFile_ItemCommand">
        <ItemTemplate>
            <div>
                <asp:LinkButton ID="lbn_load" CommandArgument='<%#Eval("ID") %>' CommandName="load"
                    runat="server" Style="line-height: 25px"><%# Eval("FileName").ToString() + Eval("FileType").ToString()%></asp:LinkButton>&emsp;&emsp;&emsp;
                <asp:LinkButton ID="lbtn_del" Style="color: Blue" CommandArgument='<%#Eval("ID") %>'
                    CommandName="del" runat="server" OnClientClick='<%#"return DelMsg(\""+Eval("FileName").ToString() + Eval("FileType").ToString()+"\")" %>'>刪除</asp:LinkButton>
            </div>
        </ItemTemplate>
    </asp:Repeater>
    <div id="atta" runat="server">
        <asp:FileUpload ID="fufile" runat="server" onchange="if(this.value)JudgeFile(this.value,this);" />
        <asp:ImageButton ID="imgbtn_add" runat="server" src="../images/add.gif" Style="margin-bottom: -2px;" />
    </div>
    <asp:HiddenField ID="hffile" runat="server" Value="1" />
</div>
<div id="tabView" runat="server" visible="false">
    <asp:Repeater ID="rpFileV" runat="server" OnItemCommand="rpFile_ItemCommand">
        <ItemTemplate>
            <div>
                <asp:LinkButton ID="lbn_load" CommandArgument='<%#Eval("ID") %>' CommandName="load"
                    runat="server" Style="line-height: 25px"><%# Eval("FileName").ToString() + Eval("FileType").ToString()%></asp:LinkButton>
            </div>
        </ItemTemplate>
    </asp:Repeater>
    <asp:Literal ID="ltlfile" runat="server"></asp:Literal>
</div>
View Code

其中引用的AttaUpload.js文件,就是該控制項用到的所有JS代碼所在,裡面包含有動態創建上傳控制項,刪除附件提示,刪除動態創建的上傳控制項,判斷附件類型等等相關功能的JS編碼。

/**********動態添加上傳附件**********/
function AddAtta(id, hfid) {
    //var hfid = jQuery("#" + id).next().attr('id'); //document.getElementById(id).nextSibling.id;(IE10不相容)
    var d = document.createElement("div");
    var f = document.createElement("input");
    f.setAttribute("type", "file");
    f.setAttribute("name", "upfile");
    f.setAttribute("style", "margin-top:5px;");
    f.onchange = function () {
        if (this.value) JudgeFile(this.value, this);
    }
    d.appendChild(f);

    //添加刪除按鈕
    var im = document.createElement("img");
    im.setAttribute("src", "../images/close.gif");
    im.style.cssText = "margin-left:3px;margin-bottom: -2px;cursor:pointer";
    im.onclick = function () {
        document.getElementById(hfid).value = $val(hfid) - 1;
        return DelFile(this, "DIV");
    }
    d.appendChild(im);
    document.getElementById(id).appendChild(d);

    //添加計數
    document.getElementById(hfid).value = parseInt($val(hfid)) + 1;
    return false;
}

/**********刪除**********/
function DelFile(f, name) {
    while (f.tagName != name)
        f = f.parentNode;
    f.parentNode.removeChild(f);
    return false;
}

/**********判斷文件類型和大小**********/
function JudgeFile(file, node) {
    var typelist = ["txt", "doc", "xls", "ppt", "docx", "xlsx", "pptx", "pdf", "jpeg", "jpg", "png", "bmp", "gif"];
    if (file) {
        var match = 0;
        var suffix = file.split(".");
        var num = suffix.length - 1;
        var name = suffix[num].toLowerCase();
        for (var i = 0; i < typelist.length; i++) {
            if (name == typelist[i]) {
                match = 1;
                break;
            }
        }
        if (match != 1) {
            alert("暫不支持上傳該類型的文件,請重新選擇!");
            node.outerHTML = node.outerHTML;
        }
    }
    getFileSize(node);
}

//判斷文件大小
function getFileSize(obj) {
    var size = 0;
    if (navigator.userAgent.indexOf("MSIE") > 0) {
        try {
            var fso = new ActiveXObject('Scripting.FileSystemObject'); //獲取上傳文件的對象
            var file = fso.GetFile(obj.value);
            size = file.Size;
        }
        catch (err) {
            size = 0;
        }
    } else {
        size = obj.files[0].size;
    }
    if ((size / 1048576) > 40) {
        alert("上傳文件大於40M,無法上傳!");
        obj.outerHTML = obj.outerHTML;
    }
}


/**********刪除信息提示框**********/
function DelMsg(mess) {
    return confirm("系統提示:您確認刪除" + mess + "嗎?");
}
View Code


現在我們來看下控制項的後臺編碼:

1、參數:

/// <summary>
        /// 項目ID
        /// </summary>
        public string ProID
        {
            get
            {
                if (ViewState["AttaProID"] == null)
                {
                    return "";
                }
                else
                {
                    return (string)ViewState["AttaProID"];
                }
            }
            set
            {
                ViewState["AttaProID"] = value;
            }
        }

        /// <summary>
        /// 控制項ID
        /// </summary>
        public string WucID
        {
            get
            {
                if (ViewState["AttaWucID"] == null)
                {
                    return "AttaUp";
                }
                else
                {
                    return (string)ViewState["AttaWucID"];
                }
            }
            set
            {
                ViewState["AttaWucID"] = value;
            }
        }

        /// <summary>
        /// 查看或編輯(0:編輯;1:查看)
        /// </summary>
        public string Flag
        {
            get
            {
                if (ViewState["AttaFlag"] == null)
                {
                    return "0";
                }
                else
                {
                    return (string)ViewState["AttaFlag"];
                }
            }
            set
            {
                ViewState["AttaFlag"] = value;
            }
        }
View Code

2、頁面載入:

/// <summary>
/// 載入
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        imgbtn_add.Attributes.Add("onclick", "return AddAtta('" + WucID   + "_atta','" + WucID + "_hffile')");
        //頁面附件綁定
      if (ProID != "")
        {
            //讀取現有數據
        InitData();
        }
    }
}
View Code

  關於在後臺給“添加”按鈕綁定JS方法,是為了要把控制項的ID傳到前臺,否則“動態創建上傳控制項”和“保存累計個數”的方法就不能使用了。

  而如果id="atta"的div不加上runat="server"的話,那任何頁面就只能使用一次了。

3、綁定數據:

        /// <summary>
        /// 讀取數據
        /// </summary>
        private void InitData()
        {
            PrjFileEntity model = new PrjFileEntity();
            model.ProID = ProID;
            model.FileFlag = -2;
            DataView dv = PrjFileBLL.GetContact(model).DefaultView;
            if (Flag == "0")
            {
                // 編輯數據
                rpFileE.DataSource = dv;
                rpFileE.DataBind();
            }
            else
            {
                // 查看數據
                rpFileV.DataSource = dv;
                rpFileV.DataBind();
                tabEdit.Visible = false;
                tabView.Visible = true;
                if (dv == null || dv.Count <= 0)
                {
                    ltlfile.Text = "&nbsp;";
                }
            }
        }
View Code

4、保存附件:

        /// <summary>
        /// 保存附件
        /// </summary>
        /// <param name="proid"></param>
        public PrjFileEntity Save(int start, string path, string ucid)
        {
            int one = Convert.ToInt32(hffile.Value);
            PrjFileEntity filemodel = CommonFunction.FileUpLoad(start, one + start, hffile, path, ucid, (int)CommonEnum.FileFlag.上傳);
            if (filemodel.ID == "-2")
            {
                CommonFunction.delfile(hffile.Value.ToString());
                hffile.Value = "1";
                ShowMessages(filemodel.FileName);
                return null;
            }
            else
            {
                return filemodel;
            }
        }
View Code
        /// <summary>
        /// 項目文檔上傳文件
        /// </summary>
        /// <param name="start">起始值</param>
        /// <param name="end">終止值</param>
        /// <param name="hfcount">隱藏控制項</param>
        /// <param name="url">路徑(例:project/123)</param>
        /// <param name="ucid">用戶控制項ID(UserContronlID)</param>
        /// <param name="fileflag">附件標識(CommonEnum.FileFlag)</param>
        /// <returns></returns>
        public static PrjFileEntity FileUpLoad(int start, int end, HiddenField hfcount, string url, string ucid, int fileflag)
        {
            int upsize = 40000000;
            try
            {
                upsize = Convert.ToInt32(ConfigurationManager.AppSettings["upsize"].ToString());
            }
            catch (Exception)
            {
                upsize = 40000000;
            }

            //清空隱藏控制項的值,用於存放路徑
            if (hfcount != null)
            {
                hfcount.Value = "";
            }

            //設置上傳路徑
            string path = System.Web.HttpContext.Current.Server.MapPath("~/UpFile/" + url + "/");
            //判斷上傳文件夾是否存在,若不存在,則創建
            if (!Directory.Exists(path))
            {
                //創建文件夾
                Directory.CreateDirectory(path);
            }

            string attaname = "";
            string attaurl = "";
            string attatype = "";
            PrjFileEntity accessinfo = null;
            HttpFileCollection files = HttpContext.Current.Request.Files;
            for (int i = start; i < end; i++)
            {
                HttpPostedFile postedFile = files[i];
                if (postedFile.FileName != "")
                {
                    if (postedFile.ContentLength < upsize)
                    {
                        string[] name = postedFile.FileName.ToString().Split('\\');
                        //獲取擴展名
                        string extname = System.IO.Path.GetExtension(postedFile.FileName);
                        //獲取上傳文件的名稱
                        string oglname = name[name.Length - 1].ToString().Replace(extname, "");
                        //存儲上傳的文件名
                        attaname += oglname + ",";
                        attatype += extname + ",";

                        //為上傳的文件設置新的名稱,防止重名
                        string newname = System.DateTime.Now.ToString("yyyyMMddHHmmssffff") + i.ToString();
                        newname = newname + extname;

                        //設置完整的文件上傳路徑
                        string filepath = path + newname;
                        postedFile.SaveAs(filepath);
                        if (hfcount != null)
                        {
                            hfcount.Value += filepath + "$";
                        }
                        int j = filepath.IndexOf("UpFile");
                        string str = filepath.Substring(j - 1);

                        attaurl += "~" + str + ",";

                    }
                    else
                    {
                        accessinfo = new PrjFileEntity();
                        accessinfo.ID = "-2";
                        accessinfo.FileName = "上傳失敗,上傳文件不能大於" + upsize / 1000000 + "M!";
                        return accessinfo;
                    }
                }
            }

            attatype = attatype.TrimEnd(',');
            attaname = attaname.TrimEnd(',');
            attaurl = attaurl.TrimEnd(',');
            if (attaname != "" && attaurl != "" && attatype != "")
            {
                accessinfo = new PrjFileEntity(attatype, attaname, attaurl, ucid, fileflag);
            }
            else
            {
                accessinfo = new PrjFileEntity();
            }
            return accessinfo;
        }
View Code

5、刪除附件:

        /// <summary>
        /// 刪除附件
        /// </summary>
        public void Delete()
        {
            CommonFunction.delfile(hffile.Value.ToString());
            hffile.Value = "1";
        }
View Code

6、附件下載及刪除:

        /// <summary>
        /// 附件下載及刪除
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        protected void rpFile_ItemCommand(object source, RepeaterCommandEventArgs e)
        {
            string id = e.CommandArgument.ToString().Trim();
            PrjFileEntity fileinfo = PrjFileBLL.GetUniqueObj(id);
            string path = fileinfo.FilePath;

            if (e.CommandName.ToString() == "del")
            {
                path = HttpContext.Current.Server.MapPath(path);
                bool istrue = PrjFileBLL.Delete(id);
                if (istrue)
                {
                    //物理路徑的文件刪除
                    if (System.IO.File.Exists(path))
                    {
                        System.IO.File.Delete(path);
                    }
                    ShowMessages("刪除成功");
                    //InitData();
                    //表單附件綁定
                    if (WorkTaskInsID != "")
                    {
                        FormData();
                    }
                    //頁面附件綁定
                    else if (ProID != "")
                    {
                        //讀取現有數據
                        InitData();
                    }
                }
                else
                {
                    ShowMessages("刪除失敗");
                }
            }
            else
            {
                ShowScript("AttaView(\"" + id + "\",1)");
            }
        }
View Code

7、消息提醒:

        /// <summary>
        /// 消息提醒
        /// </summary>
        /// <param name="sMessage"></param>
        private void ShowMessages(string sMessage)
        {
            Page.ClientScript.RegisterStartupScript(this.GetType(), "Message", "<script>alert('系統提示:" + sMessage + "!');</script>");
            return;
        }
        /// <summary>
        /// 運行純腳本
        /// </summary>
        /// <param name="sMessage"></param>
        public void ShowScript(string script)
        {
            Page.ClientScript.RegisterStartupScript(GetType(), "", script, true);
        }
View Code

8、獲取隱藏控制項的計數:

        /// <summary>
        /// 獲取隱藏控制項的數值
        /// </summary>
        /// <returns></returns>
        public int GetHiddenCount()
        {
            return Convert.ToInt32(hffile.Value);
        }
View Code

  此方法在頁面調用兩個或兩個以上此控制項的時候使用。

 

最後看下調用:

1、在webconfig中註冊:

 <add src="~/webcontrols/AttaUpload.ascx" tagName="AttaUp" tagPrefix="wuc"/>

2、頁面前臺調用:

        <tr>
            <th>
                附件
            </th>
            <td colspan="3">
                <wuc:AttaUp ID="AttaUp" runat="server" />
            </td>
        </tr>

3、頁面載入時傳遞參數:

//附件
AttaUp.ProID = CID;
//查看時才傳,編輯時不需要
AttaUp.Flag = "1";

  至於控制項的WucID參數,再沒有修改控制項ID的情況下不需要傳遞,如果你把控制項的ID重命名了,例如改為“FileUpControl”時,則一定要傳遞,否則會報錯!!

4、提交頁面時調用:

 PrjFileEntity filemodel = AttaUp.Save(0, CommonFunction.GetProjectPath(hfproid.Value), "");

  第一參數“0”,表示是從第一個上傳控制項開始查找附件;如果有兩個上傳控制項,那麼第一個控制項保存附件時,傳“0”;第二個則要用第一控制項的GetHiddenCount()方法,獲取第一個控制項的上傳控制項個數;如果有第三個控制項,那就要“累加”第一個控制項和第二個控制項的GetHiddenCount()方法的返回值。以此類推!!

  註意:該方法只是返回了附件的實體類,多附件的每個屬性值都以逗號(,)隔開,詳情請仔細閱讀FileUpLoad()方法。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在WCF4.0里,通過提供一種虛擬的服務類型映射機制來實現WCF服務的激活。我們可以在配置文件里指定服務類型和相對地址之間的映射關係。這就使得我們可以在不是要.svc文件的情況下,在WAS/IIS里托管WCF服務程式。 ...
  • <esri:InfoWindow x:Name="InfoWinMF" Placement="TopRight" Padding="15" Map="{Binding ElementName=mainmap}" ContentTemplate="{StaticResource GeneralData ...
  • Lambda表達式 簡化了匿名委托的使用,讓你讓代碼更加簡潔,優雅。據說它是微軟自c#1.0後新增的最重要的功能之一。 首先來看一下其發展 根據上面的發展歷程,可以感到Lambda表達式愈加簡化。 詳細介紹: ...
  • 回到目錄 關於邏輯刪除 對於邏輯刪除之前的做法是在實體類中加個欄位,一般是status,其中一種狀態是刪除,當然也有其它做法,如加個bool的欄位IsDeleted,這些其實都過於武斷,即它在基類裡加上後,所以實體類都會有這種特性,而對於現實的數據表,可能不顯示這種邏輯刪除的特性,如關係表,日誌表, ...
  • 背水一戰 Windows 10 之 動畫: PopInThemeAnimation - 控制項出現時的動畫, PopOutThemeAnimation - 控制項消失時的動畫, FadeInThemeAnimation - 控制項淡入的動畫, FadeOutThemeAnimation - 控制項淡出的動畫... ...
  • 本文參考Roslyn項目中的Issue:#259. 1. C# 7.0 新特性1: 基於Tuple的“多”返回值方法 簡而言之,【本地方法】就是在方法體內部定義一個方法。 其實咋眼一看,這個新特新並沒有什麼新意,因為目前大量C#的項目中,都可以使用delegate或基於delegate變形的各種方案 ...
  • 如果一個頁面中有很長的列表/內容,很多應用都會在用戶向下滾動時隱藏頁面的頭,給用戶留出更多的閱讀空間,同時提供一個方便的吸頂工具欄,比如淘寶中的店鋪頁面。 下麵是一個比較簡單的實現,如果有同學有更好的實現,歡迎留言,讓我們共同進步。 首先假設我們的頁面整體包含3部分; 結構代碼如下,為了區別清楚,我 ...
  • 最近看到滿大街的二維碼掃碼有驚喜,對二維碼也有過一些瞭解,想看看到底是什麼原理,在網上找了一些資料,自己弄了一個實例,採用的是MVC,貼出來分享一下 一維碼生成 Controller 1 <div class="col-md-4"> 2 <h2>一維碼生成</h2> 3 <div><input ty ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...