Im generating a List in my CalculationsController in post method CalculateMenu(). In this method Im drawing a table to represent a list, and a button. The button should send this list to another controller. How to do it? What do I need to attach so you can help me?
CalculateMenu method:
[HttpPost]
public async Task<IActionResult> CalculateMenu([FromForm] int[] peopleCount, [FromForm] DateOnly date)
{
StringBuilder resultString = new StringBuilder();
resultString.AppendLine("<style>table, th, td {\n table-layout: fixed; \n border: 1px solid; \n width: 100%; \n border-collapse: collapse; \n}</style>");
resultString.AppendLine("<h1>Answer:</h1>");
var resultIngredients = await _calculationsService.CalculateIngredients(peopleCount, date);
resultString.Append(CalculateTotalWeightOfEveryIngredient(resultIngredients));
resultString.Append(await CalculatePrice(peopleCount, date));
//How to generate a button? What did i tried:
//resultString.AppendLine($"<form method=\"what method should i use in this case?\" action=\"put here address of second controller(dont know how)">\n <button type=\"submit\"> submit </button>\n</form>");
return Content(resultString.ToString(), "text/html; charset=utf-8");
}
[HttpPost]
[Route("api/calculations/send")]
public ActionResult Send()
{
TempData["mydata"] = "111";
return RedirectToAction("SaveReport", "ReportController");
}
string serializedIngedientsList = JsonSerializer.Serialize(resultIngredients);
resultString.AppendLine($"<button role=\"button\" class=\"sendBtn\"><a href=\"www.siteadress/api/reports/{serializedIngedientsList}\" style=\"text-decoration: none; color: #000000\"> Отчёт </a></button>");
So I took a while to consider your question and in my opinion you got it wrong, as you are going against MVC principle and you are mixing controller and view by putting HTML inside controller's code.
So to do it the right way, you'd need to add view and controller for actions related to menu.
For example consider below:
Views/Menu
contains Index.cshtml
page with following simple form code:
@{
ViewData["Title"] = "View";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>View</h1>
<form asp-action="CalculateMenu" method="post">
<label for="peopleCount">People count:</label><br>
<input type="text" id="peopleCount" name="peopleCount" value="0"><br>
<label for="date">Date:</label><br>
<input type="date" id="date" name="date" value=""><br><br>
<input type="submit" value="Submit">
</form>
And the HomeController
has the below code:
using Microsoft.AspNetCore.Mvc;
using System.Text;
using System.Threading.Tasks;
using System;
using System.Linq;
namespace TestAspNetMvc.Controllers;
public class MenuController : Controller
{
public IActionResult Index()
{
return View();
}
[HttpPost]
public async Task<IActionResult> CalculateMenu(
[FromForm] string peopleCount,
[FromForm] DateTime date)
{
// You need to add necessary error handling if input is wrong.
var peopleCountParsed = peopleCount.Split(',')
.Select(x => int.Parse(x))
.ToArray();
// your logic here
// Here we are using the method to redirect and provide additional data.
return RedirectToAction("Index", "Test", routeValues: new { peopleCount });
}
}
// This is just very simple controller for presentation purposes.
public class TestController : Controller
{
public IActionResult Index(string peopleCount)
{
return Ok();
}
}
So the idea is to create separate HTML file with form, and keep all logic in controllers. There we can use method RedirectToAction
which allows providing routeValues
which can be used to forward query parameters.
And also - I switched peopleCount
type to string
and date
to DateTime
, but you can adjust as necessary, but I guess for complex structures you could just post JSON body instead of form data.
EDIT
In order for user to be able to send another request to other controller with the parameter set in form, the easiest way is to add a
element with proper href
attribute:
<a href="/test?peopleCount={value of param}" />