JeffreySu/WeiXinMPSDK · error · WeixinNullReferenceException

httpContext.Request 不能为null!

Error message

httpContext.Request 不能为null!

What it means

In the ASP.NET Core (non-NET462) branch of GenerateOAuthCallbackUrl, the code requires a non-null HttpContext.Request to read the absolute URI, scheme and host. If httpContext.Request is null it throws WeixinNullReferenceException early with a descriptive message. This prevents downstream null failures while composing the OAuth callback URL.

Solutions

  1. Ensure the call happens within a real ASP.NET Core request where HttpContext.Request is set
  2. Guard with httpContext?.Request == null check before invoking
  3. In tests use DefaultHttpContext() which provides a populated Request
  4. If the request has already completed, capture the needed URL data during the request lifetime instead

Example fix

// before
var callbackUrl = UrlUtility.GenerateOAuthCallbackUrl(httpContext, "callback");
// after
if (httpContext?.Request == null)
{
    throw new InvalidOperationException("GenerateOAuthCallbackUrl requires a live HttpContext.Request");
}
var callbackUrl = UrlUtility.GenerateOAuthCallbackUrl(httpContext, "callback");
Defensive patterns

Strategy: type-guard

Validate before calling

if (httpContext?.Request == null) throw new InvalidOperationException("GenerateOAuthCallbackUrl requires HttpContext.Request");

Type guard

bool HasRequest(HttpContext ctx) => ctx?.Request != null;

Try / catch

try { var url = UrlUtility.GenerateOAuthCallbackUrl(httpContext, "oauthCallback"); }
catch (WeixinNullReferenceException ex) { log.Warn("HttpContext.Request unavailable", ex); }

Prevention

When it happens

Trigger: Calling GenerateOAuthCallbackUrl on an HttpContext that has no Request object — e.g. a manually constructed HttpContext in tests, or a context taken from outside the middleware pipeline.

Common situations: Unit tests with mock HttpContext lacking a Request property, integration code caching an HttpContext after the request ended, custom middleware passing a stripped context.

Related errors


AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12). Data as JSON: /api/errors/4f2a9088b27992f4. Report an issue: GitHub.

Appendix: source

Thrown at src/Senparc.Weixin.AspNet/Utilities/HttpUtility/UrlUtility.cs:100

#if NET462

            if (httpContext.Request.Url == null)
            {
                throw new WeixinNullReferenceException("httpContext.Request.Url 不能为null!", httpContext.Request);
            }

            var returnUrl = httpContext.Request.Url.ToString();
            var urlData = httpContext.Request.Url;
            var scheme = urlData.Scheme;//协议
            var host = urlData.Host;//主机名(不带端口)
            var port = urlData.Port;//端口
            string schemeUpper = scheme.ToUpper();//协议(大写)
            string baseUrl = httpContext.Request.ApplicationPath;//子站点应用路径
#else
            if (httpContext.Request == null)
            {
                throw new WeixinNullReferenceException("httpContext.Request 不能为null!", httpContext);
            }

            var request = httpContext.Request;
            //var location = new Uri($"{request.Scheme}://{request.Host}{request.Path}{request.QueryString}");
            //var returnUrl = location.AbsoluteUri; //httpContext.Request.Url.ToString();    
            var returnUrl = request.AbsoluteUri();
            var urlData = httpContext.Request;
            var scheme = urlData.Scheme;//协议
            var host = urlData.Host.Host;//主机名(不带端口)
            var port = urlData.Host.Port ?? -1;//端口(因为从.NET Framework移植,因此不直接使用urlData.Host)
            string schemeUpper = scheme.ToUpper();//协议(大写)
            string baseUrl = httpContext.Request.PathBase;//子站点应用路径
#endif

            //授权回调字符串
            var callbackUrl = Senparc.Weixin.HttpUtility.UrlUtility.GenerateOAuthCallbackUrl(scheme, host, port, baseUrl, returnUrl, oauthCallbackUrl);
            return callbackUrl;
        }

View on GitHub (pinned to be573f6f94)