如何在 MVC 5 的同一页面中实现索引和创建?

How to implement Index and create in the same page on MVC 5?

我是 MVC 的初学者,我正在尝试创建一个 Web 应用程序,我希望用户能够在其中创建新项目并在同一页面中查看它们。 我正在尝试通过在索引视图中为创建操作使用局部视图来做到这一点。

问题是我无法在创建新项目后从子项重定向到索引以更新列表。我收到此错误消息(不允许子操作执行重定向操作。

这是我的模型

 public class Expense
{
    public int Id { get; set; }

    [Required]
    public string Title { get; set; }

    [Required]
    [DataType(DataType.Currency)]
    public decimal Amount { get; set; }

    //[Required]
    public string ApplicationUserId { get; set; }
}

,这是我的索引和创建操作

    public ActionResult Index()
    {
        return View(db.Expenses.ToList());
    }
    public ActionResult Create()
    {
        return PartialView("Create", new Expense());
        //return View();
    }

    // POST: /Expense/Create
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include="Id,Title,Amount,ApplicationUserId")] Expense expense)
    {
        if (ModelState.IsValid)
        {
            expense.ApplicationUserId = User.Identity.GetUserId();
            db.Expenses.Add(expense);
            db.SaveChanges();
            return RedirectToAction("Index"); // Here is where The exception is thrown
        }
        return View();
    }

这是我的索引视图

@model IEnumerable<HomeManager.Models.Expense>
@{
    ViewBag.Title = "Index";
}
<h2>Index</h2>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Title)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Amount)
        </th>
        <th></th>
    </tr>
    @foreach (var item in Model)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Amount)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
                @Html.ActionLink("Details", "Details", new { id = item.Id }) |
                @Html.ActionLink("Delete", "Delete", new { id = item.Id })
            </td>
        </tr>
    }
</table>
<p>
    @Html.ActionLink("Create New", "Create")
    @{Html.RenderAction("Create", "Expense");}
</p>

这是我的创建视图

@model HomeManager.Models.Expense

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>


@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>Expense</h4>
        <hr />
        @Html.ValidationSummary(true)

        <div class="form-group">
            @Html.LabelFor(model => model.Title, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Title)
                @Html.ValidationMessageFor(model => model.Title)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Amount, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Amount)
                @Html.ValidationMessageFor(model => model.Amount)
            </div>
        </div>

        @*<div class="form-group">
            @Html.LabelFor(model => model.ApplicationUserId, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.ApplicationUserId)
                @Html.ValidationMessageFor(model => model.ApplicationUserId)
            </div>
        </div>*@

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default"/>
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

如果您想立即显示新记录,那么我建议您使用 Javascript 库,例如 Knockout、Angular Js 或 Ember。

或者,如果您只想使用 MVC,那么您将需要 ajax 调用一个方法,该方法 returns 更新费用记录的部分视图并将此部分视图放在您的DOM 在您看来。

发生错误是因为您html 正在生成表单

<form action="/Expense/Index" method="post">

不是action="/Expense/Create",因为它需要。如果您在 Index() GET 和 Create(Expense expense) POST 方法上都设置了断点,您将看到在提交表单时同时击中了它们。

要解决这个问题,请在局部视图的 BeginForm() 方法中显式设置操作和控制器名称

@using (Html.BeginForm("Create", "Expense"))

请注意,由于您的 Create() GET 方法不执行任何逻辑,您还可以使用

@{ Html.RenderPartial("Create", new Expense()); }

代替RenderAction