Aspnetboilerplate: Razor Pages JsonResult actions not returning JSON

Created on 12 Apr 2019  ·  3Comments  ·  Source: aspnetboilerplate/aspnetboilerplate

As per documentation Handling Exceptions # Ajax Requests

If the return type of an MVC action is a JsonResult (or Task

This doesn't work for Razor Pages, PageModel action will simply throw an exception.

public async Task<JsonResult> OnPostAsync()
{
    throw new UserFriendlyException("Test");
}

image

Tested with latest module-zero-core-template updated to ABP 4.5.0

Most helpful comment

I will try it, thank you for your code.

All 3 comments

The razor page does not have its own authorization and exception filters, although mvc authorization and exception filters can be used.
But in the filter can not get the current page execution method information (such as onget or onpost).

Limited to this, this feature is not possible

@maliming I've looked into it and it should be possible with Razor Pages own IPageFilter

OnPageHandlerSelected : Called after a handler method has been selected, but before model binding occurs.
OnPageHandlerExecuting : Called before the handler method executes, after model binding is complete.
OnPageHandlerExecuted : Called after the handler method executes, before the action result.

In OnPageHandlerExecuted it should be possible to get all the necessary info on the executing method and handle it before the action result in similar fashion to MVC.


I wrote this quick code that demonstrates method information extraction and exception handling

Pages/Test.cshtml

@page
@model AbpCompanyName.AbpProjectName.Web.Mvc.Pages.TestModel

<form method="post">
    <button asp-page-handler="Json">Submit to JSON handler</button>
    <button asp-page-handler="ActionResult">Submit to ActionResult handler</button>
</form>

Pages/Test.cshtml.cs

using Abp.UI;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Threading.Tasks;

namespace AbpCompanyName.AbpProjectName.Web.Mvc.Pages
{
    public class TestModel : PageModel
    {
        public void OnGet()
        {
        }

        public async Task<JsonResult> OnPostJsonAsync() => throw new UserFriendlyException("This should return json");

        public async Task<IActionResult> OnPostActionResultAsync() => throw new UserFriendlyException("This should return exception");

        public override void OnPageHandlerExecuted(PageHandlerExecutedContext context)
        {
            var method = context.HandlerMethod.MethodInfo;

            var isJsonResult =
                typeof(JsonResult).IsAssignableFrom(method.ReturnType)
                || typeof(Task<JsonResult>).IsAssignableFrom(method.ReturnType);

            if (!isJsonResult || context.ExceptionHandled)
            {
                base.OnPageHandlerExecuted(context);
                return;
            }

            context.HttpContext.Response.Clear();
            context.HttpContext.Response.StatusCode = 500;
            context.ExceptionHandled = true;
            context.Result = new JsonResult(new[] { context.Exception.GetType().Name, context.Exception.Message });
        }
    }
}

I will try it, thank you for your code.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

apchenjun picture apchenjun  ·  3Comments

iyilm4z picture iyilm4z  ·  3Comments

iyhammad picture iyhammad  ·  3Comments

Gardens18 picture Gardens18  ·  3Comments

sylfree9999 picture sylfree9999  ·  3Comments