Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does Page() method in Razor Pages OnPost method do?

ASP NET CORE 2 I have following page model code

public class CreateModel : PageModel
{
    private readonly IItemService _itemService;
    public ItemCreateViewModel ItemModel { get; set; }

    public CreateModel(IItemService itemService)
    {
        _itemService = itemService;
    }
    // all related data downloaded from db, so all rendered correctly
    public async Task OnGet(ItemCreateViewModel itemModel)
    {
        ItemModel = await _itemService.GetCreateViewModel();
    }

    public async Task<IActionResult> OnPost(ItemCreateViewModel itemModel)
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }
        var item = _itemService.CreateItem(itemModel);
        var image = await ImagesController.ProcessFormImage(itemModel.ImageUpload.UploadPhoto, item.Id, ModelState);
        if (!ModelState.IsValid)
        {
            //trouble is somewhere here 
            return Page();
        }
        await _itemService.SaveItemImage(image);
        _itemService.CreateItem(itemModel);
        return RedirectToPage("./Index");
    }
}

When I try to post wrong image, !ModelState.IsValid yeilds true and Page() invoked. I get NullReferenceException: Object reference not set to an instance of an object. in Model.ItemModel.Categories where Categories is one of serveral select lists normally downloaded from db by _itemService.GetCreateViewModel(). I do not understand what happens at Page(). Why isn't old data from form used? How can I rerender page with validation errors (I have asp-validation-for in cshtml)? I tried this.ItemModel = itemModel, and I get no more Null reference, but do not see any validation errors, and previous select lists values not saved.

like image 356
Alexander Kozachenko Avatar asked May 28 '18 13:05

Alexander Kozachenko


1 Answers

return Page is the same as calling return View() in the normal MVC Controller action.

When the submitted form has validation errors (that are passed to the server), the OnPostAsync handler method calls the Page helper method. Page returns an instance of PageResult. Returning Page is similar to how actions in controllers return View. PageResult is the default return type for a handler method. A handler method that returns void renders the page.

Update the page model property to allow the view to bind to the model.

public class CreateModel : PageModel {
    private readonly IItemService _itemService;

    public CreateModel(IItemService itemService) {
        _itemService = itemService;
    }

    [BindProperty]
    public ItemCreateViewModel ItemModel { get; set; }

    // all related data downloaded from db, so all rendered correctly
    public  async Task<IActionResult>  OnGetAsync() {
        ItemModel = await _itemService.GetCreateViewModel();
        return Page();
    }

    public async Task<IActionResult> OnPostAsync() {
        if (!ModelState.IsValid) {
            return Page();
        }
        var item = _itemService.CreateItem(ItemModel);
        var image = await ImagesController.ProcessFormImage(ItemModel.ImageUpload.UploadPhoto, item.Id, ModelState);
        if (!ModelState.IsValid) {                
            return Page();
        }

        await _itemService.SaveItemImage(image);
        _itemService.CreateItem(ItemModel);
        return RedirectToPage("./Index");
    }
}

Reference Introduction to Razor Pages in ASP.NET Core

like image 142
Nkosi Avatar answered Sep 27 '22 23:09

Nkosi