iT邦幫忙

0

關於ASP NET Core 6 MVC 圖片上傳的問題

  • 分享至 

  • xImage

各位大大好 小弟是最近開始學ASP NET 的新手
目前在嘗試用 Core 6 MVC 製作一個簡易網站
但有一個問題 始終找不到無法解決辦法

就是在製作一個類似最新消息的單元
有標題+簡述+日期+內容+圖片上傳的功能

第一次 在欄位全填的情況下 都很正常
但第二次開始 只要圖片欄位 沒有選擇圖片
就會跳出
The pic1(圖片欄位名稱) field is required.的錯誤
但在Models中 我並未將該圖片欄位設定為必填

附上程式碼 希望各位大大能幫助小弟

以下為view

@model TestMvc.Models.News

@{

    ViewData["Title"] = "Edit";
}

<h4>Edit: News</h4>
<hr />
<div class="row">
    <div class="col-md-8">
    <form asp-action="Edit" enctype="multipart/form-data">
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <input type="hidden" asp-for="id" />

        <div class="form-group row">
            <label class="col-sm-3 col-form-label">標題</label>
            <div class="col-sm-9">
                <input asp-for="topic" class="form-control" id="topic" type="text" value="@Model.topic"/>
                <span asp-validation-for="topic" class="text-danger"></span>
            </div>
        </div>
        <div class="form-group row">
            <label class="col-sm-3 col-form-label">簡述</label>
            <div class="col-sm-9">
                <input asp-for="field_tmp" class="form-control" id="field_tmp" type="textarea" value="@Model.field_tmp"/>
                <span asp-validation-for="field_tmp" class="text-danger"></span>
            </div>
        </div>
        <div class="form-group row">
            <label class="col-sm-3 col-form-label">日期</label>
            <div class="col-sm-9">
                @Html.EditorFor(m => m.update_time ,new { htmlAttributes = new { @class = "form-control" } })
                <span asp-validation-for="update_time" class="text-danger"></span>
            </div>
        </div>
        <hr>
        <div class="form-group row">
            <label class="col-sm-3 col-form-label">圖片上傳</label>
            <div class="col-sm-9">
                <input type="file" asp-for="pic1" class="form-control" value="@Model.pic1"/>
                <span asp-validation-for="pic1" class="text-danger"></span>
                @if(String.IsNullOrEmpty(@Model.pic1)){
                    
                }else{
                    <img src="~/upload/news/@Model.pic1">
                }
                
            </div>
                
        </div>
        <hr>
        <div class="form-group row">
            <label class="col-sm-3 col-form-label">內容</label>
            <div class="col-sm-9">
                <textarea asp-for="detail" class="form-control" id="editor"></textarea>
                <span asp-validation-for="detail" class="text-danger"></span>
            </div>
        </div>
        <!-- <div class="form-group row">
            <label class="col-sm-3 col-form-label">內容</label>
            <div class="col-sm-9">
                @Html.EditorFor(m => m.detail)
                <span asp-validation-for="detail" class="text-danger"></span>
            </div>
        </div> -->
        <input asp-for="is_enable" type="hidden"/>
        <input asp-for="ml_key" type="hidden"/>

        <div class="form-group row">
            <label class="col-sm-3 col-form-label"></label>
            <div class="col-sm-9">
                <input type="submit" value="Update" class="btn btn-primary" />
            </div>
        </div>
    </form>
    </div>
    </div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

以下為Controller

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Edit(long id,News news,IFormFile pic1)
    {
        if (id != news.id)
        {
            return NotFound();
        }

        if (ModelState.IsValid)
        {
            try
            {            
                if(pic1.Length > 0){   
                    string pic_path="wwwroot/upload/news/";                                 
                    var fileOriginName = Path.GetFileName(pic1.FileName);//抓檔名
                    var fileExt = Path.GetExtension(fileOriginName);//從檔名抓附檔名
                    
                    var fileName=DateTime.Now.ToString("yyyyMMdd")+news.id+fileExt;//從新命名 日期+ID+附檔名
                    using(var stream=System.IO.File.Create(pic_path+fileName)){
                        pic1.CopyTo(stream);
                    }
                    news.pic1=fileName;
                }
                _context.Update(news);
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!CategoryExists(news.id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }
            return RedirectToAction(nameof(Index));
        }else{
            
            _context.Update(news);
            await _context.SaveChangesAsync();
        }
        
        return View(news);
    }

以下為Models

public class News
    {
        public Int64 id { get; set; }
        [Required]
        public string? topic { get; set; }
        [Required]
        public string? field_tmp { get; set; }

        public DateTime? update_time { get; set; }

        public string? ml_key { get; set; }

        public Int64? sort_id { get; set; }

        public Int64? is_enable { get; set; }
    
        public string? pic1 { get; set; }

        public string? detail { get; set; }

        
    }
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
1
johncoc
iT邦新手 3 級 ‧ 2022-12-20 17:20:56
最佳解答

應該是 IFormFile pic1 沒有初始化導致這個錯誤(default 為 null)
在 ModelState.IsValid 前面初始化 pic1 可解決這個問題
建議名稱不要取一樣的,容易造成混淆

感謝大大的提示,把前台圖片上傳的欄位名稱改掉後,就可以正常了

0
jack8900
iT邦新手 2 級 ‧ 2022-12-20 16:48:23
//應該是這邊錯
if(pic1.Length > 0)
//可以改用這個判斷,然後才判斷圖片大小
if(pic1!=null)

如果沒有圖片,這邊應該會報錯吧?
偵錯的時候逐行檢視會比較好找錯誤點~

感謝大大回覆 不過 我有測試過了是在上一行的判斷時報錯的

if (ModelState.IsValid){

還未執行到下面的

if(pic1.Length > 0)
0
科科
iT邦研究生 1 級 ‧ 2022-12-21 12:35:21
asp-validation-for="pic1"

這個拿掉試試

感謝大大回覆,不過拿掉還是有問題,按照樓上johncoc大大說的,改掉前台欄位名稱,就可以了

我要發表回答

立即登入回答