将单个方法指定为多个控制器URL

时间:2016-03-18 12:22:29

标签: c# .net asp.net-mvc asp.net-mvc-5

有很多问题反过来询问这个逻辑,但是,我无法找到问题的答案。我是MVC的新手,所以可能没有正确指定术语。

我有一个包含表单的视图,用户可以在其中请求产品。无论产品如何,都使用相同的视图,但特定字段以与特定产品相关的形式显示,例如

public class RequestController : Controller
{
    // This bit works fine and displays the appropriate form in the view
    public ActionResult MyProduct(string id)
    {
        if (string.IsNullOrWhiteSpace(id))
        {
            return new HttpNotFoundResult();
        }
        ProductRequest qd = new ProductRequest();
        switch (id)
        {
            case "Beer":
                qd.RequestType = Models.RequestType.Beer;
                break;
            case "Coffee":
                qd.RequestType = Models.RequestType.Coffee;
                break;
            case "Soda":
                qd.RequestType = Models.RequestType.Soda;
                break;
        }
        return View("Index", qd);
    }

    // Need to get all forms rendered by the above to post here...
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult MyProduct(ProductRequest qd)
    {
        if (!ModelState.IsValid)
        {
            return View(qd);
        }
        else
        {
            // To do ...
        }
    }
}

在视图中呈现表单时,使用...

@using (Html.BeginForm())

...呈现的HTML显示每种产品类型的不同表单目标URL,例如:

<form action="/Request/MyProduct/Beer" method="post">

无论产品类型如何,我都可以使form action属性使用相同的控制器/方法吗? e.g。

<form action="/Request/MyProduct" method="post">

我认为有很多方法可以实现这一点,因为MVC似乎提供了灵活性,但我正在寻找最佳实践,请作为学习经验。

2 个答案:

答案 0 :(得分:2)

Html.BeginForm()调用接受各种参数,这些参数可以声明您希望表单使用的控制器/方法。

@using (Html.BeginForm("MyProduct", "Request", FormMethod.Post, new { enctype = "multipart/form-data"}))

应该产生:

<form action="/Request/MyProduct" enctype="multipart/form-data" method="post">

答案 1 :(得分:1)

除了阻止您轻松控制您的操作网址之外,还有什么附加值可以让您自己编写html Html.BeginForm帮助器?

就个人而言,我已经禁止了大多数Html助手的使用,只是以我的方式而不是帮助我。

自己编写html代码,这通常比使用html帮助程序更简洁(如answer所示)。

<form action"@Url.Action("MyProduct", "Request")" method="post">
    @* Add [ValidateAntiForgeryToken, HttpPost] attributes to target action *@
    @Html.AntiForgeryToken()
    ...
</form>

(更好的是,使用UrlHeper extensions来定义和集中您的URI,而不是在您的视图或控制器中调用Url.Action。)

为了完整性,我应该提到大多数输入字段html辅助扩展(后缀为For)具有利用视图模型的数据注释的附加值。但我认为这些注释是不好的做法,因为它们处理的主题不是严格的MVC模式中的视图模型责任。 (显示标签?应由视图控制。验证规则?应由控制器控制。操作参数和/或参数模型?没有理由绑定到视图模型名称。)