Вернуть JSON в IHttpModule WebAPI - PullRequest
0 голосов
/ 08 мая 2018

Я использую приведенный ниже код для обработки базовой авторизации в моем проекте WebAPI. Он отлично работает, но я бы хотел настроить Response, возвращающий данные JSON на основе определенного класса. Возможно ли это?

Пример класса, который я хочу вернуть:

public class BasicResponse 
{ 
    public bool Valid {get;set;} 
    public string[] Messages { get; set;}
}

public class BasicAuthHttpModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.AuthenticateRequest += Context_AuthenticateRequest; 
    }

    private void Context_AuthenticateRequest(object sender, EventArgs e)
    {
        var request = HttpContext.Current.Request;
        var authHeader = request.Headers["Authorization"];
        if (authHeader != null)
        {
            var authHeaderVal = AuthenticationHeaderValue.Parse(authHeader);

            // RFC 2617 sec 1.2, "scheme" name is case-insensitive
            if (authHeaderVal.Scheme.Equals("basic", StringComparison.OrdinalIgnoreCase) &&
                authHeaderVal.Parameter != null)
            {
                AuthenticateUser(authHeaderVal.Parameter);
            }
        }
    }

    // TODO: Here is where you would validate the username and password.
    private static bool CheckOnRightNow(string credentials)
    {
        return true;
    }

    private static void AuthenticateUser(string credentials)
    {
        try
        {
            var encoding = Encoding.GetEncoding("iso-8859-1");
            var credentialsDecoded = encoding.GetString(Convert.FromBase64String(credentials));

            int separator = credentialsDecoded.IndexOf(':');
            string name = credentialsDecoded.Substring(0, separator);

            if (CheckOnRightNow(credentials))
            {
                var identity = new GenericIdentity(name);
                SetPrincipal(new GenericPrincipal(identity, null));
            }
            else
            {
                // Invalid username or password.
                HttpContext.Current.Response.StatusCode = 401;
            }
        }
        catch (FormatException)
        {
            // Credentials were not formatted correctly.
            HttpContext.Current.Response.StatusCode = 401;

        }
    }

    private static void SetPrincipal(IPrincipal principal)
    {
        Thread.CurrentPrincipal = principal;
        if (HttpContext.Current != null)
        {
            HttpContext.Current.User = principal;
        }
    }

    public void Dispose()
    {
    }

}

В настоящее время возвращается HTML-страница по умолчанию при установке StatusCode = 401:

<!DOCTYPE html>
<html>
    <head>
        <title>Access is denied.</title>
        <meta name="viewport" content="width=device-width" />
        <style>
         body {font-family:"Verdana";font-weight:normal;font-size: .7em;color:black;} 
         p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px}
         b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px}
         H1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red }
         H2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon }
         pre {font-family:"Consolas","Lucida Console",Monospace;font-size:11pt;margin:0;padding:0.5em;line-height:14pt}
         .marker {font-weight: bold; color: black;text-decoration: none;}
         .version {color: gray;}
         .error {margin-bottom: 10px;}
         .expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; }
         @media screen and (max-width: 639px) {
          pre { width: 440px; overflow: auto; white-space: pre-wrap; word-wrap: break-word; }
         }
         @media screen and (max-width: 479px) {
          pre { width: 280px; }
         }
        </style>
    </head>

    <body bgcolor="white">

            <span><H1>Server Error in '/' Application.<hr width=100% size=1 color=silver></H1>

            <h2> <i>Access is denied.</i> </h2></span>

            <font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">

            <b> Description: </b>An error occurred while accessing the resources required to serve this request. This may have been caused by an incorrect user name and/or password.
            <br><br>

            <b> Error message 401.1: </b>Logon credentials were not recognized. Make sure you are providing the correct user name and password. Otherwise, contact the Web server's administrator for help.<br><br>

    </body>
</html>

1 Ответ

0 голосов
/ 08 мая 2018

Да, это возможно.

Вы можете записать JSON в HttpContext.Current.Response, как это

var basicResponse = new BasicResponse { Valid = false; Messages = new string[] { "not valid" } };
var response = JsonConvert.SerializeObject(basicResponse);

HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ContentType = "application/json; charset=utf-8";
HttpContext.Current.Response.Write(response);
HttpContext.Current.Response.End();
...