Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
710 views
in Technique[技术] by (71.8m points)

asp.net mvc form includes for loop over form controllers

i want to submit a form with for loop inside of it that loops over the form controllers since i want to pass list of model into a post method action in such a way that each and every form controller ( TextBoxFor ) is populated by corresponding value of my list of model

my Model :

public class ExcelRowData
{
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public string Score { get; set; }
    public string EnrollmentTime { get; set; }
    public string GraduationTime { get; set; }
}

and this is my view :

@model List<NewTest.Models.ExcelRowData>
@using (Html.BeginForm("Delete", "MyTest", FormMethod.Post))
{
    for (var i = 0 ; i < Model.Count ; i++)
    {
        <tr>
            <td>@Html.TextBoxFor(p => Model[i].LastName)</td>
            <td>@Html.TextBoxFor(p => Model[i].FirstName)</td>
            <td>@Html.TextBoxFor(p => Model[i].Score)</td>
            <td>@Html.TextBoxFor(p => Model[i].EnrollmentTime)</td>
            <td>@Html.TextBoxFor(p => Model[i].GraduationTime)</td>
            <td><input type="submit" formaction="@Url.Action("Delete", "MyTest", new {Ln = Model[i].LastName})" value="Delete"/></td>
        </tr>
    }
}

i populated my model from excel file then i show the excel data in above table in view and then there is a delete button in case of deleting a record

and in my delete action i delete the selected record by the parameter passed from submit button , after that i repopulate my model and again i pass it to the same view

this is the delete action in my controller :

[HttpPost]
public ActionResult Delete(ExcelRowData evm, string Ln)
{
    var exceldata = new List<ExcelRowData>();

    var del = evm.FirstOrDefault(p => p.LastName == Ln);
    evm.Remove(del);

    foreach (var item in evm)
    {
        exceldata.Add(
            new ExcelRowData { LastName = item.LastName, FirstName = item.FirstName, Score = item.Score, EnrollmentTime = item.EnrollmentTime, GraduationTime = item.GraduationTime}
            );
    }

    return View("ExcelTable", exceldata);
}

the problem is when i press delete button in any row , it delets the record from bottom of the list , it doesn't matter which row i click to delete , it deletes from bottom of the list.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You posting back the whole collection, so all the property values have been added to ModelState, and the HtmlHelper methods that generate form controls (except PasswordFor()) use the values from ModelState (if they exist) rather the the property value.

You can solve this by adding

ModelState.Clear();

before you return the view, however the correct approach is to follow the PRG (Post, Redirect Get) pattern, and redirect to your GET method.

To understand why the HtmlHelper methods use ModelState, refer this answer.

As a side note, you can improve performance by using ajax to remove the item (and if successfully deleted, remove the corresponding row from the DOM), but that means you also need to include a hidden input for the collection indexer so that you can post back non-zero/non-consecutive indexers if your also posting back the updated collection elsewhere in your view. The input would be <input type="hidden" name="Index" value = "@i" />


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...