如果我有一个强类型到模型列表的视图,有没有办法从该列表中获取特定模型以传递给我的控制器?我目前正在循环访问所述列表并在复选框列表中吐出值。例如:
@model List<myModel>
@using (Html.BeginForm("MyAction", "MyController", FormMethod.Post, new { @id = "selectedStatusForm" }))
{
<ul class="list-group">
@for (var i = 0; i < Model.Count; i++)
{
<li class="list-group-item">
@Html.RadioButton("reviewSelected", Model[i].ID.ToString())
@Html.Label(Model[i].ReviewDate.ToShortDateString()) - @Html.Label(Model[i].TypeOfReview)
</li>
@Html.Hidden("ID", Model[i].ID.ToString()) // This persists
}
</ul>
<input type="submit" class="btn btn-warning" />
}
我希望我的控制器看起来像什么:
public ActionResult MyAction(myModel model){}
在上面的例子中,我可以使用"reviewSelected"作为参数并只获得该值,但我不能说"给我这个单选按钮上的dang模型"。
我不反对为此使用 ajax,但我没有成功地序列化它以传递。我的模型保持空。
如果只有一个参数reviewSelected
不够好,您可能必须定义一个视图模型来包装myModel
列表和选定的审阅标识符,即reviewSelected
.
注意:我只是编造了类名。
我的模型
public class ReviewTemplateViewModel
{
public int ReviewId { get; set; }
public DateTime ReviewDate { get; set; }
public string TypeOfReview { get; set; }
}
包装 MyModel 列表和其他属性的模型
public class CreateReportViewModel
{
public int ReviewSelected { get; set; }
public IList<ReviewTemplateViewModel> AvailableReviewTemplates { get; set; }
}
视图
@model CreateReportViewModel
@using (Html.BeginForm("create", "report", new { area = "" }, FormMethod.Post, new { @id = "selectedStatusForm" }))
{
<ul class="list-group">
@for (var i = 0; i < Model.AvailableReviewTemplates.Count; i++)
{
<li class="list-group-item">
@Html.RadioButtonFor(m => m.ReviewSelected, Model.AvailableReviewTemplates[i].ReviewId)
<label>
@Model.AvailableReviewTemplates [i].ReviewDate.ToShortDateString()
-
@Model.AvailableReviewTemplates[i].TypeOfReview
</label>
</li>
}
</ul>
<input type="submit" class="btn btn-warning" />
}
控制器
[HttpPost]
public ActionResult(CreateReportViewModel model)
{
// model.ReviewSelected will give you the selected review id
...
// and model.AvailableReviewTemplates will be NULL because
// they are not in the input field. They're not carried over on form
// submit.
}
现在,如果您想保存所有AvailableReviewTemplates
的信息,以便不必在帖子后重新获取列表,则必须将它们放入隐藏的输入字段中。
@for (var i = 0; i < Model.AvailableReviewTemplates.Count; i++)
{
<li class="list-group-item">
@Html.HiddenFor(m => m.AvailableReviewTemplates[i].ReviewId)
@Html.HiddenFor(m => m.AvailableReviewTemplates[i].ReviewDate)
@Html.HiddenFor(m => m.AvailableReviewTemplates[i].TypeOfReview)
@Html.RadioButtonFor(m => m.ReviewSelected, Model.AvailableReviewTemplates[i].ReviewId)
<label>
@Model.AvailableReviewTemplates [i].ReviewDate.ToShortDateString()
-
@Model.AvailableReviewTemplates[i].TypeOfReview
</label>
</li>
}
或更好
使用ajax
提交表单,即使用Ajax.BeginForm()
. Ajax.BeginForm()
确实需要jquery.unobtrusive-ajax.js
包。
@model CreateReportViewModel
@{
AjaxOptions ajaxOpts = new AjaxOptions
{
HttpMethod = "POST",
OnBegin = "onFormBegin",
OnComplete = "onFormComplete"
// There are more options
};
}
@using (Ajax.BeginForm("create", "report", new { area = "" }, ajaxOpts, new { @id = "selectedStatusForm" }))
{
...
}
@section scripts {
<script type="text/javascript">
$(function() {
window.onFormBegin = function() {
// define what you want to do before form post begins
// i.e., spins loading icon?
};
window.onFormComplete = function(request, status) {
// I have a response object returned from the controller in
// JSON format so that I can do these. It's up to you to
// define a response object from the controller.
var response = request.responseJSON;
if (response.isOK) {
...
}
};
});
</script>
}
因此,我将通过Ajax
调用添加执行此操作的选项:
模型
public class MyModel
{
public string Name { get; set; }
public int Id { get; set; }
}
控制器
public class HomeController : Controller
{
public ActionResult MyAction(MyModel model)
{
// ... controller logic here
return View();
}
}
阿贾克斯/视图
@model List<myModel>
<ul class="list-group">
@for (var i = 0; i < Model.Count; i++)
{
<li class="list-group-item">
@Html.RadioButton("reviewSelected", Model[i].ID.ToString())
@Html.Label(Model[i].ReviewDate.ToShortDateString()) - @Html.Label(Model[i].TypeOfReview)
</li>
@Html.Hidden("ID", Model[i].ID.ToString()) // This persists
}
</ul>
<input type="submit" id="my-submit" class="btn btn-warning" />
<script>
$('#my-submit').on("click", function() {
var modelObject = {
"Name": $('#reviewSelected').val(),
"Id": $('#ID').val()
};
$.ajax({
type: "POST",
url:"../Home/MyAction",
dataType: "json",
data: modelObject,
error:function(eroor){alert("opps it broke");},
success: function (data) {
// do stuff with data
}
});
});
</script>
而是使用帮助程序将整个事情序列化为单个隐藏字段,因为当维护导致向模型添加一些新字段时,它不应该中断。
@Html.Hidden("model", new Microsoft.Web.Mvc.MvcSerializer().Serialize(Model[i]))
然后在控制器中:
public ActionResult MyAction([Deserialize] myModel model)
控制器的操作方法顶部写入[HttpPost]
。
现在,当您提交表单时,它将查找并检测您的操作方法,并将表单数据(模型)发送给它。