Reputation: 4811
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
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.
Upvotes: 3
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
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:
Session
instead of TempData
Upvotes: 1