【问题标题】:MVC5 - Posting a view which contains Html.ActionMVC5 - 发布一个包含 Html.Action 的视图
【发布时间】:2016-09-21 13:48:10
【问题描述】:

我的应用程序需要 CRUD 合同,我可以将文件附加到每个合同。 所以,在我的编辑/更新页面中,我有三种形式:

  • 一个更新合同属性(Edit.cshtml)
  • 向合同中添加文档 (AddDocument.cshtml)
  • 从合同中删除文件(无需出示)

它看起来像这样:

编辑.cshtml

@model ContractViewModel
@Html.Action("AddDocument", "Contracts", new { id = Model.IdContract })
@Html.Action("RemoveDocument", "Contracts", new { id = Model.IdContract })
@using (Html.BeginForm("Edit", "Contracts", FormMethod.Post, new { @class = "form-horizontal", enctype = "multipart/form-data" }))
{
     @Html.AntiForgeryToken()
     @Html.ValidationSummary(true)
     @Html.HiddenFor(model => model.IdContract)
     <div class="form-group">
          @Html.LabelFor(model => model.ContractNumber, htmlAttributes: new { @class = "control-label col-md-4" })
          <div class="col-md-8">
               @Html.EditorFor(model => model.ContractNumber, new { htmlAttributes = new { @class = "form-control" } })
               @Html.ValidationMessageFor(model => model.ContractNumber)
          </div>
    </div> [...]
    <input type="submit" value="Update"/>
}

AddDocument.cshtml

@model DocumentViewModel
@using (Html.BeginForm("AddDocument","Contracts", FormMethod.Post, new { @class = "form-horizontal", enctype="multipart/form-data" }))
{
        @Html.AntiForgeryToken()
        @Html.HiddenFor(model => model.IdContract)
        <div class="form-group">
             @Html.LabelFor(model => model.DocHttp, htmlAttributes: new { @class = "control-label col-md-2" })
             <div class="col-md-10">
                  @Html.TextBoxFor(x => x.DocHttp, htmlAttributes: new { @class = "form-control", data_style = "btn-primary", type = "file", multiple = "multiple" })
                  @Html.ValidationMessageFor(model => model.DocHttp)
             </div>
        </div>
        <input type="submit" value="Add"/>
}

ContractController.cs

public ActionResult Edit(int? id)
{
    if (id == null)
    {
        throw new HttpException(400, "Bad request");
    }
    Contract contract = business.Get<Contract>(x => x.IdContract == id);
    ContractViewModel vm = new ContractViewModel(contract);
    if (contract == null)
    {
        throw new HttpException(404, "Not found");
    }            
    return View(vm);
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(ContractViewModel vm)
{
    Contract contract = business.Get<Contract>(x => x.IdContract == id);
    if (ModelState.IsValid)
    {
        [...]
    }
    return View(vm);
}

public ActionResult AddDocument(int id)
{
    DocumentViewModel vm = new DocumentViewModel();
    vm.IdContract = id;
    return PartialView(vm);
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddDocument(DocumentViewModel vm)
{
    Contract contract = business.Get<Contract>(x => x.IdContract == vm.IdContract);            
    if (ModelState.IsValid)
    {
        [...]
    }
    return RedirectToAction("Edit", "Contracts", new { id = vm.IdContract });
    //return View(vm);
}

首先,问题是,当我提交Edit表单的时候,自然调用了[HttpPost]Edit方法,同时也调用了[HttpPost]AddDocument。是不是因为使用了 Html.Action 而不是 Html.RenderPartial?

如果我是对的,当您必须在生成局部视图之前进行处理时调用 Html.Action,而 Html.RenderPartial 只传递参数。

为什么要调用 [HttpPost]AddDocument 方法?谁叫它的?

其次,要绕过这个问题,我必须重定向到编辑页面,而不是调用 View 方法。但是,我丢失了输入的数据。我该如何解决这个问题?

谢谢。

【问题讨论】:

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


    【解决方案1】:

    [...] 还有 [HttpPost]AddDocument。是不是因为使用了 Html.Action 而不是 Html.RenderPartial?

    一个视图中可以有多个表单,每个表单只会调用对应的控制器方法。

    如果我是对的,当您必须在生成局部视图之前进行处理时调用 Html.Action,而 Html.RenderPartial 只传递参数。

    检查这个post

    基本上,在调用@html.Partial 时,您会在没有控制器调用的情况下导入 html。如果该局部视图是强类型的,您需要确保进行调用的视图的当前模型具有该局部视图所需的模型。

    因为您有一个与调用视图模型具有不同模型的局部视图,所以您有两个选择:

    1- 与您的解决方案相同,调用操作方法并为该视图创建模型

    2- 您传递给调用@Html.renderPartial 或@Html.Partial 的视图的模型必须在部分中包含您需要的模型。 用法示例@Html.Partial("SomePartialview",Model.thePartialViewModel)

    其次,要绕过这个问题,我必须重定向到编辑页面,而不是调用 View 方法。但是,我丢失了输入的数据。我该如何解决这个问题?

    数据不会在重定向之间保留。

    您可以使用this 和/或阅读this

    【讨论】:

    • 谢谢,但您的回答对我没有帮助。我想知道为什么当我应该只调用 Edit 方法时,我的 3 个 HttpPost 方法被调用(Edit、AddDocument、RemoveDocument)。
    • 我无法在新创建的项目中复制您的问题。可能有些大括号不合适?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    相关资源
    最近更新 更多