关于将按钮连接到ActionResult

时间:2015-12-02 15:53:54

标签: c# asp.net-mvc forms asp.net-mvc-4

我还在使用Web Forms进行MVC的学习过程。我试图理解的一件事是将按钮/输入与ActionResult相关联的适当方法。

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

这是控制器中的Contoso .cshtml和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")'" >

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

2 个答案:

答案 0 :(得分:2)

这些只是BeginForm方法的overloads

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

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

默认情况下,BeginForm会将表单标记的方法值设置为&#34; POST&#34;。

第二个重载允许您显式指定目标操作值

因此,如果您在“创建剃须刀”视图(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();
}

我们有另一个overload,它允许我们明确指定Form发布方法。默认为POST,您可以使用此重载将其更改为GET(但99%次,您将使用POST类型。)

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

您可以看到所有可用的重载here。尝试不同的并看到那些生成的html输出(你可以在页面上做&#34;查看源和#34;)。

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

这意味着,您不需要(并且不应该在正常使用情况下执行此操作)

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

但这已经足够了

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

答案 1 :(得分:0)

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