关于将按钮连接到ActionResult的说明

本文关键字:ActionResult 说明 连接 按钮 | 更新日期: 2023-09-27 18:25:25

我仍在学习MVC,这是我长期使用Web Forms的结果。我试图理解的一件事是如何将按钮/输入与ActionResult相关联。

我一直在使用的一个项目是Contoso大学。在该项目中,他们有一个CourseController,在Course/Edit.cshtml页面中,他们使用的表单没有指定控制器或操作方法。因此,我不完全清楚表单是如何知道它需要去哪里的,因为表单或按钮都不指向控制器/操作方法。是因为页面名为Edit,ActionResult也名为Edit吗?

这是控制器中的Contoso.cs.html和ActionResult。

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    <div class="form-horizontal">
        <h4>Course</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.CourseID)
        <div class="form-group">
            @Html.LabelFor(model => model.CourseID, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DisplayFor(model => model.CourseID)
            </div>
        </div>
        <div class="form-group">
            @Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            @Html.LabelFor(model => model.Credits, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Credits, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Credits, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            <label class="control-label col-md-2" for="DepartmentID">Department</label>
            <div class="col-md-10">
                @Html.DropDownList("DepartmentID", null, htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.DepartmentID, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
}
 [HttpPost, ActionName("Edit")]
        [ValidateAntiForgeryToken]
        public ActionResult EditPost(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            var courseToUpdate = db.Courses.Find(id);
            if (TryUpdateModel(courseToUpdate, "",
               new string[] { "Title", "Credits", "DepartmentID" }))
            {
                try
                {
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
                catch (RetryLimitExceededException /* dex */)
                {
                    //Log the error (uncomment dex variable name and add a line here to write a log.
                    ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
                }
            }
            PopulateDepartmentsDropDownList(courseToUpdate.DepartmentID);
            return View(courseToUpdate);
        }

我在搜索中发现的另一件事是,开发人员在表单中调用控制器/动作方法,并在按钮或输入中直接指向控制器/动作方式。

在这里,他们将其添加到表单中。

@using (Html.BeginForm("SignUp", "Account", FormMethod.Post))
{
    <!-- form goes here -->
    <input type="submit" value="Sign Up" />
}

在这里,它直接在按钮中。

<button type="button" onclick="location.href='@Url.Action("MyAction", "MyController")'" >

使用这些方法有什么优点/缺点吗?如果将控件/方法放在表单声明中或直接放在按钮上,我会更清楚。

关于将按钮连接到ActionResult的说明

这些只是BeginForm方法的不同重载。

@using (Html.BeginForm()) {}将呈现一个表单标记,其中action属性值设置为当前页面。这意味着,如果你正在渲染创建页面(Post/create),这个重载将渲染下面的html

<form action="/Post/Create" method="post"></form>

默认情况下,BeginForm将呈现方法值设置为"POST"的表单标记。

第二个重载允许您明确指定目标操作值

因此,如果您在创建剃刀视图(Post/Create)中有以下代码

@using (Html.BeginForm("Edit", "Post"))
{
    <input type="text" name="postName" />
}

这将呈现

<form action="/Post/Edit" method="post">
   <input type="text" name="postName" />
</form>

您需要确保您有用[HttpPost]属性装饰的操作方法来处理控制器中的表单发布

[HttpPost]
public ActionResult Edit(string postName)
{
 //to do  : Do something useful
  return View();
}

我们有另一个重载,它允许我们显式指定Form发布方法。默认值是POST,您可以使用此重载将其更改为GET(但99%的情况下,您将使用POST类型。)

@using (Html.BeginForm("Edit","Post",FormMethod.Get))
{    
}

你可以在这里看到所有可用的重载。尝试不同的方法,并查看这些方法生成的html输出(您可以在页面上进行"查看源代码")。

最后,当您单击表单内的提交按钮时,表单将提交给目标操作。

这意味着,您不需要(也不应该在正常用例中这样做)

<button type="button" onclick="location.href='@Url.Action("MyAction", "MyController")'" >

但这已经足够了

@using (Html.BeginForm("Edit", "Post"))
{
  <input type="submit" />
}

每种方法都有一些优点1) actionresult名称将显示在url中,它还将直接获取该操作结果、同步调用或直接服务器调用2) @url.action我们用于相对路径有时url不识别处理这些问题的第二级,我们使用@url.act来更好地理解它检查绝对路径和相对路径3) 您可以对异步调用进行ajax调用,以获得更好的性能。希望对你有所帮助。