【问题标题】:How to reuse model and view for Add and Edit in the administration MVC 4 app如何在管理 MVC 4 应用程序中重用模型和视图以进行添加和编辑
【发布时间】:2013-12-02 12:09:19
【问题描述】:

我正在使用 C# 构建 MVC 4 应用程序,并且我一直在做很多彼此非常相似的添加和编辑视图。我的问题是如何通过填写表单以添加和编辑项目来重用与模型返回的对象的相同视图。这是我在我的应用程序中所做的示例:

@model namespace.Register
@{
    ViewBag.Title = "Manage User";
}

<div class="col1 manage-user">
<div>   
    @using (Html.BeginForm())
    {
        <h1>Add User</h1>
        <div id="error" class="clear">@Html.ValidationSummary(true)</div>
        <ul class="clear">
            <li><label for="UserName">Username:</label>
                @Html.EditorFor(x => x.UserName)
            </li>
            <li><label for="Password">Password:</label>
                @Html.EditorFor(x => x.Password)
            </li>
            <li><label for="ConfirmPassword">Confirm password:</label>
                @Html.EditorFor(x => x.ConfirmPassword)
            </li>
            <li>
                <label for="level">Level:</label>
                @Html.DropDownList("levels", Model.Elements.Levels)
            </li>
        </ul>

        <div class="buttons">
            <input type="submit" class="button create" value="Save" name="Save"/>
            <input type="submit" class="button back" value="Back" name="Back" formnovalidate/>
        </div>
    }
</div>

和我的添加方法:

public ActionResult AddUser()
    {
        Levels levels = new Levels(MyRepository.GetLevelsForUser(User.Identity.Name));
        Register model = new Register(levels);
        return View(register);
    }

    [HttpPost]
    public ActionResult AddUser(Register model, FormCollection form)
    {
        if(form["Back"] != null)
        {
            return RedirectToAction("UserList");
        }

        if (ModelState.IsValid)
        {
        ... add user logic
        }    

        // If we got this far, something failed, redisplay form
        ModelState.AddModelError("", "Please enter valid username and password.");
        return View(model);
    }

当我编辑时,我需要打开与 AddUser 相同的视图,但在模型中填充适当的属性并发布以保存模型中的更改。目前我使用 ViewData["Username"] ,||-|| “密码”,所以要做到这一点,有没有更好的方法来重用这个 AddUser 视图?

寄存器模型如下

public class Register
{       
    [Required]
    [Display(Name = "User name")]
    public string UserName { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }

    public Levels Levels { get; set; }

    public Register()
    {
        UserName = null;
        Password = null;
        ConfirmPassword = null;
        Levels = null;
    }

    public Register(Levels levels)
    {
        UserName = null;
        Password = null;
        ConfirmPassword = null;
        Levels = levels;
    }   
}

【问题讨论】:

  • 真正的唯一区别是在视图模型中提供一些 ID 或标志来指示它是否处于编辑模式。然后,该视图将基于此进行设置。发布时,请务必发布到受尊重的操作(即编辑模式为编辑或新模式为新)。不要过度复杂化。

标签: c# asp.net-mvc asp.net-mvc-4 dry razorengine


【解决方案1】:

为此,我通常利用EditorTemplate 功能,在专用的局部视图中解耦公共部分。

根据您的代码遵循一个示例(注意 BeginForm 标记在每个标记中都不同,而“肉”的形式是从部分中挖掘出来的):

注意:这只是一个示例,它可能可以被剥离更多,但它更多的是概念证明。

添加视图 cshtml

@model namespace.Register
@{
    ViewBag.Title = "Manage User";
}

<div class="col1 manage-user">
<div>   
    @using (Html.BeginForm("AddUser", "YourController", FormMethod.Post))
    {
        <h1>Add User</h1>

        @Html.EditorFor(model => Model)

        <div class="buttons">
            <input type="submit" class="button create" value="Create user" name="Save"/>
            <input type="submit" class="button back" value="Back" name="Back" formnovalidate/>
        </div>
    }
</div>

编辑视图 cshtml

@model namespace.Register
@{
    ViewBag.Title = "Manage User";
}

<div class="col1 manage-user">
<div>   
    @using (Html.BeginForm("UpdateUser", "YourController", FormMethod.Post)
    {
        <h1>Edit User</h1>

        @Html.EditorFor(model => Model)

        <div class="buttons">
            <input type="submit" class="button create" value="Update user" name="Save"/>
            <input type="submit" class="button back" value="Back" name="Back" formnovalidate/>
        </div>
    }
</div>

以上两个视图都将利用此文件(名称不是虚构的,它由 MVC 命名约定规定)。

\Views\Shared\EditorTemplates\Register.cshtml

@model namespace.Register
<div id="error" class="clear">@Html.ValidationSummary(true)</div>
<ul class="clear">
    <li><label for="UserName">Username:</label>
        @Html.EditorFor(x => Model.UserName)
    </li>
    <li><label for="Password">Password:</label>
        @Html.EditorFor(x => Model.Password)
    </li>
    <li><label for="ConfirmPassword">Confirm password:</label>
        @Html.EditorFor(x => Model.ConfirmPassword)
    </li>
    <li>
        <label for="level">Level:</label>
        @Html.DropDownList("levels", Model.Elements.Levels)
    </li>
</ul>

这也适用于显示数据,原理完全相同,但部分进入 \Views\Shared\DisplayTemplates 并通过 DisplayFor() 使用。

可以为模板指定您想要的任何名称,但如果它与类型不匹配,您将不得不使用 EditorFor / DisplayFor 的重载,它们采用视图名称作为参数。

【讨论】:

  • 如果需要,我会使用模板执行相同的技巧,这样我就可以重用代码的某些部分,但我的目标是使用 4 种方法来获取/发布添加/编辑和相同查看我仅更改字段状态的位置 -> 为空或填充信息。虽然我的意图只是在处理表格的帖子时使情况过于复杂。因此,经过一些研究后,我得出一个结论,最好为不同的动作做单独的模型和视图,以免过度复杂化这些简单的模式。不过,您的答案是一个解决方案,因此我会将其标记为已接受;]
猜你喜欢
  • 2011-12-30
  • 1970-01-01
  • 1970-01-01
  • 2012-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-05
  • 1970-01-01
相关资源
最近更新 更多