MVC Razor - 创建/编辑视图最佳实践

时间:2011-06-10 10:21:26

标签: asp.net-mvc-3 razor

我第一次使用MVC 3 / Razor,用于创建和编辑视图的所有示例和VS脚手架都为这些概念提供了单独的HTML视图,这似乎很奇怪。

许多创建/编辑表单之间没有太大区别,所以我想知道为什么我找不到使用单个更新表单的人员示例,可以由创建和编辑操作使用。

我已经获得了一个Update.cshtml视图,但是想知道它是如何与控制器上的编辑或创建操作方法进行对话的。

我的问题是:

  1. 任何人都可以快速回答与控制器交谈,或
  2. 任何人都知道有一个教程显示以这种方式工作的良好实践,或者
  3. 当HTML经常相同时,是否有一些很好的理由让创建/编辑视图保持独立。
  4. 干杯戴夫

5 个答案:

答案 0 :(得分:10)

此问题(善意!)之前会被问到:ASP.NET MVC - using the same form to both create and edit

基本上,您可以创建局部视图并将其包含在“创建”和“编辑”视图中。

Scott Guthrie关于Partial Views的帖子不错。

(我在某个地方看过这个,但找不到它,我会在找到它时更新这篇文章)

答案 1 :(得分:8)

请注意,您的问题的答案也应该由业务需求(和角色)驱动。脚手架确实提供了单独的功能,在某些情况下是首选实现。

从技术(编程)角度来看,CREATE和EDIT功能通常非常相同。这可以使技术人员认为应该结合功能以实现更有效的技术解决方案。但是,任何技术实施都必须响应业务需求,这可能需要与这些问题分离(例如,通过业务角色)。

例如,企业可能要求CREATE业务对象的角色与编辑它们的角色不同。在这种情况下,实现的网页可能根本不会被相同的角色(和人)看到。

如果使用常用功能实现CREATE和EDIT,但业务需求是角色分离,则必须实现"角色检查"在渲染所需的视图/部分视图/等之前。在这种情况下,单独的视图可以是首选实现。

答案 2 :(得分:3)

我这样做。我不知道这是不是最好的做法,但它可以很好。在某些情况下,完全独立的添加/编辑视图可能很有用。此外,如果您正在使用ViewModels,那么据我所知,您使用相同的ViewModel进行添加和编辑。从理论上讲,他们都应该拥有自己的ViewModel。

以下是我的看法:

<强> 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>

我对这些进行了一些编辑,因此可能会遗漏一些内容,但这应该会给你一般的想法。

答案 3 :(得分: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个获取),而不是2个视图和4个动作。

答案 4 :(得分:-1)

在nuget中查看MVC脚手架,当它生成视图文件时,它会明确地创建一个creatandedit partial,并让创建页面和编辑页面使用该部分。