我有一个应用程序调用Web服务,根据用户输入的条件显示导入记录。
每个“导入”可以包含0到多个PurchaseOrder,0到多个容器,0到多个产品,0到多个发票。
View(显示查询)工作正常,当我点击提交按钮时,控制器没有通过viewmodel获取“import”信息。我可以通过“formCollection”访问这些控件。
我错过了什么????
这是我的代码......
...模型
namespace LemansCorpIntranet.Models
{
public class ImportWebViewModel
{
public string button { get; set; }
public string status_filter { get; set; }
public string import_id_filter { get; set; }
public DateTime date_filter { get; set; }
public string vendor_filter { get; set; }
public string port_filter { get; set; }
public string whse_filter { get; set; }
public Boolean not_released_filter { get; set; }
public int release_gap { get; set; }
public List<import_row> import_rows; /// this is the piece that is not coming
// thru on the POST
}
public class import_row
{
public string update_switch { get; set; }
public string id { get; set; }
public IEnumerable<SelectListItem> ship_via { get; set; }
public string broker_number { get; set; }
public string voyage { get; set; }
public string vessel { get; set; }
public decimal shipment_value { get; set; }
public int cartons { get; set; }
public decimal weight { get; set; }
public decimal volume { get; set; }
public string clearance_port { get; set; }
public string warehouses_in_shipment { get; set; }
public string payment_type { get; set; }
public string insurance { get; set; }
public DateTime ship_date { get; set; }
public DateTime close_date { get; set; }
public DateTime customs_date { get; set; }
public string customs_entry { get; set; }
public DateTime pl_2_whse_date { get; set; }
public DateTime estimated_arrival_date { get; set; }
public DateTime wire_transfer_request_done_date { get; set; }
public DateTime approved_broker_bill_date { get; set; }
public DateTime product_released_date { get; set; }
public List<Invoice> Invoices;
public List<PurchaseOrder> PurchasOrders;
public List<Product> Products;
public List<Container> Containers;
}
public class Invoice
{
public string invoice_number { get; set; }
}
public class PurchaseOrder
{
public string id { get; set; }
public string whse { get; set; }
public string vendor_code { get; set; }
public string vendor_name { get; set; }
}
public class Product
{
public int line_number { get; set; }
public string description { get; set; }
}
public class Container
{
public int line_number { get; set; }
public int size { get; set; }
public string id { get; set; }
public string seal { get; set; }
public DateTime received_date { get; set; }
public int cartons { get; set; }
}
}
这是我的观点(部分)
<% using (Html.BeginForm("ImportLog", "ImportWeb")) %>
<% { %>
<table style="position:fixed">
.
.
.
<% if (Model.import_rows != null) %>
<% { %>
<% var row_number = 0; %>
<table id="import_web_detail">
<% foreach (var row in Model.import_rows) %>
<% { %>
<% if (row.id != " ")%>
<% { %>
<% row_number++; %>
<tr style="vertical-align:top">
<td style="width:.5em" />
<td align="center">
<table>
<tr>
<td colspan="4"></td>
<td><%=Html.CheckBox("update_switch", row.update_switch)%></td>
<td colspan="4"></td>
</tr>
</table>
</td>
<td />
<td>
<table>
<tr>
<td><%=Html.TextBox("import_id", row.id)%></td>
</tr>
</table>
</td>
这是我的控制器......
namespace LemansCorpIntranet.Controllers
{
public class ImportWebController : Controller
{
eptest_importweb_svc.Service importweb_svc = new eptest_importweb_svc.Service();
//
// Import Web Request
public ActionResult ImportLog(ImportWebViewModel import_request)
{// import_request.import_rows is null. should be loaded with view detail
switch (import_request.button)
{
case "Next":
case "Previous":
return RedirectToAction("ImportPage", import_request);
case "Update":
return RedirectToAction("ImportUpdate");
case "Importlog":
return RedirectToAction("ImportReport");
default:
break;
}
// ----------------------------------
// fall thru for initial page display
// ----------------------------------
// load "date filter" with default. 300 days in the past.
// ------------------------------------------------------
import_request.date_filter = new DateTime(DateTime.Now.Year - 1,
DateTime.Now.Month, DateTime.Now.Day).AddDays(65);
return View("ImportLog", import_request);
}
我还没有发布视图/控制器的完整性....
它可以渲染视图......
当我提交视图/表单时,控制器只能访问视图模型主要部分中的项目(“列表”中没有任何内容通过)。
我可以通过“formcollection”访问这些其他控件。
我想知道为什么viewmodel中有null。
答案 0 :(得分:1)
您的问题是您没有以MVC模型绑定器可以理解它们是嵌套类的一部分的方式命名您的字段。对于每一行,您只需要一个具有相同名称的字段。这不起作用。
这是您不应使用辅助类的非类型安全版本的原因之一,因为类型安全版本将自动生成正确的名称。您还应该利用EditorTemplates,因为它们为集合做了正确的事情,并自动遍历集合。
阅读http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-1-introduction.html
如果必须按照自己的方式进行,那么您需要在名称中包含数组语法。使用for语句而不是foreach,并使用计数器计算行号。做这样的事情:
<% for(int row = 0; row < Model.import_rows.Count; row++) { %>
....
<td><%=Html.CheckBoxFor(x => Model.import_rows[row].update_switch)%></td>
....
<% } %>
在此处阅读更多内容:http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
答案 1 :(得分:0)
我认为您遗漏的是一些@HiddenFor
条款,用于您未在模型中获得的值。如果我理解你,你会得到一些,但不是全部。那些你没有得到的,为他们定义@HiddenFor
,看看会发生什么。
<强>更新强>
这是关于嵌套视图模型的堆栈溢出:
Nested ViewModel Classes in asp.net MVC
更新2
在这里看一下,看起来与你的问题非常相似:
ASP.net MVC2. Populated model is not getting back to the controller
希望这有帮助
答案 2 :(得分:0)
我试图在RedirectToAction中传递viewmodel ..
发现这不起作用。
感谢大家的帮助。