Sebastian
Sebastian

Reputation: 4811

List is NULL while POST from View

I use the below Action to allow the user to see a preview of Excel import

[HttpGet]
[Authorize]
public ActionResult ImportVerify()
{
    string temp_sessionname = "ImportedData_" + User.Identity.Name;
    List<ProjectImportModel> view_model = (List<ProjectImportModel>)TempData[temp_sessionname];
    return View(view_model);
}
[HttpPost]
[Authorize]
public ActionResult ImportVerify(List<ProjectImportModel> model)
{
    return View(model);
}

And on View i am using a table to show the List of imported data from excel and ask user to confirm the action of import

My view is like this

<h2>Import Verify</h2>
@using (Html.BeginForm())
{
@Html.ValidationSummary(true)
 //table with all details and a submit button in the end

  <div class="form-group">
    <div class="col-md-10" style="text-align:center;">
        <input type="submit" value="Submit" class="btn btn-primary" />         
    </div>
</div>
}

And model is

public class ProjectImportModel

{ public string Page { get; set; }

 public string Author { get; set; }

 public string Translator { get; set; }

 public string Holder { get; set; }

public string Title { get; set; }

public string TrTitle { get; set; }
//and similar 20 more properties of string type

}

But on POST the list is null

Is any way to get the list back at POST event. My intension is just to allow the preview to user

Or do i need to refill List from TempData @ post as well?

Upvotes: 2

Views: 110

Answers (3)

hutchonoid
hutchonoid

Reputation: 33306

In order to post a collection back you need to index the properties, if they're readonly you can just use HiddenFor with a model. If you want the user to edit them, change them to TextBoxFor's instead or the control that you data requires.

@model List<ProjectImportModel>
<h2>Import Verify</h2>
@using (Html.BeginForm())
{
@Html.ValidationSummary(true)
 //table with all details and a submit button in the end

  <div class="form-group">
    <div class="col-md-10" style="text-align:center;">
        @for(var i = 0 ; i < Model.Count; i++)
        {
          @Html.HiddenFor(m => m[i].Foo) 
          @Model[i].Foo <br/>
        }
        <input type="submit" value="Submit" class="btn btn-primary" />         
    </div>
</div>
}

I just used a dummy property of Foo without seeing your model.

Obviously you would want to display the data too.

Model Binding To A List

Upvotes: 3

BgrWorker
BgrWorker

Reputation: 679

There are some requirements to post a list back to a controller. Specifically, indexes must be 0-based and unbroken (example, you can bind a list with indexes [0], [1], [2] but not one with [0], [1], [3] or [1], [2], [3].

Alternatively, you could write a custom model binder to parse the request body the way you like.

More on this here: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/

EDIT: Here is an example on how to do it:

Given the following model

public class ExampleModel
{
    public int Field1 {get; set;}
    public string Field2 {get; set;}
}

And the following actions

[HttpGet]
[Authorize]
public ActionResult ImportVerify()
{
    List<ExampleModel> model = //populate the list somehow
    return View(model);
}

[HttpPost]
[Authorize]
public ActionResult ImportVerify(List<ExampleModel> model)
{
    //do something
}

The example view "ImportVerify.cshtml" would be:

@model List<ExampleModel>

@using(Html.BeginForm())
{
    for(var i = 0; i < Model.Count; i++)
    {
       <div>
            @Html.HiddenFor(m => m[i].Field1);
            @Html.HiddenFor(m => m[i].Field2);
            <p>
                Value @i : Field1 = @m[i].Field1 , Field2 = @m[i].Field2
            </p> 
        </div>
    }
    <input type="submit" value="Send"/>
}

Also, I would revise your logic a bit, to avoid the use of TempData (generally bad practice) and to allow strongly typed views.

Upvotes: 0

Liem Do
Liem Do

Reputation: 943

I don't see the snippet code that set your TempData. So I intend that you set it in another Action and then redirect to the ImportVerify Action

TempData keep the information for the time of an HTTP Request. This mean only from one page to another. It's mean that after redirect to your ImportVerify Get Action the data is expired. If you want to keep the data you can try the following ways:

  • Create a hidden List in your page
  • Use Session instead of TempData

Upvotes: 1

Related Questions