【问题标题】:Post form from modal partial view to a different controller with a routeprefix attribute将表单从模态部分视图发布到具有 routeprefix 属性的不同控制器
【发布时间】:2016-09-07 20:54:24
【问题描述】:

我有一个带有表单的局部视图 - 我从 Home 控制器启动这个局部视图。

@using (Html.BeginForm("CloudContent","Files", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <div id="container"></div>
    <input type="submit" name="PostMe" title="Submit" value="Submit Form" /> 
    @Html.HiddenFor(m => m.MyProperty);
    @Html.HiddenFor(m => m.SelectedIds);
}

我想将此表单发布到文件控制器,但是文件控制器有一个路由前缀: [RoutePrefix("sth/api/v1/files")]

这导致我的表单操作为空。

它似乎没有被添加到命名路由,所以我不能使用 beginrouteform。另外,我对应用的影响不大,所以最好在我的表单或局部视图中处理...

我想在文件控制器中发布的方法:

[HttpPost]
[Route("getcloudcontent")]
public List<ConnectedFile> CloudContent(CloudFilesModel model)
{
    //do magic
}

【问题讨论】:

  • 您可以自己编写 html,而不是使用 html 助手。如果这正是你想要的,帮助者很棒,但如果你完全偏离他们所做的,可能会很痛苦。另一种选择是编写自定义助手。如果这是一个 1-off 那么它是不值得的。
  • 其他选项包括在 RouteConfig.cs (ick) 中编写您自己的路由或在 Files 控制器的方法中添加路由属性。如果您无法访问这些内容,那么明确编写表单路由是您最好的选择。
  • @nurdyguy - 我可以向文件控制器中的方法添加路由属性 - 我实际上有一个 [Route("getcloudcontent")],但我想前缀仍然很重要?
  • [Route("Files/CloudContent")] 不行吗?
  • 从我读到的文档中听起来它会起作用。但是,当我在一个测试项目上尝试它时,它没有。 RoutePrefix 将添加 Route 属性,这意味着这可能对您不起作用。对于您的情况,我认为明确编写表单可能是最好的。

标签: c# asp.net-mvc forms html.beginform


【解决方案1】:

更新:

这是另一个包含部分视图/子操作的示例:

HomeController.cs:

using System.Web.Mvc;

public class HomeController : Controller
{
    [Route("~/")]
    public ActionResult Index()
    {
        return View();
    }

    [Route("ModalContent")]
    [ChildActionOnly]
    public ActionResult ModalContent()
    {
        return View();
    }
}

FilesController.cs:

using System.Web.Mvc;

[RoutePrefix("sth/api/v1/files")]
public class FilesController : Controller
{
    [HttpPost]
    [Route("getcloudcontent")]
    public ActionResult CloudContent(string model)
    {
        return Content("test");
    }
}

Views\Home\Index.cshtml:

<!DOCTYPE html>
<html>
<head>
    <title>Test</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
    <button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
        Show modal
    </button>

    <div class="modal fade" id="myModal" tabindex="-1">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-body">
                    @Html.Action("ModalContent")
                </div>
            </div>
        </div>
    </div>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</body>
</html>

Views\Home\ModalContent.cshtml:

@using (Html.BeginForm("CloudContent", "Files", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <div id="container"></div>
    <input type="submit" name="PostMe" title="Submit" value="Submit Form" />
}

Global.asax.cs:

using System.Web.Mvc;
using System.Web.Routing;

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        RouteTable.Routes.MapMvcAttributeRoutes();
    }
}

结果HTML:

<!DOCTYPE html>
<html>
<head>
    <title>Test</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
    <button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
        Show modal
    </button>

    <div class="modal fade" id="myModal" tabindex="-1">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-body">
                    <form action="/sth/api/v1/files/getcloudcontent" enctype="multipart/form-data" method="post">
                        <div id="container"></div>
                        <input type="submit" name="PostMe" title="Submit" value="Submit Form" />
                    </form>
                </div>
            </div>
        </div>
    </div>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</body>
</html>

您的代码有一些不同之处。我运行了你的代码,它没有任何问题。

代码如下:

FilesController.cs:

using System.Web.Mvc;

namespace Controllers
{
    [RoutePrefix("sth/api/v1/files")]
    public class FilesController : Controller
    {
        [Route("")]
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        [Route("getcloudcontent")]
        public ActionResult CloudContent(string model)
        {
            return Content("test");
        }
    }
}

Index.cshtml:

@using (Html.BeginForm("CloudContent", "Files", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <div id="container"></div>
    <input type="submit" name="PostMe" title="Submit" value="Submit Form" />
}

Global.asax.cs:

using System.Web.Mvc;
using System.Web.Routing;

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        RouteTable.Routes.MapMvcAttributeRoutes();
    }
}

当我转到http://localhost/sth/api/v1/files 时,我看到以下 HTML:

<!DOCTYPE html>
<html>
<head><title>Test</title></head>
<body>
    <form action="/sth/api/v1/files/getcloudcontent" enctype="multipart/form-data" method="post">    <div id="container"></div>
    <input type="submit" name="PostMe" title="Submit" value="Submit Form" />
</form>
</body>
</html>

请注意,表单操作具有正确的 URL,其中包含前缀。

【讨论】:

  • 用局部视图测试。也可以。
  • 谢谢 - 这可能是我的 PartialView 从某个 Home 控制器操作返回并显示为引导模式的问题吗?
  • 它不应该,因为由于@Html.Partial(partialViewName) 调用,部分渲染在服务器端,所以他们“不知道”他们在哪里渲染。但根据你的“从控制器操作返回部分视图”的评论我认为您的意思是子操作,情况略有不同。让我用另一个例子更新我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-14
  • 1970-01-01
  • 2018-11-19
  • 1970-01-01
  • 2020-06-08
相关资源
最近更新 更多