我已经和这个人争吵了很长一段时间。一切都按计划进行,直到我尝试将View中填充的值返回给Controller(见下文):
使用Fiddler,我一提交数据就会显示有效的html(请参阅下文:)
据我了解,这应该绑定到模型。我回复了财务 ActionResult,但这是我得到的:
在ActionResult财务中返回NULL
我只是不明白这一点。我将列表传递到查看:
@model List<FinanceMVC.Models.FinanceViewModel>
我的 ActionResult 期待以下内容:
List<FinanceViewModel> finance
我觉得我的模特在某个地方有问题,而且我已尽力找到它,但我无法看到它。有谁之前经历过这个吗?请有人伸出援助之手。
请参阅下面的代码:
我有以下模型:
namespace FinanceMVC.Models
{
//public class Finance
//{
//}
public class FinanceViewModel
{
/*ID*/
//[Required]
//[Display(Name = "ID")]
//public int ID { get; set; }
/*BINL_BIND_ID*/
[Required]
[Display(Name = "Invoice Type")]
public IEnumerable<SelectListItem> InvoiceType { get; set; }
/*BINL_Inv_Num_Pointer*/
[RegularExpression(@"^[0-9]*$",
ErrorMessage = "Email is not valid")]
[Required]
[Display(Name = "Invoice Number")]
public string InvoiceNumber { get; set; }
/*BINL_Inv_Num_Period*/
[Required]
[Display(Name = "Invoice Number Period")]
public IEnumerable<SelectListItem> InvoiceNumberPeriod { get; set; }
//public List<C_Period> InvoiceNumberPeriod { get; set; }
/*BINL_Created*/
[Display(Name = "Invoice Created Date")]
[Required]
[DataType(DataType.DateTime)]
public DateTime InvoiceDateCreated { get; set; }
///*BINL_SystemInserted*/
//[Required]
//[Display(Name = "Invoice System Inserted")]
//public bool InvoiceSystemInserted { get; set; }
}
public class C_InvoiceType
{
public int ID { get; set; }
public string Description { get; set; }
}
public class C_Period
{
public int Period { get; set; }
}
public class ReturnInfo
{
string InvoiceType { get; set; }
string InvoiceNumber { get; set; }
string InvoiceNumberPeriod { get; set; }
string InvoiceDateCreated { get; set; }
}
}
查看:
@model List<FinanceMVC.Models.FinanceViewModel>
@{
ViewBag.Title = "Index";
}
@using (Html.BeginForm("Finance", "Finance", FormMethod.Post, new { @class = "form-horizontal" }))
{
<div class="col-md-1 fade in" style="margin-left: 5%; width: 100%; font-size: 11px; height: auto;">
<div id="div_Finance_Container" style="width: 100%; height: 80%; overflow: auto; text-align: left;" runat="server" class="scroll-pane">
<div style="height: 500px; overflow: auto;">
<table id="dataTable" border="0">
@for(int i = 0; i <Model.Count; i++)
{
<tr>
@Html.Label("The next recommended Invoice Number is: ", "The next recommended Invoice Number is: " + Model[i].InvoiceNumber, new { style="font-weight:bold;" })
</tr>
<br />
<tr class="tr_clone">
<td>
<div class="col-md-1" style="width: 20%;">
@Html.DropDownList("InvoiceType[" + @i + "].InvoiceType", Model[i].InvoiceType)
</div>
</td>
<td>
@Html.TextBox("InvoiceNumber[" + @i + "].InvoiceNumber", Model[i].InvoiceNumber)
</td>
<td>
@Html.DropDownList("InvoiceNumberPeriod[" + @i + "].InvoiceNumberPeriod", Model[i].InvoiceNumberPeriod, new { @class = "InvoiceNumberPeriod", string.Empty })
</td>
<td>
@Html.TextBox("InvoiceDateCreated[" + @i + "].InvoiceDateCreated", Model[i].InvoiceDateCreated, new { @class = "InvoiceDateCreated", @type = "date" })
</td>
<td>
<input type="button" name="add" value="Add another record" class="tr_clone_add">
</td>
</tr>
}
</table>
<input type="submit" value="Save Bulk Data" />
</div>
</div>
</div>
}
和控制器:
public class FinanceController : Controller
{
public ActionResult Finance()
{
List<C_Period> c_Per = new List<C_Period>();
// This is only for show by default one row for insert data to the database
List<FinanceViewModel> FinanceViewList = new List<FinanceViewModel>
{
new FinanceViewModel
{
/*ID = 0 ,*/ InvoiceType = ListInvoiceTypesForFinances() /*ReturnInvoiceType()*/, InvoiceNumber = ReturnInvoiceNumber(), InvoiceNumberPeriod = ListInvoiceNumPeriodForFinances() /*c_Per*/, InvoiceDateCreated = DateTime.Now, /*InvoiceSystemInserted = false*/
},
new FinanceViewModel
{
/*ID = 0 ,*/ InvoiceType = ListInvoiceTypesForFinances() /*ReturnInvoiceType()*/, InvoiceNumber = ReturnInvoiceNumber(), InvoiceNumberPeriod = ListInvoiceNumPeriodForFinances() /*c_Per*/, InvoiceDateCreated = DateTime.Now, /*InvoiceSystemInserted = false*/
},
new FinanceViewModel
{
/*ID = 0 ,*/ InvoiceType = ListInvoiceTypesForFinances() /*ReturnInvoiceType()*/, InvoiceNumber = ReturnInvoiceNumber(), InvoiceNumberPeriod = ListInvoiceNumPeriodForFinances() /*c_Per*/, InvoiceDateCreated = DateTime.Now, /*InvoiceSystemInserted = false*/
}
};
return View(FinanceViewList);
}
//
// GET: /Finance/
/*Matches file name of Finance.cshtml*/
//[HttpPost]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Finance(List<FinanceViewModel> finance)
{
if (ModelState.IsValid)
{
}
return null;
}
//
// GET: /Finance/Welcome/
//public string Index()
//{
// return "This is the Welcome action method...";
//}
public static string ReturnInvoiceNumber()
{
string sQ = ""
+ " Select Max(BINL_Inv_Num_Pointer) AS [Last Invoice Number] \n"
+ " From Biller_InvoiceNum_List with(nolock) \n"
;
using (SqlConnection sCon = new SqlConnection(Application_Info.sMOB_Master_Conn()))
{
if (sCon.State != ConnectionState.Open)
{
sCon.Open();
}
using (SqlCommand sCmd = new SqlCommand(sQ, sCon))
{
using (SqlDataReader sRdr = sCmd.ExecuteReader())
{
string LastInvoiceRecordNumber = "";
while (sRdr.Read())
{
LastInvoiceRecordNumber = (string)sRdr["Last Invoice Number"];
}
int LastInvoiceLength = LastInvoiceRecordNumber.Length;
int number = int.Parse(LastInvoiceRecordNumber);
/*Increment to get recommended next Invoice Number*/
number = (number + 1);
string IntStr = number.ToString();
string NextInvoiceRecordNumber = IntStr.PadLeft(LastInvoiceLength, '0');
return NextInvoiceRecordNumber;
}
}
}
}
public static IEnumerable<C_InvoiceType> ReturnIType()
{
var srtQry = "\n"
+ " Select ID, BIND_Description \n"
+ " From Biller_InvoiceNum_DefSet with(nolock) \n"
;
using (var conn = new SqlConnection(Application_Info.sMOB_Master_Conn()))
using (var objCommand = new SqlCommand(srtQry, conn) { CommandType = CommandType.Text })
using (var dt = new DataTable())
using (var adp = new SqlDataAdapter(objCommand))
{
conn.Open();
adp.Fill(dt);
return dt.AsEnumerable().Select(o => new C_InvoiceType
{
ID = o.Field<int>("ID"),
Description = o.Field<string>("BIND_Description"),
}).ToList();
}
}
public static IEnumerable<SelectListItem> ListInvoiceTypesForFinances()
{
var listIVTypes = ReturnIType();
return listIVTypes
.Select(o => new SelectListItem
{
Text = o.Description,
Value = o.ID.ToString()
})
.ToList();
}
public static IEnumerable<C_Period> ReturnINumPeriod()
{
var srtQry = "\n"
+ " Select BINL_Inv_Num_Period \n"
+ " From Biller_InvoiceNum_List with(nolock) \n"
+ " Where ID = 99999 \n"
;
using (var conn = new SqlConnection(Application_Info.sMOB_Master_Conn()))
using (var objCommand = new SqlCommand(srtQry, conn) { CommandType = CommandType.Text })
using (var dt = new DataTable())
using (var adp = new SqlDataAdapter(objCommand))
{
conn.Open();
adp.Fill(dt);
return dt.AsEnumerable().Select(o => new C_Period
{
Period = o.Field<int>("BINL_Inv_Num_Period"),
}).ToList();
}
}
public static IEnumerable<SelectListItem> ListInvoiceNumPeriodForFinances()
{
var listIVTypes = ReturnINumPeriod();
return listIVTypes
.Select(o => new SelectListItem
{
Text = o.Period.ToString(),
Value = o.Period.ToString()
})
.ToList();
}
}
更新
所以,更改了View @Html帮助程序,如下所示:
@for(int i = 0; i <Model.Count; i++)
{
<tr>
@Html.Label("The next recommended Invoice Number is: ", "The next recommended Invoice Number is: " + Model[i].InvoiceNumber, new { style="font-weight:bold;" })
</tr>
<br />
<tr class="tr_clone">
<td>
<div class="col-md-1" style="width: 20%;">
@*@Html.DropDownList("InvoiceType[" + @i + "].InvoiceType", Model[i].InvoiceType)*@
@Html.DropDownListFor(x => Model[i].InvoiceType, Model[i].InvoiceType)
</div>
</td>
<td>
@*@Html.TextBox("InvoiceNumber[" + @i + "].InvoiceNumber", Model[i].InvoiceNumber)*@
@Html.TextAreaFor(x => Model[i].InvoiceNumber)
</td>
<td>
@*@Html.DropDownList("InvoiceNumberPeriod[" + @i + "].InvoiceNumberPeriod", Model[i].InvoiceNumberPeriod, new { @class = "InvoiceNumberPeriod", string.Empty })*@
@Html.DropDownListFor(x => Model[i].InvoiceNumberPeriod, Model[i].InvoiceNumberPeriod, new { @class = "InvoiceNumberPeriod", string.Empty })
</td>
<td>
@*@Html.TextBox("InvoiceDateCreated[" + @i + "].InvoiceDateCreated", Model[i].InvoiceDateCreated, new { @class = "InvoiceDateCreated", @type = "date" })*@
@Html.TextBoxFor(x => Model[i].InvoiceDateCreated, new { @class = "InvoiceDateCreated", @type = "date" })
</td>
<td>
<input type="button" name="add" value="Add another record" class="tr_clone_add">
</td>
</tr>
}
显示下拉列表仍有问题:
答案 0 :(得分:2)
如果您使用它们,您的前缀需要与您的操作参数名称匹配:
@Html.TextBox("finance[" + i + "].InvoiceNumber", Model[i].InvoiceNumber)
@Html.DropDownList("finance[" + i + "].InvoiceNumberPeriod", Model[i].InvoiceNumberPeriod, new { @class = "InvoiceNumberPeriod", string.Empty })
@Html.TextBox("finance[" + i + "].InvoiceDateCreated", Model[i].InvoiceDateCreated, new { @class = "InvoiceDateCreated", @type = "date" })
当您只有一个参数时,它们不是必需的,在这种情况下您可以使用:
@Html.TextBox("[" + i + "].Property", ...)
您也可以并且实际上应该使用For
方法:
@Html.TextBoxFor(m => m[i].InvoiceNumber, ...)
@Html.DropDownListFor(m => m[i].InvoiceNumberPeriod, ...)
@Html.TextBoxFor(m => m[i].InvoiceDateCreated, ...)
答案 1 :(得分:1)
你必须这样写:
@Html.DropDownList("[" + @i + "].InvoiceType", Model[i].InvoiceType)
@Html.TextBox("[" + @i + "].InvoiceNumber", Model[i].InvoiceNumber)
.................................
.................................
因为您在模型中没有InvoiceType
集合属性,当您编写InvoiceType
时,您在我的模型中说我有一个名为{的集合InvoiceType[0].InvoiceType
{1}},其属性名称为InvoiceType
,而不是
更好的方法是使用 For Helpers,它会自动将控制值与Model绑定:
InvoiceType
您也可以参考此related SO post
答案 2 :(得分:1)
OMG。使用强类型帮助程序。您的控件名称都不匹配您的属性名称
@Html.TextBoxFor(m => m[i].InvoiceNumber)