2011-06-10 117 views
21

我正在第一次使用MVC 3/Razor,並且所有用於創建和編輯視圖的示例和VS腳手架都具有用於這些概念的單獨HTML視圖,這似乎很奇怪。MVC剃刀 - 創建/編輯視圖最佳實踐

許多創建/編輯表單之間確實沒有多少區別,所以我想知道爲什麼我找不到使用可由創建和編輯操作使用的單個更新表單的人員的示例。

我已經得到了一個Update.cshtml視圖的工作,但想知道它如何與控制器上的編輯或創建操作方法交談。

我的問題是:

  1. 任何人有一個快速的答案,聊到控制器,或
  2. 任何人都知道出了這種方式工作的良好做法教程,或
  3. 是有一些好的當HTML通常是相同的時候保持創建/編輯視圖分離的原因。問題

乾杯戴夫

+0

可能的[ASP.NET MVC的重複 - 使用相同的形式來創建和編輯](http://stackoverflow.com/questions/399914/asp-net-mvc-using-the-same-form-to -both-create-and-edit) – 2014-12-03 15:27:56

回答

10

這(!那種)被問過:ASP.NET MVC - using the same form to both create and edit

基本上你可以創建一個局部視圖,包括它在您創建和編輯視圖。

Scott Guthrie有一篇關於Partial Views的帖子。

(我讀過有關這地方,但無法找到它,我會更新這個帖子的時候我找到它)

+0

Scott Guthrie博客帖子是關於佈局,而不是部分視圖。 – jlafay 2012-05-10 16:06:24

+1

我不認爲這是重複的問題; TS正在使用MVC 3 – kite 2012-08-31 21:32:37

-1

查找到的NuGet MVC腳手架爲好,當它產生的觀點文件它明確創建一個creatandedit部分,並使創建頁面和編輯頁面使用該部分。

3

我這樣做。我不知道這是否是最佳做法,但它可以很好。有些情況下完全獨立的添加/編輯視圖可能會有用。此外,如果您使用ViewModels,那麼據我所知,您使用相同的ViewModel進行添加和編輯。理論上他們都應該擁有自己的ViewModels。

以下是這看起來對我來說:

AddVideo.cshtml

@model Multimedia.MediaVideoViewModel 

@{ 
    Layout = "~/Views/Shared/LiveSubLayout.cshtml"; 
} 

@section AdditionalHeadContent { 

} 

<div class="page-header"> 
    <h1>Add a new video</h1> 
</div> 

<div id="add-video" class="row-fluid"> 
    @Html.Partial("_VideoForm", Model, new ViewDataDictionary { { "ActionKeyword", "Add" } }) 
</div> 

EditVideo.cshtml

@model Multimedia.MediaVideoViewModel 

@{ 
    Layout = "~/Views/Shared/LiveSubLayout.cshtml"; 
} 

@section AdditionalHeadContent { 

} 

@if (ViewBag.Success) 
{ 
    <div class="alert alert-success"> 
    <button class="close" data-dismiss="alert">×</button> 
     <h3><strong>Video saved!</strong></h3><br/> 
     <div class="btn-group"> 
      <a href="#" class="btn">Preview this video</a> 
      @Html.ActionLink("Add Another Video", "AddVideo", "Multimedia", new { Model.Id }, new { @class = "btn" }) 
      @Html.ActionLink("View all media", "Index", "Multimedia", null, new { @class = "btn" }) 
     </div> 
     <p>or continue editing below...</p> 
    </div> 
} 

<div class="page-header"> 
    <h1>Edit video <small>@Model.Title</small></h1> 
</div> 

<div id="edit-video" class="row-fluid"> 
    @Html.Partial("_VideoForm", Model, new ViewDataDictionary { { "ActionKeyword", "Edit" } }) 
</div> 

_VideoForm.cshtml(部分)

@model Multimedia.MediaVideoViewModel 

@{ 
    string actionKeyword = ViewData["ActionKeyword"].ToString(); 
} 

<div class="span6"> 

    @using (Html.BeginForm("editvideo", "multimedia")) 
    { 
     <label class="control-label" id="embed-url">Paste video URL here:</label> 
     <div class="control-group"> 
      @Html.TextBoxFor(model => model.EmbedUrl, new { @class = "span12", id = "video-url", placeholder = "ex: http://www.youtube.com/watch?v=PoAGasPLh30" }) 
      <button class="btn disabled" id="get-video" title="Tooltip">Get Video</button> 
     </div> 

     <div class="video-meta"> 

      <h3>Video Information</h3> 
      <label class="control-label">Title:</label> 

      <div class="control-group"> 
       @Html.TextBoxFor(model => model.Title, new { @class = "span12", id = "video-title" }) 
       @Html.ValidationMessageFor(model => model.Title, "A title is required", new { @class = "label label-important" }) 
      </div> 

      <label class="control-label">Description:</label> 
      <div class="control-group"> 
       @Html.TextAreaFor(model => model.Description, new { @class = "span12", id = "video-description" }) 
      </div> 

      <h3>Categories</h3> 

      <div id="tag-search" class="well"> 
        <label class="control-label">Search tags:</label> 
        <div class="controls"><input type="text" class="typeahead" /></div> 
        @if (Model != null) 
        { 
         foreach (var category in Model.Tags) 
         { 
          @Html.Partial("_TagFragment", category) 
         } 
        } 
      </div> 

      <hr /> 

      @Html.HiddenFor(model => model.Id) 
      @Html.HiddenFor(model => model.ThumbnailUrl, new { id = "thumb-url" }) 
      <input type="submit" id="video-submit" name="video-submit" class="btn-large btn-primary" value="@actionKeyword video" /> 
     </div> 
    } 

</div> 

我編輯了這些,所以可能會丟失一些東西,但這應該給你一個總體思路。

+0

不要在AddVideo和EditVideo視圖中創建新的ViewDataDictionary對象 - 驗證消息將不起作用。 – Krahu 2014-05-09 08:19:06

0

這裏就是我如何做到這一點,它並不總是最好的做法(這取決於案件)

1 /結合起來,創建和編輯

public PartialViewResult Creedit(string id = null) 
{ 
    if (id == null) 
    { 
     // Create new record (this is the view in Create mode) 
     return PartialView(); 
    } 
    else 
    { 
     // Edit record (view in Edit mode) 
     Client x = db.ClientSet.Find(id); 
     if (x == null) { return PartialView("_error"); } 
     // ... 
     return PartialView(x); 
    } 
} 

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Creedit(Client x) 
{ 
    if (x.id == null) 
    { 
     // insert new record 
    } 
    else 
    { 
     // update record 
    } 
} 

2 /組合編輯控制器的操作和創建視圖到一個視圖我叫Creedit

// if you need to display something unique to a create view 
// just check if the Model is null 
@if(Model==null){ 
} 

,所以我有1個視圖和2個操作(1篇帖子和1個GET),而不是2次和4個行動。

8

請注意,您的問題的答案也應該由業務需求(和角色)驅動。腳手架確實提供了單獨的功能,在某些情況下這是首選的實施方式。

從技術(編程)角度來看,CREATE和EDIT功能通常非常相似。這可能會導致技術人員認爲應該將功能組合起來,以便實施更高效的技術解決方案。但是,任何技術實施都必須針對業務需求,這可能需要分離(例如通過業務角色)這些問題。

例如,企業可能會要求創建業務對象的角色與編輯它們的角色不同。在這種情況下,實現的網頁可能不會被相同的角色(和人)看到。

如果您使用通用功能實現CREATE和EDIT,但業務需要用於角色分離,則在呈現所需視圖/部分視圖/ etc之前,您仍必須實施「角色檢查」。在這種情況下,單獨的視圖可能是首選的實現。