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

时间:2017-10-27 16:10:46

标签: asp.net-mvc

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

@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){}

在上面的示例中,我可以使用&#34; reviewSelected&#34;作为一个参数,并获得这个价值,但我不能说&#34;给我这个在这个单选按钮上发现的模型&#34;。

我并不反对使用ajax,但我没有成功将其序列化以通过。我的模型仍然无效。

4 个答案:

答案 0 :(得分:1)

如果只有一个参数reviewSelected不够好,您可能必须定义一个视图模型来包装myModel列表和所选的审阅标识符,即reviewSelected。< / p>

注意:我刚刚编写了班级名称。

为MyModel

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>
}

答案 1 :(得分:0)

所以我通过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();
    }
}

Ajax / 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>

答案 2 :(得分:0)

而是使用帮助程序将整个事物序列化为单个隐藏字段,因为当维护导致向模型添加一些新字段时,它不应该中断。

@Html.Hidden("model", new Microsoft.Web.Mvc.MvcSerializer().Serialize(Model[i]))

然后在你的控制器中:

public ActionResult MyAction([Deserialize] myModel model)

答案 3 :(得分:0)

在控制器中的操作方法顶部写下[HttpPost]

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