Why is my model and its variables not passing from View to Method inside of my Controller?


Why is my model and its variables not passing from View to Method inside of my Controller?



My application searches for the files that contains a string the user is looking for. So far it does that perfectly. The last thing I need to do is to export it to an excel file so I added a method inside of my controller that is called by the Result page after I press a button.


Result



The results are stored in a List of type Result which is a class with four variables.


List


Result



The method ExportToExcel currently returns string so that I can test if the list of results is null. Every single time it has come out as "No Data", therefore it is null. It perfectly prints out a table with the information in the Results page but does not have the information when i want to export it.


ExportToExcel


Results



Why is my model not passing from view to method?



At first I wanted to pass my model so that I can access the information in the List but now I am wondering if it would be better to save the List data in the controller so that I can directly pass it to my method.


List


List



Either way would be fine and I am open to any other ways to do this.



Model


namespace Final.Models
{
public class InputModel:Result
{

public List<Result> Results { get; set; }

}
}



Controller



This controller is just showing how I am passing the InputModel between the views and method. Maybe I am doing something wrong here?


public ActionResult Index()
{
var input = new InputModel();
return View(input);
}

[HttpPost]
public ActionResult Index(InputModel input)
{
//Finds files that contain string.
//send model to Result
return View("Result", input);
}

public ActionResult Result(InputModel input)
{
return View(input);
}

[HttpPost]
public string Result(InputModel input,string export)
{

return ExportToExcel(input);
}

public string ExportToExcel(InputModel input)
{
if (input.Results!=null)
{
//Run excel code here
return "Excel Exported";
}
else
{
return "No Data";
}
}



View for Result



This is part of the view, not the whole thing. I didn't think the full view was necessary but I posted it in the bottom just in case.


@foreach(var result in Model.Results)
{

<tr>
//Return graph of information received
</tr>

}
</table>

<form action="Find/Result" method="POST">
<input type="submit" value="Export" name="export" class="btn btn-default">
</form>



Output



Occurs after pressing the "Export" Button


"No Data"



This is my first MVC applications so once again please let me know if there is any other area I can improve in.



Full View For Result



Changed the form to enclose the entire view as suggested by Wubbly but I get the same output.


@model Final.Models.InputModel

@{
ViewBag.Title = "Result";
Layout = "~/Views/Shared/_Layout.cshtml";
}




<br />
<h4>Result</h4>
<hr />


@using (Html.BeginForm("Result", "Find", FormMethod.Post))
{
<p>The <b>@Model.SelectedText</b> files that contain <b>"@Model.Find"</b> are: </p>




//HEADERS


@foreach (var result in Model.Results)
{
// int i = 1;








}
@result.SelectedText @result.FileName @result.Line @result.LineCode









</div>

</div>
}







<p>
@Html.ActionLink("Back to List", "Index")
</p>





It looks like you're submitting an empty form, as you can see your form only contains a button and nothing else, which is why the input.Results is null.
– Wubbler
Jun 29 at 19:33


input.Results





Why would you expect the InputModel to be populated if the form you submit is empty?
– mason
Jun 29 at 19:49





Is that your complete view? Have you copied everything to your question?
– bsod_
Jun 29 at 19:56





You're still not submitting any form elements. You should probably learn the basics of HTML Forms and how they POST data to web servers before learning ASP.NET MVC.
– mason
Jun 29 at 20:44





Your form has not form controls, so there is nothing to submit. And if you include form controls, then you cannot use a foreach loop (refer this answer. But what is the point of this - you are not editing anything so why in the world would you send back to the controller all the data you just sent from the controller - its just pointless extra overhead that would be degrading performance. If you need the data, then you get it again in the controller by calling the database.
– Stephen Muecke
Jun 29 at 22:47


foreach




2 Answers
2



Use for loop with hidden property which takes your property value to model.


@using (Html.BeginForm("Result", "Find", FormMethod.Post))
{
<p>The <b>@Model.SelectedText</b> files that contain <b>"@Model.Find"</b> are: </p>




//HEADERS


@for (int i = 0; i






}

@Html.HiddenFor(r => r.Model.Results[i].SelectedText)
@Html.HiddenFor(r => r.Model.Results[i].FileName)
@Html.HiddenFor(r => r.Model.Results[i].Line)
@Html.HiddenFor(r => r.Model.Results[i].LineCode)

@Html.DisplayFor(r => r.Model.Results[i].SelectedText)
@Html.DisplayFor(r => r.Model.Results[i].FileName) @Html.DisplayFor(r => r.Model.Results[i].Line) @Html.DisplayFor(r => r.Model.Results[i].LineCode)









</div>

</div>
}
<p>
@Html.ActionLink("Back to List", "Index")
</p>



To anyone who might need an answer and is in a similar situation I figured my problem out. Many of you might not think it is the right way to fix it but it is what worked for me. Either way any feedback would be appreciated to improve my abilities.



First, I did change my foreach to a for loop as recommended by StephenMuecke and ShailendraKumar.


foreach


for



The way I transferred the data from my HTTPGet to my HTTPPostis with TempData. I used it to store my model with the user's input inside my HTTPPost Index and called it in my HTTPPost Result.


HTTPGet


HTTPPost


TempData


HTTPPost


HTTPPost


Result



Here's how I changed my controller.


public ActionResult Index()
{
var input = new InputModel();
input.Type = input.FillType(input.Type);

return View(input);
}

[HttpPost]
public ActionResult Index(InputModel input)
{
input.FileType = input.ValueConvert();
input.FileFind();
TempData["model"] = input
return View("Result", input);
}

public ActionResult Result(InputModel input)
{
return View(input);
}


[HttpPost]
public void Result()
{
InputModel model = new InputModel();
model = (InputModel)TempData["model"];
model.ExportToExcel();
}






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

Export result set on Dbeaver to CSV

Opening a url is failing in Swift