2016-09-21 101 views
0

我的应用程序需要CRUD合同,并且我可以将文档附加到每个合同。 所以,在我的编辑/更新页面上,我有三种形式:MVC5 - 发布包含Html.Action的视图

  • 一个更新合同的性质(Edit.cshtml)
  • 一个补充文件(S)合同(AddDocument.cshtml)
  • 一个从合同中删除文件(没有必要显示)

,它看起来像这样:

Edit.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); 
} 

首先,问题是,当我提交编辑表单时,[HttpPost]编辑方法自然叫,但还有[HttpPost] AddDocument。这是由于使用Html.Action而不是Html.RenderPartial?

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

为什么调用了[HttpPost] AddDocument方法?谁打来的?其次,为了绕过这个问题,我必须重定向到Edit页面,而不是调用View方法。但是,我输入的数据丢失了。我怎样才能解决这个问题?

谢谢。

回答

0

[...]还有[HttpPost] AddDocument。这是由于使用Html.Action而不是Html.RenderPartial?

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

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

入住这post

基本上当调用@ html.Partial要导入的HTML无控制器的呼叫。如果该部分视图是强类型的,则需要确保您正在进行调用的视图的当前模型具有该部分所需的模型。

因为你必须有从调用视图模型diferent模型的局部视图,你有两个选择:

1 - 与您的解决方案,调用操作方法,并创建模型,以这种观点

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

其次,绕过这个问题,我有重定向到编辑页面,而不是调用视图的方法。但是,我输入的数据丢失了。我怎样才能解决这个问题?

数据不会在重定向之间持续存在。

你可以做this和/或读this

+0

感谢,但你的回答对我没有帮助。我想知道为什么我的3 HttpPost方法调用时(Edit,AddDocument,RemoveDocument)只能调用Edit方法。 – madhatterx

+0

我无法在新创建的项目中复制您的问题。也许一些可笑的大括号不适合? – Kharlos