> For the complete documentation index, see [llms.txt](https://johch3n611u.gitbook.io/c50108/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://johch3n611u.gitbook.io/c50108/ju-li-cheng-bei/201906/untitled-16.md).

# 2019/0604/ASP.NET\_MVC Part2 PhotoSharing Controller & Filter & ADO.NET & View\@RAZOR Helper

\#MVC&#x20;Part2 ( 早上自習
------------------

## #02\_Controller

前情提要CodeFirst

### 現在要自己寫controller跟view&#xD;

#### ###回覆留言用Ajax方式 ( ??? &#xD;可能之後要做

ViewData帶去View就消失了

#### ##接著先做controller&#xD;

#### ###PhotosController.cs action create()&#xD;

新增留言

首先 新增一筆新增時間到view用於顯示

接著處理httppost

\[ ]可以用 , \[ , ]寫 但通常還是要同一組

HttpPostedFileBase利用此物件接image檔案

photo.ImageMimeType = image.ContentType;  抓副檔名

{% embed url="<https://www.google.com/search?q=InputStream&rlz=1C1GCEU_zh-TWTW835TW836&oq=InputStream&aqs=chrome..69i57j0l5.652j0j4&sourceid=chrome&ie=UTF-8>" %}

照片轉為byte陣列

存到模型後 存入資料庫 然後轉到index

那如果驗證不通過就停留在create

記得這裡也要餵今天日期不然抓不到

新增範本檢視再做更改 ( 覆蓋之前範本產生的

Bundle ?? 之後會講 可以把 庫弄成一包 ?在 app\_start bundle.config

下個單元才會自己寫view ?

接著寫

刪除確認畫面

比較特別無法做多載?

Get 部分做 例外回傳

Httppost 這裡如果 參數一樣是不能做多載的 那怎辦呢 ?

直接修改action頁面即可

補充\[ActionName("Delete")]

然後查找並刪除。

回到index

接著新增範本view 去做一些細部修改

後面要講錯處理的進階作法

### Controller 到此介紹完畢&#xD;

接著講View並把之前沒講到的補講

#### ###02\_Controller/PhotoSharing/Controllers/PhotosController.cs&#xD;

```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PhotoSharing.Models;
using PhotoSharing.DAL;
using System.Net;


namespace PhotoSharing.Controllers
{
    public class PhotosController : Controller
    {
        //2.2建立Data Context 來自 Photo Model 的 PhotoSharingContext 
        PhotoSharingContext context = new PhotoSharingContext();

        // GET: Photos
        //2.3-1 Index()回傳Photo
        public ActionResult Index()
        {
            ViewBag.Date = DateTime.Now;  //用ViewBag帶入今日日期
            return View(context.Photos.ToList());
        }

        //2.3-2 Display(int id) 透過id參數回傳Photo,若找不到回傳HttpNotFound()helper
        public ActionResult Display(int? id)
        {
            ViewData["Date"] = DateTime.Now; //用ViewData帶入今日日期
            if (id==null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            Photo photo = context.Photos.Find(id);
            if(photo==null)
            {
                return HttpNotFound();
            }

            return View("Display", photo);
        }
        //2.3-7 建立GetImage(int id)回傳File(photo.PhotoFile, photo.ImageMimeType)
        //這不是View()Helper的ActionResult, 這是File()helper
        public FileContentResult GetImage(int id)
        {
            Photo photo = context.Photos.Find(id);
            return File(photo.PhotoFile, photo.ImageMimeType);
        }

        //2.3-3 GET:Create() 產生新增Photo作業,並回傳 new Photo()並產生CreatedDate屬性值= DateTime.Today
        public ActionResult Create()
        {
            Photo newPhoto = new Photo();
            newPhoto.CreatedDate = DateTime.Today;
            
            return View("Create",newPhoto);
        }
        //2.3-4 Post:Create(Photo photo, HttpPostedFileBase image),使用HTTP POST,執行新增Photo回存作業,回傳RedirectToAction()helper
        //      如果ModelState.IsValid==false,回傳Photo給View, 反之執行新增Photo回存作業
        //      photo.ImageMimeType = image.ContentType;
        //      photo.PhotoFile = new byte[image.ContentLength];
        //      image.InputStream.Read(photo.PhotoFile, 0, image.ContentLength);
        [HttpPost,ValidateAntiForgeryToken]
        public ActionResult Create(Photo photo,HttpPostedFileBase image)
        {
            photo.CreatedDate = DateTime.Today;
            if(ModelState.IsValid)
            {
                //有post照片才做照片上傳的處理
                if (image!=null)
                {
                    photo.ImageMimeType = image.ContentType;  //抓照片型態
                    photo.PhotoFile = new byte[image.ContentLength];  //取得上傳照片的大小再轉byte陣列
                    image.InputStream.Read(photo.PhotoFile, 0, image.ContentLength);
                }
                context.Photos.Add(photo);
                context.SaveChanges();
                return RedirectToAction("Index");

            }
            else
            {
                return View("Create", photo);
            }


            
        }
        //2.3-5 Get:Delete(int id)產生刪除Photo作業,並回傳Photo(),若找不到回傳HttpNotFound()helper
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            Photo photo = context.Photos.Find(id);
            if (photo == null)
            {
                return HttpNotFound();
            }

            return View("Delete", photo);
        }
        //2.3-6 Post:建立DeleteConfirmed(int id)使用[ActionName("Delete")]屬性,透過HTTP POST,執行刪除Photo回存作業.回傳RedirectToAction()helper
        [HttpPost,ValidateAntiForgeryToken]
        [ActionName("Delete")]
        public ActionResult DeleteConfirmed(int? id)
        {
            Photo photo = context.Photos.Find(id);
            context.Photos.Remove(photo);
            context.SaveChanges();
            return RedirectToAction("Index");
        }


    }
}
```

#### ###老師講解

```
//2.1.加入 Empty MVC controller -> PhotoController(PhotoController.cs)
//2.2.建立Data Context 來自 Photo Model 的 PhotoSharingContext 
//2.3.建立action
//2.3-1 Index()回傳Photo
//2.3-2 Display(int id) 透過id參數回傳Photo,若找不到回傳HttpNotFound()helper
//2.3-3 Create() 產生新增Photo作業,並回傳 new Photo()並產生CreatedDate屬性值= DateTime.Today
//2.3-4 Create(Photo photo, HttpPostedFileBase image),使用HTTP POST,執行新增Photo回存作業,回傳RedirectToAction()helper
//      如果ModelState.IsValid==false,回傳Photo給View,反之執行新增Photo回存作業
//      photo.ImageMimeType = image.ContentType;
//      photo.PhotoFile = new byte[image.ContentLength];
//      image.InputStream.Read(photo.PhotoFile, 0, image.ContentLength);
//2.3-5 Delete(int id)產生刪除Photo作業,並回傳Photo(),若找不到回傳HttpNotFound()helper
//2.3-6 建立DeleteConfirmed(int id)使用[ActionName("Delete")]屬性,透過HTTP POST,執行刪除Photo回存作業.回傳RedirectToAction()helper
//2.3-7 建立GetImage(int id)回傳File(photo.PhotoFile, photo.ImageMimeType)(注意:File()helper 是FileContentResult,不是 View()helper 的ActionResult)


//2.4.建立Index及Display Views
//      Model Class:Photo (PhotoSharing.Models)
//      Data Context Class:PhotoSharingContext (PhotoSharing.DAL)
//2.4-1 Index View使用Scaffold template:List
//2.4-2 Display View使用Scaffold template:Details 


//2.5. 更改Index View
//2.5-1 取出ViewBag值
//2.5-2 註解:不顯示圖片
//2.5-3 在Index View(Index.cshtml)將ActionLink的Details改成Display


//2.6 更改Display View
//2.6-1 取出ViewData值
//2.6-2 在Display View(Display.cshtml)使用GetImage Action


//2.7.建立Delete Views
//      Model Class:Photo (PhotoSharing.Models)
//      Data Context Class:PhotoSharingContext (PhotoSharing.DAL)
//2.7-1 Delete View使用Scaffold template:Delete
//2.7-2 在Delete View(Delete.cshtml)使用GetImage Action
```

在講view前先講&#x20;

\##03\_ActionFilter&#x20;過濾器
---

#### 示意圖&#xD;

![](/files/-LgXBIdIKsBvhlV031Zp)

![](/files/-LgXBUEyofYuBWWNWCi9)

Web.config 伺服器層級的組態設定

ApplicationInsights.config應用程式組態設定

Global.config 應用程式組態分類

HandleErroAttribute 錯誤幫助者

#### 做個猛一點的範例&#xD;

#### ###[03\_ActionFilter/PhotoSharing/Controllers/ValueReporter.cs](ftp://mvc@10.10.3.189/03_ActionFilter/PhotoSharing/Controllers/ValueReporter.cs)

過濾器 抓取使用者全部動作存入資料庫 ( 網站被攻擊時可以查看並鎖ip

其實可以寫在controller裡面寫 但要寫幾千幾百??

範例&#x20;

log 所有的請求 時間 ip host brower type&#x20;

log 對那些 action 請求

首先新增資料庫用於儲存log

![](/files/-LgXBfajKv_En13J85Pu)

寫一個一般類別而不是新增控制器 ( 差別在 繼承哪個 namespace

![](/files/-LgXBsfcr0EuwwL4CHJC)

Using mvc

繼承 ActionFilterAttribute 驗證基底類別

做一個動作就要存資料庫一次

### ##直接寫 ADO.NET ??&#xD;

{% embed url="<https://zh.wikipedia.org/wiki/ADO.NET>" %}

{% embed url="<https://zh.wikipedia.org/wiki/Entity_Framework>" %}

![](/files/-LgXCVP6o_sTbguYFr3I)

Using System.data.sqlclient

#### 連線資訊&#xD; (以下偷吃步

Using system con

以前是利用sqldatasourse 建立 connectionstrings

![](/files/-LgXCfLZaJrNCKjagC8p)

把sqldatasourse拉進去然後再設計那邊用選的選完後webconfig就會產生connectionstrings

#### 現在要自己寫&#xD;

直接 sqlconnection 物件自己重新寫一個

然後就能下 sqlcommand

接著寫個 void 函數 然後傳指令近來就做 打開 傳旨 然後關閉

寫action 把資料存到資料表 pk 跟時間都是自己產生的&#x20;

所以只要傳入其他欄位

有兩種方式可以寫

第一種 複寫 onActionExecute  ( 先後 紀錄

在外面寫一個logValies函數傳入ROUTEDATA用於?

首先清空 PARAMETERS

路徑 抓出 controller action parame的值

有可能是null但不用if的寫法

接著用 ado.net 存取方式 與 parameter參數資安用法

存值進去

回到&#x20;

### ValueReporter:ActionFilterAttribute

public override void OnActionExecuting(ActionExecutingContext filterContext)

public override void OnResultExecuted(ResultExecutedContext filterContext)

回到複寫那裏?? 看無 講太快 = =&#x20;

在做一個 requestlog 抓 httpcontext  裡面的 7個值&#x20;

封包 = httpcontext

抓ip host browser用ServerVariable 能抓啥要去查 MSDN

接著 requestType userHostaddress userhostname http method則直接抓即可

接著再做一次 ado.net 存取方式 與 parameter參數資安用法 存值

接著做複寫 ? OnResultExecuted(ResultExecutedContext filterContext)

呼叫 requestlog&#x20;

接著要去 FilterConfig.cs 註冊我們這個自己建立的過濾器

要using 或namespase位址要對

註冊好後

哪裡要用到過濾器必須指定&#x20;

\[ValueReporter] 執行到哪就做過濾器

正面表列?負面表列  ( 會在講 = = ?

Action 層級 controller 層級 application層級的

存取資料庫報錯

位址問題 要修正 PhotoSharingContext 的 base

Locodb ?? entityframwork&#x20;

但是我們用 connectionStrings 資料存取層&#x20;

放進不同的事件內 ( 成功才寄 失敗不記之類的&#x20;

所以才會有那麼多 function 因應不同事件做存取

我們的Filter 是 application 層級的 所以所有動作都會存入

近端存取 存取不到ip

![](/files/-LgXISPuWdayk0rX6-JU)

![](/files/-LgXIYldM162mWFORc6G)

#### ###controllers/ValueReporter.cs

```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Data.SqlClient;
using System.Configuration;
using System.Web.Routing;

namespace PhotoSharing.Controllers
{
    //2.8-1 繼承System.Web.Mvc.ActionFilterAttribute(注意:命名空間 System.Web.Mvc)
    public class ValueReporter:ActionFilterAttribute
    {
        SqlConnection Conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
        SqlCommand cmd = new SqlCommand();
        //2.8-2 建立一般方法executeSql()-可傳入SQL字串來輯編資料表
        void executeSql(string sql)
        {
            Conn.Open();

            cmd.Connection = Conn;
            cmd.CommandText = sql;
            cmd.ExecuteNonQuery();

            Conn.Close();
        }
        //2.8-4 覆寫OnActionExecuting方法,執行LogValues方法,透過ActionExecutingContext.RouteData屬性傳入RouteData物件
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            //base.OnActionExecuting(filterContext);
            LogValues(filterContext.RouteData);
        }
        //2.8-3 自訂LogValues方法,透過RouteData物件將controller及action參數透過ADO.net送至PhotoSharing資料庫的ActionLog資料表
        void LogValues(RouteData routeData)
        {
            cmd.Parameters.Clear();
            var controllerName = routeData.Values["controller"];
            var actionName = routeData.Values["action"];
            var parame = routeData.Values["id"] == null ? "N/A" : routeData.Values["id"];

            string sql = "insert into actionLog(controllerName,actionName,parame) values(@controllerName,@actionName,@parame)";
            cmd.Parameters.AddWithValue("@controllerName", controllerName);
            cmd.Parameters.AddWithValue("@actionName", actionName);
            cmd.Parameters.AddWithValue("@parame", parame);

            executeSql(sql);
        }

        //2.8-5 自訂RequestLog方法,取出HttpContext.Current.Request,將ServerVariable透過ADO.net送至PhotoSharing資料庫的RequestLog資料表
        void RequestLog()
        {
            cmd.Parameters.Clear();
            var ip = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            var host = HttpContext.Current.Request.ServerVariables["REMOTE_HOST"];
            var browser = HttpContext.Current.Request.ServerVariables["HTTP_USER_AGENT"];

            var requestType = HttpContext.Current.Request.RequestType;
            var userHostAddress = HttpContext.Current.Request.UserHostAddress;
            var userHostName = HttpContext.Current.Request.UserHostName;
            var httpMethod = HttpContext.Current.Request.HttpMethod;

            string sql = "insert into RequestLog(ip,host,browser,requestType,userHostAddress,userHostName,httpMethod) ";
            sql+= "values(@ip,@host,@browser,@requestType,@userHostAddress,@userHostName,@httpMethod)";
            cmd.Parameters.AddWithValue("@ip", ip);
            cmd.Parameters.AddWithValue("@host", host);
            cmd.Parameters.AddWithValue("@browser", browser);
            cmd.Parameters.AddWithValue("@requestType", requestType);
            cmd.Parameters.AddWithValue("@userHostAddress", userHostAddress);
            cmd.Parameters.AddWithValue("@userHostName", userHostName);
            cmd.Parameters.AddWithValue("@httpMethod", httpMethod);
    

            executeSql(sql);
        }
        //2.8-6 覆寫OnActionExecuted方法,執行RequestLog方法
        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            RequestLog();
        }
      
    }
}
```

#### ###ftp\://mvc\@10.10.3.189/03\_ActionFilter/PhotoSharing/Controllers/PhotosController.cs

```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PhotoSharing.Models;
using PhotoSharing.DAL;
using System.Net;


namespace PhotoSharing.Controllers
{
  
    public class PhotosController : Controller
    {
        //2.2建立Data Context 來自 Photo Model 的 PhotoSharingContext 
        PhotoSharingContext context = new PhotoSharingContext();

        // GET: Photos
        //2.3-1 Index()回傳Photo
      
        public ActionResult Index()
        {
            ViewBag.Date = DateTime.Now;  //用ViewBag帶入今日日期
            return View(context.Photos.ToList());
        }

        //2.3-2 Display(int id) 透過id參數回傳Photo,若找不到回傳HttpNotFound()helper
       
        public ActionResult Display(int? id)
        {
            ViewData["Date"] = DateTime.Now; //用ViewData帶入今日日期
            if (id==null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            Photo photo = context.Photos.Find(id);
            if(photo==null)
            {
                return HttpNotFound();
            }

            return View("Display", photo);
        }
        //2.3-7 建立GetImage(int id)回傳File(photo.PhotoFile, photo.ImageMimeType)
        //這不是View()Helper的ActionResult, 這是File()helper
        public FileContentResult GetImage(int id)
        {
            Photo photo = context.Photos.Find(id);
            return File(photo.PhotoFile, photo.ImageMimeType);
        }

        //2.3-3 GET:Create() 產生新增Photo作業,並回傳 new Photo()並產生CreatedDate屬性值= DateTime.Today
        public ActionResult Create()
        {
            Photo newPhoto = new Photo();
            newPhoto.CreatedDate = DateTime.Today;
            
            return View("Create",newPhoto);
        }
        //2.3-4 Post:Create(Photo photo, HttpPostedFileBase image),使用HTTP POST,執行新增Photo回存作業,回傳RedirectToAction()helper
        //      如果ModelState.IsValid==false,回傳Photo給View, 反之執行新增Photo回存作業
        //      photo.ImageMimeType = image.ContentType;
        //      photo.PhotoFile = new byte[image.ContentLength];
        //      image.InputStream.Read(photo.PhotoFile, 0, image.ContentLength);
        [HttpPost,ValidateAntiForgeryToken]
        public ActionResult Create(Photo photo,HttpPostedFileBase image)
        {
            photo.CreatedDate = DateTime.Today;
            if(ModelState.IsValid)
            {
                //有post照片才做照片上傳的處理
                if (image!=null)
                {
                    photo.ImageMimeType = image.ContentType;  //抓照片型態
                    photo.PhotoFile = new byte[image.ContentLength];  //取得上傳照片的大小再轉byte陣列
                    image.InputStream.Read(photo.PhotoFile, 0, image.ContentLength);
                }
                context.Photos.Add(photo);
                context.SaveChanges();
                return RedirectToAction("Index");

            }
            else
            {
                return View("Create", photo);
            }


            
        }
        //2.3-5 Get:Delete(int id)產生刪除Photo作業,並回傳Photo(),若找不到回傳HttpNotFound()helper
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            Photo photo = context.Photos.Find(id);
            if (photo == null)
            {
                return HttpNotFound();
            }

            return View("Delete", photo);
        }
        //2.3-6 Post:建立DeleteConfirmed(int id)使用[ActionName("Delete")]屬性,透過HTTP POST,執行刪除Photo回存作業.回傳RedirectToAction()helper
        [HttpPost,ValidateAntiForgeryToken]
        [ActionName("Delete")]
        public ActionResult DeleteConfirmed(int? id)
        {
            Photo photo = context.Photos.Find(id);
            context.Photos.Remove(photo);
            context.SaveChanges();
            return RedirectToAction("Index");
        }


    }
}
```

#### ###老師步驟

```
//2.1.加入 Empty MVC controller -> PhotoController(PhotoController.cs)
//2.2.建立Data Context 來自 Photo Model 的 PhotoSharingContext 
//2.3.建立action
//2.3-1 Index()回傳Photo
//2.3-2 Display(int id) 透過id參數回傳Photo,若找不到回傳HttpNotFound()helper
//2.3-3 Create() 產生新增Photo作業,並回傳 new Photo()並產生CreatedDate屬性值= DateTime.Today
//2.3-4 Create(Photo photo, HttpPostedFileBase image),使用HTTP POST,執行新增Photo回存作業,回傳RedirectToAction()helper
//      如果ModelState.IsValid==false,回傳Photo給View,反之執行新增Photo回存作業
//      photo.ImageMimeType = image.ContentType;
//      photo.PhotoFile = new byte[image.ContentLength];
//      image.InputStream.Read(photo.PhotoFile, 0, image.ContentLength);
//2.3-5 Delete(int id)產生刪除Photo作業,並回傳Photo(),若找不到回傳HttpNotFound()helper
//2.3-6 建立DeleteConfirmed(int id)使用[ActionName("Delete")]屬性,透過HTTP POST,執行刪除Photo回存作業.回傳RedirectToAction()helper
//2.3-7 建立GetImage(int id)回傳File(photo.PhotoFile, photo.ImageMimeType)(注意:File()helper 是FileContentResult,不是 View()helper 的ActionResult)


//2.4.建立Index及Display Views
//      Model Class:Photo (PhotoSharing.Models)
//      Data Context Class:PhotoSharingContext (PhotoSharing.DAL)
//2.4-1 Index View使用Scaffold template:List
//2.4-2 Display View使用Scaffold template:Details 


//2.5. 更改Index View
//2.5-1 取出ViewBag值
//2.5-2 註解:不顯示圖片
//2.5-3 在Index View(Index.cshtml)將ActionLink的Details改成Display


//2.6 更改Display View
//2.6-1 取出ViewData值
//2.6-2 在Display View(Display.cshtml)使用GetImage Action


//2.7.建立Delete Views
//      Model Class:Photo (PhotoSharing.Models)
//      Data Context Class:PhotoSharingContext (PhotoSharing.DAL)
//2.7-1 Delete View使用Scaffold template:Delete
//2.7-2 在Delete View(Delete.cshtml)使用GetImage Action

//2.8.Controllers-->Add Class-->建立ValueReporter Class(ValueReporter.cs),加入Action Filter Type
//2.8-1 繼承System.Web.Mvc.ActionFilterAttribute(注意:命名空間 System.Web.Mvc)
//2.8-2 建立一般方法executeSql()-可傳入SQL字串來輯編資料表
//2.8-3 自訂LogValues方法,透過RouteData物件將controller及action參數透過ADO.net送至PhotoSharing資料庫的ActionLog資料表
//2.8-4 覆寫OnActionExecuting方法,執行LogValues方法,透過ActionExecutingContext.RouteData屬性傳入RouteData物件
//2.8-5 自訂RequestLog方法,取出HttpContext.Current.Request,將ServerVariable透過ADO.net送至PhotoSharing資料庫的RequestLog資料表
//2.8-6 覆寫OnActionExecuted方法,執行RequestLog方法

//2.9 在PhotoSharing資料庫中建立ActionLog與RequestLog資料表
//Create table ActionLog(
//    ActionLogSN bigint identity primary key,
//    logTime datetime default getdate() not null,
//    controllerName varchar(30) not null,
//	actionName varchar(30) not null,
//	parame varchar(10) not null
//)
//go


//create table RequestLog(
//    RequestLogSN bigint identity primary key,
//    logTime datetime default getdate() not null,
//    [ip] varchar(20) not null,
//	host varchar(30) not null,
//	browser varchar(MAX) not null,
//	requestType varchar(20) not null,
//	userHostAddress varchar(20) not null,
//	userHostName varchar(30) not null,
//	httpMethod varchar(30) not null
//)
//go

//3.0 註冊Action Filter
//3.0-1 在PhotoController class註冊Action Filter Class[ValueReporter]
//    可註冊為Action層級或Controller層級

//3.0-2 在App_Start\FilterConfig.cs中Action Filter Class[ValueReporter]

//***將PhotoSharingContext.cs裡的public PhotoSharingContext() : base("PhotoSharing")
//改為public PhotoSharingContext() : base("ConnectionString")***//  此處的值要視Web.config而定
```

### 接著講

## ##04\_View

### @RAZOR Helper&#xD;&#x20;

#### ##View單純很多&#xD;

接著處理重建 display ( 手工打造 ( detail 需要 id

回到controller 的 display action 新增檢視

Empty 但 帶model的 並覆蓋 會把剛剛display的東西洗掉

#### ###keyword&#xD;

Fieldset legend

@Model.Title

@Url.Aciton()

Img-responsive/thumbnail

@Html.DisplayFor

@Html.DisplayNameFor

@Html.DisplayText

@Html.ActionLink

#### &#xD;###<ftp://mvc@10.10.3.189/04_View/PhotoSharing/Views/Photos/Display.cshtml>

```
@model PhotoSharing.Models.Photo

@{
    ViewBag.Title = "Display";
}

<fieldset>
    <legend>
        「@Model.Title」
    </legend>
    <img src="@Url.Action("GetImage","Photos",new { id=Model.PhotoID})" class="img-responsive img-thumbnail" />
    <p>
        @Html.DisplayFor(model => model.Description)
    </p>
    <p>
        @Html.DisplayNameFor(model => model.UserName)
        @Html.DisplayFor(model => model.UserName)
    </p>
    <p>
        @Html.DisplayNameFor(model => model.CreatedDate)
        @Html.DisplayFor(model => model.CreatedDate)
    </p>


</fieldset>
<p>
    @Html.ActionLink("刪除", "Delete",new { id=Model.PhotoID}) | 
    @Html.ActionLink("返回列表", "Index")
</p>
```

接著處理 creater view一樣的步驟 且帶model

差別在 create 有 form 用於上傳

直接用html5語意標籤簡單排版

然後用 simple binding 做資料傳遞處理

但是剛剛的東西拿掉 改為用&#x20;

#### ##@RAZOR Helper&#xD;

@Html.BeginForm(actionname,controllername,formmether,new{enctype前端屬性}){}

@Html.AntiForgeryToken()

@Html.ValidationSummary()驗證通過不通過的管理器

@Html.LabelFor(model=>model.Title) 不用指定id name 但要

@Html.EditorFor()

@Html.ValidationMessageFor()

不能填就用displayfor即可

Using ???

避開 filter ? 資料庫重建 action req log ?&#x20;

mvc model 獨立?&#x20;

Controller怎樣都不會影響model???

#### &#xD;###<ftp://mvc@10.10.3.189/04_View/PhotoSharing/Views/Photos/Create.cshtml>

```
@model PhotoSharing.Models.Photo

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

@*<form method="post" action="/photos/create" enctype="multipart/form-data">*@

@using (Html.BeginForm("Create", "Photos", FormMethod.Post, new { enctype = "multipart/form-data" }))
        {
            @Html.AntiForgeryToken()
                    @Html.ValidationSummary()
    <p>
       @Html.LabelFor(model => model.Title)
                      @Html.EditorFor(model => model.Title)
                        @Html.ValidationMessageFor(model => model.Title)
    </p>
    <p>
        @Html.LabelFor(model => model.PhotoFile)
        <input id = "image" name = "image" type = "file" required />


           </p>


           <p>
               @Html.LabelFor(model => model.Description)
                        @Html.EditorFor(model => model.Description)
                        @Html.ValidationMessageFor(model => model.Description)
    </p>
    <p>
        @Html.LabelFor(model => model.UserName)
                        @Html.EditorFor(model => model.UserName)
                        @Html.ValidationMessageFor(model => model.UserName)
    </p>
    <p>
        @Html.LabelFor(model => model.CreatedDate)
                        @Html.DisplayFor(model => model.CreatedDate)

    </p>
    <p>
        <input id = "Submit1" type = "submit" value = "新增資料" class="btn btn-default" />
        @Html.ActionLink("返回列表", "Index")
    </p>
}


@*<p>
    <label>主題:</label>
    <input id="Title" name="Title" type="text" />
</p>
<p>
    <label>上傳照片:</label>
    <input id="image" name="image" type="text" />
</p>
<p>
    <label>描述:</label>
    <input id="Description" name="Description" type="text" />
</p>
<p>
    <label>發表人名稱:</label>
    <input id="UserName" name="UserName" type="text" />
</p>
<p>
    <label>建立日期:</label>
    <input id="CreatedDate" name="CreatedDate" type="text" />
</p>*@

@*</form>*@


```

#### &#xD;###<ftp://mvc@10.10.3.189/04_View/PhotoSharing/Views/Photos/Delete.cshtml>

```
@model PhotoSharing.Models.Photo

@{
    ViewBag.Title = "Delete";
}

<h2>Delete</h2>

<h3>Are you sure you want to delete this?</h3>
<div>
    <h4>Photo</h4>
    <hr />
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => model.Title)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Title)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.PhotoFile)
        </dt>

        <dd>
            @*//2.7-2 在Delete View(Delete.cshtml)使用GetImage Action*@
            @*@Html.DisplayFor(model => model.PhotoFile)*@
            <img class="img-responsive img-thumbnail" src="@Url.Action("GetImage","Photos",new { id=Model.PhotoID})" />
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.ImageMimeType)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.ImageMimeType)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Description)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Description)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.CreatedDate)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.CreatedDate)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.UserName)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.UserName)
        </dd>

    </dl>

    @using (Html.BeginForm()) {
        @Html.AntiForgeryToken()

        <div class="form-actions no-color">
            <input type="submit" value="Delete" class="btn btn-danger" /> |
            @Html.ActionLink("Back to List", "Index")
        </div>
    }
</div>

```

### 到此ok 到時會講趴修view&#xD;


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://johch3n611u.gitbook.io/c50108/ju-li-cheng-bei/201906/untitled-16.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
