asp.net-mvc – MVC发布复杂对象的列表

前端之家收集整理的这篇文章主要介绍了asp.net-mvc – MVC发布复杂对象的列表前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个Feedbackviewmodel包含一个问题列表:
public class Feedbackviewmodel
{
    public List<Questionviewmodel> Questions { get; set; }
}

这个Questionviewmodel是一个可以由5种不同类型的问题继承的对象

public class Questionviewmodel
{
    public string QuestionText { get; set; }
    public string QuestionType { get; set; }
}

一个继承问题类型的例子:

public class SingleQuestionviewmodel : Questionviewmodel
{
    public string AnswerText { get; set; }
}

在控制器中的索引操作的HttpGet中,我从数据库获取问题,并在Feedbackviewmodel中的问题列表中添加正确的问题类型然后在视图中渲染此模型:

@using (Html.BeginForm())
{
    //foreach (var item in Model.Questions)
    for (int i = 0; i < Model.Questions.Count; i++)
    {
        <div class="form-group">
            @Html.DisplayFor(modelItem => Model.Questions[i].QuestionText,new { @class = "control-label col-md-4" })
            <div class="col-md-6">
                @if (Model.Questions[i].QuestionType == "Single")
                {
                    @Html.EditorFor(modelItem => (Model.Questions[i] as OpenDataPortal.viewmodels.SingleQuestionviewmodel).AnswerText)
                }
                else if (Model.Questions[i].QuestionType == "Multiple")
                {
                    @Html.TextAreaFor(modelItem => (Model.Questions[i] as OpenDataPortal.viewmodels.SingleQuestionviewmodel).AnswerText)
                }
                else if (Model.Questions[i].QuestionType == "SingleSelection")
                {
                    @Html.RadioButtonForSelectList(modelItem => (Model.Questions[i] as OpenDataPortal.viewmodels.SingleSelectionQuestionviewmodel).SelectedAnswer,(Model.Questions[i] as OpenDataPortal.viewmodels.SingleSelectionQuestionviewmodel).SelectionAnswers)
                }
                else if (Model.Questions[i].QuestionType == "MultipleSelection")
                {
                    @Html.CustomCheckBoxList((Model.Questions[i] as OpenDataPortal.viewmodels.MultipleSelectionQuestionviewmodel).AvailableAnswers)
                }
                else if (Model.Questions[i].QuestionType == "UrlReferrer")
                {
                    @Html.EditorFor(modelItem => (Model.Questions[i] as OpenDataPortal.viewmodels.SingleQuestionviewmodel).AnswerText)
                }
            </div>
        </div>
        <br />
    }

    <br />
    <button type="submit">Submit</button>
}

现在,我根本无法让它在模型中发布问题列表.是否可以发布不同对象类型的列表?

编辑:以下是我发现使用Fiddler的帖子中的数据列表:

解决方法

经过多次研究,我发现了两个解决方案:

一个是编写具有硬编码的Id和Name的HTML
二是将您的ICollection / IEnumerable转换为数组或列表(即使用“索引”来IList),并在Controller POST Action中的BindingModel中有一个Array对象.

感谢Phil Haack(@haacked)2008年博客文章http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/
哪个仍然与默认的ModelBinder如何在MVC上工作有关.
(注意:菲尔文章中关于采样和扩展方法链接被打破)

启发我的HTML片段:

<form method="post" action="/Home/Create">
    <input type="hidden" name="products.Index" value="cold" />
    <input type="text" name="products[cold].Name" value="Beer" />
    <input type="text" name="products[cold].Price" value="7.32" />

    <input type="hidden" name="products.Index" value="123" />
    <input type="text" name="products[123].Name" value="Chips" />
    <input type="text" name="products[123].Price" value="2.23" />

    <input type="submit" />
</form>

后阵列看起来有点像:

products.Index=cold&products[cold].Name=Beer&products[cold].Price=7.32&products.Index=123&products[123].Name=Chips&products[123].Price=2.23

模型:

public class Creditorviewmodel
{
    public Creditorviewmodel()
    {
        this.Claims = new HashSet<CreditorClaimviewmodel>();
    }
    [Key]
    public int CreditorId { get; set; }
    public string Comments { get; set; }
    public ICollection<CreditorClaimviewmodel> Claims { get; set; }
    public CreditorClaimviewmodel[] ClaimsArray { 
        get { return Claims.ToArray(); }
    }
}

public class CreditorClaimviewmodel
{
    [Key]
    public int CreditorClaimId { get; set; }
    public string CreditorClaimType { get; set; }
    [DisplayFormat(ApplyFormatInEditMode = true,DataFormatString = "{0:N2}")]
    public Decimal ClaimedTotalAmount { get; set; }
}

控制器GET:

public async Task<ActionResult> Edit(int id)
    {
        var testmodel = new Creditorviewmodel
        {
            CreditorId = 1,Comments = "test",Claims = new HashSet<CreditorClaimviewmodel>{
                new CreditorClaimviewmodel{ CreditorClaimId=1,CreditorClaimType="1",ClaimedTotalAmount=0.00M},new CreditorClaimviewmodel{ CreditorClaimId=2,CreditorClaimType="2",}
        };
        return View(model);
    }

Edit.cshtml:

@Html.DisplayNameFor(m => m.Comments)
@Html.EditorFor(m => m.Comments)

<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(m => Model.Claims.FirstOrDefault().CreditorClaimType)
        </th>
        <th>
            @Html.DisplayNameFor(m => Model.Claims.FirstOrDefault().ClaimedTotalAmount)
        </th>
    </tr>        
<!--Option One-->
@foreach (var item in Model.Claims)
{
    var fieldPrefix = string.Format("{0}[{1}].","Claims",item.CreditorClaimId);
    <tr>
        <td>
            @Html.DisplayFor(m => item.CreditorClaimType)
        </td>
        <td>
        @Html.TextBox(fieldPrefix + "ClaimedTotalAmount",item.ClaimedTotalAmount.ToString("F"),new
        {
            @class = "text-Box single-line",data_val = "true",data_val_number = "The field ClaimedTotalAmount must be a number.",data_val_required = "The ClaimedTotalAmount field is required."
        })
        @Html.Hidden(name: "Claims.index",value: item.CreditorClaimId,htmlAttributes: null)
        @Html.Hidden(name: fieldPrefix + "CreditorClaimId",htmlAttributes: null)
        </td>
    </tr>
    }
</table>    
<!--Option Two-->
@for (var itemCnt = 0; itemCnt < Model.ClaimsArray.Count(); itemCnt++)
{
    <tr>
        <td></td>
        <td>
            @Html.TextBoxFor(m => Model.ClaimsArray[itemCnt].ClaimedTotalAmount)
            @Html.HiddenFor(m => Model.ClaimsArray[itemCnt].CreditorClaimId)
    </td></tr>
}

表单在控制器中处理:

邮政型号:

public class CreditorPostviewmodel
{
    public int CreditorId { get; set; }
    public string Comments { get; set; }
    public ICollection<CreditorClaimPostviewmodel> Claims { get; set; }
    public CreditorClaimPostviewmodel[] ClaimsArray  { get; set; }
}

public class CreditorClaimPostviewmodel
{
    public int CreditorClaimId { get; set; }
    public Decimal ClaimedTotalAmount { get; set; }
}

控制器:

[HttpPost]
    public ActionResult Edit(int id,CreditorPostviewmodel creditorVm)
    {
        //...

猜你在找的asp.Net相关文章