Home > Enterprise >  Multiple create models in one razor view (ASP.NET Core)
Multiple create models in one razor view (ASP.NET Core)

Time:08-31

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.

  • Related