【问题标题】:ASP.NET MVC 4 - Redirect after Modal Save using Child ActionASP.NET MVC 4 - 使用子操作在模态保存后重定向
【发布时间】:2012-06-28 22:13:37
【问题描述】:

更新 - 在 SO 和 ASP.NET 论坛上有很多关于不允许子操作执行重定向操作的帖子。下面的解决方案似乎是我所见过的针对此问题的最简单的解决方法。如果你有这个问题 - 希望你会发现它有帮助。如果有更好的,我当然愿意接受建议。


我整天都在为此绞尽脑汁......

我有一个 FranchiseSet 模型和一个 Franchise 模型 - 关系是 FranchiseSet 有许多特许经营权。

在 FranchiseSet 索引视图中有一个 Franchise Sets 表格,其中每一行都是可点击的。当我单击一行时,我从 FranchiseSetControllerDetails 方法返回一个视图 - 通过 AJAX。

在该视图中,还有一个表格,显示该特许经营集的所有相关特许经营权。本质上,它是一个主/详细视图 - 如下所示:

有一个 Twitter Bootstrap 模式用于显示特许经营的创建表单。看起来是这样的:

<div class="modal hide fade in" id="myModal" )>
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal">×</button>
        <h3>Modal header</h3>
      </div>
      <div id="create_franchise_modal_body" class="modal-body">
        @Html.Action("Create", "Franchise", new { FranchiseSetId = Model.FranchiseSetID })       
      </div>
      <div class="modal-footer">
        <a href="#" class="btn" data-dismiss="modal">Close</a>
        <a href="#" class="btn btn-primary">Save changes</a>
      </div>
    </div>

在 modal 的主体内,我使用 @Html.Action 助手来调用 FranchiseController 的 Create 方法:

@Html.Action("Create", "Franchise", new { FranchiseSetId = Model.FranchiseSetID })

这是由此生成的模态:

Create 方法成功保存了新的 Franchise,但是,我得到了这个错误:

不允许子动作执行重定向动作。

我已经在 StackOverflow 和 ASP.NET 论坛上看到 LOTS 的关于此问题的帖子,并且我尝试实施一些解决方案 - 即使使用 JavaScript 重定向,但我仍然没有'无法让它工作。

我了解,由于我已经在 FranchiseSet 控制器内部,它已经在尝试基于 FranchiseSet 模型呈现视图,因此 Franchise 模型的子视图 - 未定义。那么处理父子行为之间交互的理想方式是什么?

这似乎是一个没有通用解决方案的非常常见的问题。或者至少我找不到。我对 .net mvc 比较陌生,所以可能就是我。

在这种情况下使用@Html.Action 是一个糟糕的设计选择吗?我曾尝试使用@Html.RenderPartial,但这会导致 500 Internal Server 错误 - 即使我设置了 Create 方法以返回部分视图。

这是我正在使用的 FranchiseController Create 操作 - GET 和 POST:

//
// GET: /Franchise/Create

public ActionResult Create(int FranchiseSetId)
{
    ViewBag.PossibleFranchiseSets = franchisesetRepository.All;
    var franchise = new Franchise { FranchiseSetId = FranchiseSetId };
    return PartialView(franchise);
} 

//
// POST: /Franchise/Create

[HttpPost]
public ActionResult Create(Franchise franchise)
{
    if (ModelState.IsValid) {
        franchiseRepository.InsertOrUpdate(franchise);
        franchiseRepository.Save();
        return RedirectToAction("Index", "FranchiseSet");
    } else {
        ViewBag.PossibleFranchiseSets = franchisesetRepository.All;
        return View();
    }
}

从视图上看,return RedirectToAction("Index", "FranchiseSet");@Html.Action 似乎是问题的根源。

非常感谢任何建议!


解决方案


我使用了 Russell 下面建议的修改后的模式代码,但是我在代码块中将 @Html.RenderPartial 方法切换为 @Html.RenderAction 方法。

这是现在的样子。

<div class="modal hide fade in" id="myModal" )>
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal">×</button>
        <h3>Modal header</h3>
      </div>
      @using (Html.BeginForm("Create", "Franchise", FormMethod.Post))
      {
         <div id="create_franchise_modal_body" class="modal-body">
           @{ Html.RenderAction("Create", "Franchise", new { FranchiseSetId = Model.FranchiseSetID }); }
         </div>
         <div class="modal-footer">
           <a href="#" class="btn" data-dismiss="modal">Close</a>
           <button type="submit" class="btn btn-primary">Save changes</button>
         </div>
      }
  </div>

我还修改了上面 Russell 建议的控制器的 Create 方法。

使用这个:@{ Html.RenderAction("Create", "Franchise", new { FranchiseSetId = Model.FranchiseSetID }); }

我将它放在@{ } 标签中,因为我在这里学到了:Html.RenderPartial giving me strange overload error?

我能够让 FranchiseController 重定向回其父级 - FranchiseSetController 的 Index 方法 - 没有任何问题。另外,它不需要我返回 JSON 并尝试执行 JavaScript 重定向 - 这都是 Razor 视图代码。

我希望这可以解决如何从 Child 动作重定向回 Parent 的问题。

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3


    【解决方案1】:

    为你的模态试试这个:

    <div class="modal hide fade in" id="myModal" )>
          <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal">×</button>
            <h3>Modal header</h3>
          </div>
          @using (Html.BeginForm("Create", "Franchise", FormMethod.Post))
          {
             <div id="create_franchise_modal_body" class="modal-body">
               @Html.RenderPartial("Create")
             </div>
             <div class="modal-footer">
               <a href="#" class="btn" data-dismiss="modal">Close</a>
               <button type="submit" class="btn btn-primary">Save changes</button>
             </div>
          }
     </div>
    

    然后在您的控制器中,修复您的 GET 方法,使其返回部分视图结果

    //
    // GET: /Franchise/Create
    
    public PartialViewResult Create(int FranchiseSetId)
    {
        ViewBag.PossibleFranchiseSets = franchisesetRepository.All;
        var franchise = new Franchise { FranchiseSetId = FranchiseSetId };
        return PartialView(franchise);
    } 
    

    我在这个修复中做了几个假设。

    1. 您的“创建”视图应该是包含所有表单输入的局部视图
    2. 当您调用 @Html.Action("Create", "Franchise", new { FranchiseSetId = Model.FranchiseSetID }) 时,您希望渲染该局部视图
    3. 您希望模态底部的“保存更改”链接实际保存您的模态,而不是显示的“创建”按钮

    如果我遗漏了什么,请告诉我,我会更新我的答案以尝试提供更好的解决方案。

    【讨论】:

    • 感谢罗素的回复。我实际上已经尝试过了,但问题是它呈现了 FranchiseSet 的 Create 部分(这在这个 Detail 视图中是强类型的) - 当我需要 Franchise 的 Create 部分时。这就是我使用 Action 助手的原因,因为我需要到达 Franchise 控制器并返回它的视图。我目前能够使用@Html.Action 呈现正确的视图 - 但它能够从 Franchise 控制器的 Create 方法重定向回 FranchiseSet 控制器,这是主要问题。你知道这样做的方法吗?
    • 您是否有与您的索引页关联的视图模型?
    • 嘿 Russell - 我使用了 RenderAction 而不是 RenderPartial,现在一切正常。我在我的 OP 中添加了一个解决方案部分,解释了我做了什么。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-04
    • 1970-01-01
    相关资源
    最近更新 更多