有没有办法将模型从强类型视图传递到 List<object>?



如果我有一个强类型到模型列表的视图,有没有办法从该列表中获取特定模型以传递给我的控制器?我目前正在循环访问所述列表并在复选框列表中吐出值。例如:

@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]

现在,当您提交表单时,它将查找并检测您的操作方法,并将表单数据(模型)发送给它。

相关内容

最新更新