文件上傳到數據庫與下載


基於 FinUICore,實現文件上傳到數據庫與下載

最終效果如圖:

功能實現:
1、表單有兩個上傳字段,用於上傳2個文件;

2、點 “瀏覽”選擇錯誤的文件,可通過 “刪除->重置上傳控件” 重置;

3、點“保存並關閉” 保存數據並上傳文件;

4、重新打開工序報工,可編輯(已保存的表單數據和文件名會重新顯示到頁面)。如果已上傳文件,則上傳控件后的 “下載” 和 “刪除->刪除” 按鈕可用;

5、編輯狀態,如上傳控件重選文件,“保存並關閉”則會覆蓋原文件;

6、點 “刪除->刪除”,可刪除文件,不需要點保存即刪除(刪除前提示確認);刪除成功后,控件中的文件名清除、 “下載” 和 “刪除->刪除” 按鈕不可用;

以下介紹實現步驟:

一、創建模型

 

public class R_QC: IKeyID
    {
        [Key]
        public int ID { get; set; }

        [Display(Name ="PO工序")]
        [Required]
        public int POProcID { get; set; }
        public B03_POProc B03_POProc { get; set; }

        [Display(Name ="送檢人員")]
        public int? SQCID { get; set; }
        public User SQC { get; set; }

        [Display(Name ="檢驗人員")]
        public int? QCID { get; set; }
        public User QC { get; set; }

        [Display(Name ="計划檢完時間")]
        public DateTime? PFinishTime { get; set; }

        [Display(Name = "開始檢驗時間")]
        public DateTime? StartTime { get; set; }

        [Display(Name = "完成檢驗時間")]
        public DateTime? EndTime { get; set; }

        [Display(Name = "檢驗結果")]
        [StringLength(50)]
        public string QCResult { get; set; }

        [Display(Name = "檢驗單上傳")]
        [StringLength(200)]
        public string QCReport { get; set; }

        [Display(Name = "檢驗單上傳")]
        public byte[] QCReportContent { get; set; }

        [Display(Name = "拍照留底")]
        [StringLength(200)]
        public string Photo { get; set; }
        [Display(Name = "拍照留底")]
        public byte[] PhotoContent { get; set; }

        [Display(Name = "備注")]
        [StringLength(500)]
        public string Remark { get; set; }

        [Display(Name = "操作人")]
        public int OperatorID { get; set; }
        public User Operator { get; set; }

        [Display(Name = "狀態")]
        public int StatusID { get; set; }
        public A07_Statu A07_Statu { get; set; }

        [Display(Name = "創建時間")]
        public DateTime? CreateTime { get; set; }
    }

 

生成的數據表如下圖,其中,2個紅框為兩個文件記錄字段,一個字段記錄文件名,一個字段存儲文件。

 

二、前端界面設計

1、為了實現“上傳控件”、“刪除”、“下載” 按鈕在同一行,需要為  <f:FormRow > 控件標簽增加  ColumnWidths="100%"  屬性。

 2、在上傳控件后面添加一組菜單按鈕,包含  “重置上傳控件” 和 “刪除”兩個菜單按鈕。

  • 重置上傳控件:點擊上傳控件的瀏覽按鈕,且選擇文件后,可能需要取消選擇(不是重選,是取消、不想上傳了),可使用該按鈕重置、取消選擇;方法是為 “重置上傳控件” 按鈕指定JS,通過 reset() 方法重置。
  • 刪除:編輯時,可能需要將已上傳文件刪除;按鈕執行JS,JS彈框提示,點OK后,觸發后台事件刪除;”刪除“ 代碼見 “四、文件下載與文件刪除”

 

@page
@model XXX.Pages.WH.R_QCModel
@{
    ViewData["Title"] = "R_QC";
    var F = Html.F();
}

@section head {

}

@section body{

    <f:Panel ID="Panel1" ShowBorder="false" ShowHeader="false" AutoScroll="true" IsFluid="true" IsViewPort="true">
        <Toolbars>
            <f:Toolbar ID="Toolbar1" Position="Top" ToolbarAlign="Left">
                <Items>
                    <f:Button ID="btnClose" Icon="SystemClose" Text="關閉">
                        <Listeners>
                            <f:Listener Event="click" Handler="F.activeWindow.hide();"></f:Listener>
                        </Listeners>
                    </f:Button>
                    <f:ToolbarSeparator></f:ToolbarSeparator>
                    <f:Button ID="btnSaveClose" ValidateForms="SimpleForm1" OnClickFields="SimpleForm1" Icon="SystemSaveClose" OnClick="@Url.Handler("BtnSaveClose_Click")" Text="保存后關閉"></f:Button>
                    <f:ToolbarSeparator></f:ToolbarSeparator>
                    <f:Button ID="btnFinishClose" ValidateForms="SimpleForm1" OnClickFields="SimpleForm1" IconFont="Check" OnClick="@Url.Handler("BtnSaveClose_Click")" Text="完工關閉"></f:Button>
                </Items>
            </f:Toolbar>
        </Toolbars>
        <Items>
            <f:Form ID="SimpleForm1" ShowBorder="false" ShowHeader="false" BodyPadding="10" LabelWidth="110">
                <Rows>
                    <f:FormRow>
                        <Items>
                            <f:DropDownList For="currentR_QC.SQCID" DataTextField="ChineseName" AutoSelectFirstItem="false" DataSource="@Model.Users"
                                            DataValueField="ID" EmptyText="請選擇人員..." EnableEdit="true"></f:DropDownList>                            
                            <f:HiddenField ID="currentR_QCID" Text="@Model.currentR_QCID"></f:HiddenField>
                            <f:HiddenField ID="currentR_QCRProcID" Text="@Model.SelectedNodesID"></f:HiddenField>
                        </Items>
                    </f:FormRow>
                    <f:FormRow>
                        <Items>
                            <f:DropDownList For="currentR_QC.QCID" DataTextField="ChineseName" AutoSelectFirstItem="false" DataSource="@Model.Users"
                                            DataValueField="ID" EmptyText="請選擇人員..." EnableEdit="true"></f:DropDownList>
                        </Items>
                    </f:FormRow>
                    <f:FormRow>
                        <Items>
                            <f:TriggerBox For="currentR_QC.PFinishTime" EmptyText="請選擇時間" TriggerIcon="Date" CssClass="dtime"></f:TriggerBox>
                        </Items>
                    </f:FormRow>
                    <f:FormRow>
                        <Items>
                            <f:TriggerBox For="currentR_QC.StartTime" EmptyText="請選擇時間" TriggerIcon="Date" CssClass="dtime"></f:TriggerBox>
                        </Items>
                    </f:FormRow>
                    <f:FormRow>
                        <Items>
                            <f:TriggerBox For="currentR_QC.EndTime" EmptyText="請選擇時間" TriggerIcon="Date" CssClass="dtime">
                            </f:TriggerBox>
                        </Items>
                    </f:FormRow>
                    <f:FormRow>
                        <Items>
                            <f:TextBox For="currentR_QC.QCResult"></f:TextBox>
                        </Items>
                    </f:FormRow>
                    <f:FormRow ColumnWidths="100%">
                        <Items>
                            <f:FileUpload ID="QCReportContent" Label=檢驗單上傳 AcceptFileTypes="image/*" ButtonIcon="Add" Text="@Model.QCReport"></f:FileUpload>
                            <f:Button ID="btDelete" Icon="Delete" Text="刪除...">
                                <Menu>
                                    <f:MenuButton ID="rsQCReportContent" Text="重置上傳控件" IconFont="Repeat">
                                        <Listeners>
                                            <f:Listener Event="click" Handler="reSetQCReportContent();"></f:Listener>
                                        </Listeners>
                                    </f:MenuButton>
                                    <f:MenuButton ID="mbtDeleteQ" Text="刪除" Enabled="@Model.btQCReport" IconFont="Remove">
                                        <Listeners>
                                            <f:Listener Event="click" Handler="reMoveFile('Q');"></f:Listener>
                                        </Listeners>
                                    </f:MenuButton>
                                </Menu>
                            </f:Button>
                            <f:Button ID="btDownloadQCRep" IconFont="Download" Text="下載" Enabled="@Model.btQCReport">
                                <Listeners>
                                    <f:Listener Event="click" Handler="downLoad('QCReport');"></f:Listener>
                                </Listeners>
                            </f:Button>
                        </Items>
                    </f:FormRow>
                    <f:FormRow ColumnWidths="100%">
                        <Items>
                            <f:FileUpload ID="PhotoContent" Label="拍照留底" AcceptFileTypes="image/*" ButtonIcon="Add" Text="@Model.Photo"></f:FileUpload>
                            <f:Button ID="btDelete" Icon="Delete" Text="刪除...">
                                <Menu>
                                    <f:MenuButton ID="rsPhotoContent" Text="重置上傳控件" IconFont="Repeat">
                                        <Listeners>
                                            <f:Listener Event="click" Handler="reSetPhotoContent();"></f:Listener>
                                        </Listeners>
                                    </f:MenuButton>
                                    <f:MenuButton ID="mbtDeleteP" Text="刪除" Enabled="@Model.btPhoto" IconFont="Remove">
                                        <Listeners>
                                            <f:Listener Event="click" Handler="reMoveFile('P');"></f:Listener>
                                        </Listeners>
                                    </f:MenuButton>
                                </Menu>                                
                            </f:Button>
                            <f:Button ID="btDownloadPhoto" IconFont="Download" Text="下載" Enabled="@Model.btPhoto">
                                <Listeners>
                                    <f:Listener Event="click" Handler="downLoad('Photo');" ></f:Listener>
                                </Listeners>
                            </f:Button>
                        </Items>
                    </f:FormRow>
                    <f:FormRow>
                        <Items>
                            <f:TextArea For="currentR_QC.Remark" AutoGrowHeight="true" EmptyText="最多500字"></f:TextArea>
                        </Items>
                    </f:FormRow>
                </Rows>
            </f:Form>
        </Items>
    </f:Panel>
}

@section script {
<script src="~/res/third-party/layDate-v5.2.0\laydate\laydate.js" type="text/javascript"></script> <script> function reSetPhotoContent() { var f = F.ui.PhotoContent; f.reset(); } function reSetQCReportContent() { var f = F.ui.QCReportContent; f.reset(); } function reMoveFile(actionType) { F.confirm({ message: '確定刪除此文件嗎?', target: '_top', ok: function () { // 觸發后台事件 F.doPostBack('@Url.Handler("RemoveFile")', 'SimpleForm1',{ actionType: actionType }); } }); } function downLoad(button) { var id = F.ui.currentR_QCID.value; window.location.href = '@Url.Content("~/WH/DownLoad?ID=")' + id + "&button=" + button + "&station=R_QC" ; } F.ready(function () { lay('.dtime').each(function () { laydate.render({ elem: this.getElementsByTagName('input')[0] //this.getElementsByTagName('input')[0] //this.childNodes[1].childNodes[0].childNodes[0] //兩種方法均可定位到input元素; , eventElem: this.getElementsByTagName('i')[0] , type: 'datetime' //datetime, , show: false //, trigger: 'click' //, closeStop: '#tbxMyBox-inputEl' , position: 'abolute' //默認值:absolute,絕對定位,始終吸附在綁定元素周圍; fixed固定定位,初始吸附在綁定元素周圍,不隨瀏覽器滾動條所左右。 , zIndex: 10029 // , theme: 'molv' , calendar: true }); }); }); </script> }

三、數據初始化及上傳

1、頁面初始化
下載、刪除按鈕默認不可用;如果記錄已存在,上傳控件顯示文件名,並將下載、刪除按鈕設置為可用。

public class R_QCModel : BaseAdminModel
    {
        [BindProperty]
        public R_QC currentR_QC { get; set; }
        public IEnumerable<User> Users { get; set; }     //檢驗員、送檢員下拉列表;
        public int SelectedNodesID { get; set; }           //選擇的工序ID
        public int currentR_QCID { get; set; }
        public string Photo { get; set; }                //文件名稱
        public string QCReport { get; set; }              //文件名稱
        public bool btPhoto { get; set; }                 //下載、刪除按鈕是否啟用;
        public bool btQCReport { get; set; }              //下載、刪除按鈕是否啟用;

        private readonly long _fileSizeLimit=299999;
        private readonly string[] _permittedExtensions = { ".txt",".png" ,".jpeg", ".jpg",".gif" };



        public async Task<IActionResult> OnGetAsync(int proc)
        {
            //下載、刪除按鈕默認不可用;
            btPhoto = false;
            btQCReport = false;

            // 如果記錄已存在,上傳控件顯示文件名,並將下載、刪除按鈕設置為可用;
            R_QC _currentR_QC = new R_QC();
            _currentR_QC = await DB.R_QC.Include(q => q.SQC).Include(q => q.QC).
            Where(p => p.POProcID == proc).FirstOrDefaultAsync();

            if (_currentR_QC != null)
            {
                currentR_QC = _currentR_QC;
                QCReport=_currentR_QC.QCReport;
                Photo= _currentR_QC.Photo;
                currentR_QCID = _currentR_QC.ID;

                if (_currentR_QC.QCReportContent!=null)
                {
                    btQCReport = true;
                }
                if (_currentR_QC.PhotoContent!=null)
                {
                    btPhoto = true;
                }

            }
            SelectedNodesID = proc;
            Users = await DB.Users.ToListAsync();            
            return Page();
        }
    }

2、數據、文件上傳后端代碼

 public async Task<IActionResult> OnPostBtnSaveClose_ClickAsync(string currentR_QCRProcID, string currentR_QCID, List<IFormFile> QCReportContent,List<IFormFile> PhotoContent)
        {
            //ModelState.Remove("currentR_QC.ID");

            if (ModelState.IsValid)
            {                
                
                var _r = await DB.R_QC.Include(q => q.SQC).Include(q => q.QC).Where(q=>q.ID== Convert.ToInt32(currentR_QCID)).SingleOrDefaultAsync();

                //_r 不為空,則更新;
                if (_r != null)
                {
                    if (await TryUpdateModelAsync<R_QC>(_r, "currentR_QC"
                        ,r => r.SQCID
                        , r => r.QCID
                        ,r=>r.StartTime
                        ,r=>r.EndTime
                        ,r=>r.PFinishTime
                        ,r=>r.QCResult
                        ,r=>r.Remark
                        )
                        )
                    {
                        //文件
                        foreach (var formFile in QCReportContent)
                        {
                            var formFileContent =
                                await FileHelpers.ProcessFormFile<BufferedMultipleFileUploadDb>(
                                    formFile, ModelState, _permittedExtensions,
                                    _fileSizeLimit);

                            //// Perform a second check to catch ProcessFormFile method
                            //// violations. If any validation check fails, return to the
                            //// page.
                            if (!ModelState.IsValid)
                            {
                                //Alert.Show( "請上傳正確格式的文件!");
                                return UIHelper.Result();
                            }

                            _r.QCReportContent = formFileContent;
                            _r.QCReport = formFile.FileName;
                        }
                        foreach (var formFile in PhotoContent)
                        {
                            var formFileContent =
                                await FileHelpers.ProcessFormFile<BufferedMultipleFileUploadDb>(
                                    formFile, ModelState, _permittedExtensions,
                                    _fileSizeLimit);

                            if (!ModelState.IsValid)
                            {
                                //Alert.Show( "請上傳正確格式的文件!");
                                return UIHelper.Result();
                            }

                            _r.PhotoContent = formFileContent;
                            _r.Photo = formFile.FileName;
                        }
                    } 
                }
                else  //如果記錄不存在,則新增記錄;
                {
                    currentR_QC.POProcID = Convert.ToInt32(currentR_QCRProcID);
                    currentR_QC.OperatorID = (int)GetIdentityID();
                    currentR_QC.CreateTime = DateTime.Now;
                    currentR_QC.StatusID = 6;

                    foreach (var formFile in QCReportContent)
                    {
                        var formFileContent =
                               await FileHelpers.ProcessFormFile<BufferedMultipleFileUploadDb>(
                                   formFile, ModelState, _permittedExtensions,
                                   _fileSizeLimit);

                        if (!ModelState.IsValid)
                        {
                            //Alert.Show( "請上傳正確格式的文件!");
                            return UIHelper.Result();
                        }

                        currentR_QC.QCReportContent = formFileContent;
                        currentR_QC.QCReport = formFile.FileName;
                    }

                    foreach (var formFile in PhotoContent)
                    {
                        var formFileContent =
                            await FileHelpers.ProcessFormFile<BufferedMultipleFileUploadDb>(
                                formFile, ModelState, _permittedExtensions,
                                _fileSizeLimit);

                        if (!ModelState.IsValid)
                        {
                            //Alert.Show( "請上傳正確格式的文件!");
                            return UIHelper.Result();
                        }

                        currentR_QC.PhotoContent = formFileContent;
                        currentR_QC.Photo = formFile.FileName;
                    }

                    DB.R_QC.Add(currentR_QC);
                }
                await DB.SaveChangesAsync();
                // 關閉本窗體(觸發窗體的關閉事件)
                ActiveWindow.HidePostBack();
            }
            return UIHelper.Result();
        }

public class BufferedMultipleFileUploadDb { [Required] [Display(Name = "File")] public List<IFormFile> FormFiles { get; set; } [Display(Name = "Note")] [StringLength(50, MinimumLength = 0)] public string Note { get; set; } }

四、文件下載及文件刪除

 1、文件下載后端代碼

文件下載,采用跳轉頁面方式進行。

  • 創建下載頁面,頁面名稱:Download.cshtml
@page
@model XXX.Pages.WH.DownloadModel

@section body{ 
<h2>下載出錯,文件不存在或已被刪除!</h2>
}
public class DownloadModel : BaseAdminModel
    {
        public async Task<IActionResult> OnGetAsync(int ID,string station,string button)
        {
            if (ID != 0)
            {
                if (station == "R_QC")
                {
                    var requestFile = await DB.R_QC.SingleOrDefaultAsync(q => q.ID == ID);
                    if (requestFile == null)
                    {
                        return Page();
                    }

                    if (button == "Photo")
                    {
                        if (requestFile.PhotoContent == null)
                        {
                            return Page();
                        }
                        return File(requestFile.PhotoContent, MediaTypeNames.Application.Octet, requestFile.Photo);
                    }
                    if (button == "QCReport")
                    {
                        if (requestFile.QCReportContent == null)
                        {
                            return Page();
                        }
                        return File(requestFile.QCReportContent, MediaTypeNames.Application.Octet, requestFile.QCReport);
                    }
                }

                else if (button == "R_QC_Photo")
                {

                }

            }

            return Page();
        }
    }
  • 執行下載

2、文件刪除后端代碼

 //刪除已上傳的文件
        public async Task<IActionResult>OnPostRemoveFileAsync(string actionType,string currentR_QCID)
        {
            var _r = await DB.R_QC.Where(p => p.ID == Convert.ToInt32(currentR_QCID)).SingleOrDefaultAsync();
            if (_r == null)
            {
                Alert.Show("文件已刪除!");
                return UIHelper.Result();
            }

            if (actionType == "Q")
            {
                _r.QCReportContent = null;
                _r.QCReport = null;
                //更新前端控件
                UIHelper.FileUpload("QCReportContent").Text("");
                UIHelper.Button("btDownloadQCRep").Enabled(false);
                UIHelper.MenuButton("mbtDeleteQ").Enabled(false);
            }
            if (actionType == "P")
            {
                _r.PhotoContent = null;
                _r.Photo = null;
                //更新前端控件
                UIHelper.FileUpload("PhotoContent").Text("");
                UIHelper.Button("btDownloadPhoto").Enabled(false);
                UIHelper.MenuButton("mbtDeleteP").Enabled(false);
            }

            await DB.SaveChangesAsync();            
            return UIHelper.Result();
        }

以上是本文全部內容。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM