1

How can i change the default response message with a custom one in MVC WebApi?

{ "Message": "Authorization has been denied for this request." }

Thanks in advance

This is my custom ResponseModel

public class DefaultResponseModel<T>
    {
        public string ResponseID { get; private set; }
        public DateTimeOffset ResponseDateTime { get; private set; }
        public string RequestMethod { get; private set; }
        public string IPAddress { get; private set; }
        public T Data { get; set; }

        public DefaultResponseModel(ApiController controller)
        {
            ResponseDateTime = DateTimeOffset.Now;
            RequestMethod = controller.Request.Method.ToString();
            if (controller.Request.Properties.ContainsKey("MS_HttpContext"))
            {
                var ctx = controller.Request.Properties["MS_HttpContext"] as HttpContextBase;
                if (ctx != null)
                {
                    IPAddress = ctx.Request.UserHostAddress;
                }
                else
                {
                    IPAddress = "--";
                }
            }
            ResponseID = controller.Request.Properties.FirstOrDefault(x => x.Key == "RequestID").Value.ToString();
        }
        public DefaultResponseModel(HttpRequestMessage Request)
        {
            ResponseDateTime = DateTimeOffset.Now;
            RequestMethod = Request.Method.ToString();
            if (Request.Properties.ContainsKey("MS_HttpContext"))
            {
                var ctx = Request.Properties["MS_HttpContext"] as HttpContextBase;
                if (ctx != null)
                {
                    IPAddress = ctx.Request.UserHostAddress;
                }
                else
                {
                    IPAddress = "--";
                }
            }
            ResponseID = Request.Properties.FirstOrDefault(x => x.Key == "RequestID").Value.ToString();


        }

I'd like to use it in the authorize code as you said, becouse i generate a ResponseID and i send it to my response model. I want to use the same model for each response.

  • OK, so why don't you do your logging in the custom authorize attribute then? – howcheng Nov 18 '19 at 21:14
  • But can i find a way to use my custom model in the authorize response? – Gianmarco Varriale Nov 18 '19 at 21:21
  • I don't understand what you mean by the "authorize response". The response sent is the 403. If you mean you want another component to do something after the authorize attribute is done, then perhaps you want another action filter attribute or an HTTP module. See https://stackoverflow.com/questions/11507496/http-module-vs-action-filter-in-asp-net-mvc for help with that. – howcheng Nov 18 '19 at 21:28
  • I Just want to modify the default response message ({ "Message": "Authorization has been denied for this request." }) with my custom class model if it's possible.. – Gianmarco Varriale Nov 18 '19 at 21:29
  • Now I'm confused. My answer shows you how to set the response message. If you want to use your object, then do it in the `HandleUnauthorizedRequest` method. Are you trying to put your `ResponseID` into the message? – howcheng Nov 18 '19 at 21:34

1 Answers1

1

You would have to create a class that derives from AuthorizeAttribute and override the HandleUnauthorizedRequest method. Something like this in Web API (note: this is not tested):

using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Controllers;

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
    {
        actionContext.Response = actionContext.Request.CreateErrorResponse(
            HttpStatusCode.Forbidden, 
            "Custom message goes here");
    }
}

Then wherever you were using AuthorizeAttribute, replace it with MyAuthorizeAttribute instead.

For MVC, you inherit System.Web.Mvc.AuthorizeAttribute instead.

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext actionContext)
    {
        actionContext.Result = new HttpStatusCodeResult(
            HttpStatusCode.Forbidden, 
            "Custom message goes here");
    }
}
howcheng
  • 2,211
  • 2
  • 17
  • 24
  • My question now is, how can it works? I'm using a custom response model, how can i implement this one? actionContext.Result = new HttpStatusCodeResult( HttpStatusCode.Forbidden, new DefaultResponseModel(actionContext.HttpContext.Request.UserHostAddress) { Data = "Authorization has been denied for this request!" }); – Gianmarco Varriale Nov 18 '19 at 20:31
  • Unfortunately, `HttpStatusCodeResult` doesn't take an object as a parameter. What are you trying to accomplish? Are you redirecting the 403 response to a custom error page? If so, you can store your object into the actionContext.Controller.TempData dictionary and then pull it out in the controller method. – howcheng Nov 18 '19 at 20:52
  • I'm using a custom response model becouse i have to send a ID that i generate in a logging handler, and i'd like to send it here too... how can i do it? – Gianmarco Varriale Nov 18 '19 at 21:02
  • Can you give more detail, please? – howcheng Nov 18 '19 at 21:05