I have multiple create
forms in my view and they always send null data to the controller.
Here's my code View model:
public class IndexModel : PageModel
{
public List<Device> devicelist { get; set; }
public Process proclist { get; set; }
public Extratime extras { get; set; }
public Foodadd foods { get; set; }
public void OnGet()
{
devicelist = new List<Device>();
proclist = new Process();
extras = new Extratime();
foods = new Foodadd();
}
}
And one of the forms in my view which always sends null data:
<form method="post" asp-action="AddTime" style="direction: rtl;">
<input type="hidden" asp-for="@Model.proclist.DeviceId" value="@item.Id" />
<input type="hidden" asp-for="@Model.proclist.Userid" value="@currentUser.Id" />
<div >
<select asp-for="@Model.proclist.IsLimited" id="cc">
<option value="true">limited</option>
<option value="false">Open</option>
</select>
</div>
<div id="pp">
<input type="number" asp-for="@Model.proclist.hours" placeholder="1.5" step=".01">
</div>
<div >
<select asp-for="@Model.proclist.IsSingle" >
<option value="true">single</option>
<option value="false">multi</option>
</select>
</div>
<button type="submit" >Enable</button>
</form>
That's what my controller expects from my view ( returns a NullReferenceException for the lack of data from the view. ):
public IActionResult AddTime(Process data)
{
using (KoraContext db = new KoraContext())
{
var tdevice = db.Devices.Where(x => x.Id == data.DeviceId).FirstOrDefault();
tdevice.Isbusy = "true"; // Gives a NullReferenceException.
db.Processes.Add(data);
db.SaveChanges();
return RedirectToAction("index", new { Controller = "Home", Action = "Index" });
}
}
CodePudding user response:
You have a form with method="post" but your page model doesn't have OnPost method. You also need to add [BindProperty]
attribute:
public class IndexModel : PageModel
{
public List<Device> devicelist { get; set; }
[BindProperty]
public Process proclist { get; set; }
public Extratime extras { get; set; }
public Foodadd foods { get; set; }
public void OnGet()
{
devicelist = new List<Device>();
proclist = new Process();
extras = new Extratime();
foods = new Foodadd();
}
public void OnPost()
{
// do something with proclist
}
}
https://www.learnrazorpages.com/razor-pages/forms
Edit:
You can add multiple OnPost handlers like this (Named Handler Methods):
public void OnPostAddTime()
{
...
}
public void OnPostAddFood()
{
...
}
And the forms:
<form asp-page-handler="addtime" method="post">
...
</form>
<form asp-page-handler="addfood" method="post">
...
</form>
https://www.learnrazorpages.com/razor-pages/handler-methods
CodePudding user response:
I think you misunderstand the way of using Razor Page
. In Razor Page
, There is no Controller
in Backstage, So if you want to set HttpGet
or HttpPost
action, you need to set the method name like OnGetxxxx
and OnPostxxx
(xxx is method Name), Then if you want to pass model between PageModel
and View
, You need to add [BindProperty]
, So in your PageModel, You need to change the code like:
public class IndexModel : PageModel
{
public List<Device> devicelist { get; set; }
[BindProperty]
public Process proclist { get; set; }
public Extratime extras { get; set; }
public Foodadd foods { get; set; }
public void OnGet()
{
devicelist = new List<Device>();
proclist = new Process();
extras = new Extratime();
foods = new Foodadd();
}
public IActionResult OnPostAddTime()
{
using (KoraContext db = new KoraContext())
{
var tdevice = db.Devices.Where(x => x.Id == proclist.DeviceId).FirstOrDefault();
tdevice.Isbusy = "true"; // Gives a NullReferenceException.
db.Processes.Add(proclist);
db.SaveChanges();
return RedirectToPage(xxxxxxx);
}
}
}
Then in the view, You can use asp-page-handler=xxx
to specify whtich method you want to submit.
More information you can refer to this link.