JeffreySu/WeiXinMPSDK · error · WeixinNullReferenceException

httpContext.Request.Url 不能为null!

Error message

httpContext.Request.Url 不能为null!

What it means

GenerateOAuthCallbackUrl builds the fully-qualified OAuth redirect/callback URL from the current ASP.NET request. Under .NET Framework (NET462) it reads httpContext.Request.Url; if that is null the library throws WeixinNullReferenceException instead of letting a confusing NullReferenceException surface later. This guards URL construction that requires scheme/host/port data.

Solutions

  1. Only call GenerateOAuthCallbackUrl inside an active HTTP request where Request.Url is populated
  2. Check httpContext.Request?.Url != null before calling
  3. In tests, build a complete HttpRequest with a valid Url (e.g. HttpRequest with http://localhost)
  4. If under ASP.NET Core, ensure the NET462 branch is not compiled in and use the Core overload path

Example fix

// before
var url = UrlUtility.GenerateOAuthCallbackUrl(httpContext, "oauthCallback");
// after
if (httpContext?.Request?.Url == null)
{
    throw new InvalidOperationException("GenerateOAuthCallbackUrl requires an active request with Request.Url");
}
var url = UrlUtility.GenerateOAuthCallbackUrl(httpContext, "oauthCallback");
Defensive patterns

Strategy: type-guard

Validate before calling

if (httpContext?.Request?.Url == null) throw new InvalidOperationException("GenerateOAuthCallbackUrl requires an active HTTP request");

Type guard

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

Try / catch

try { var url = UrlUtility.GenerateOAuthCallbackUrl(httpContext, "oauthCallback"); }
catch (WeixinNullReferenceException ex) { log.Warn("No Request.Url available", ex); /* skip OAuth flow */ }

Prevention

When it happens

Trigger: Calling GenerateOAuthCallbackUrl with an HttpContext whose Request.Url is null — typically when invoked outside a real HTTP request pipeline (e.g. Application_Start, background thread, self-hosted/test context) or a request without a URL.

Common situations: OAuth redirect setup during app startup, unit tests constructing a bare HttpContext without a Url, hosting environments (custom handlers, OWIN bridges) that do not populate Request.Url.

Related errors


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

Appendix: source

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

    {
        /// <summary>
        /// 生成OAuth用的CallbackUrl参数(原始状态,未整体进行UrlEncode)
        /// </summary>
        /// <param name="httpContext"></param>
        /// <param name="oauthCallbackUrl"></param>
        /// <returns></returns>
#if NET462
        public static string GenerateOAuthCallbackUrl(HttpContextBase httpContext, string oauthCallbackUrl)
#else
        public static string GenerateOAuthCallbackUrl(HttpContext httpContext, string oauthCallbackUrl)
#endif
        {

#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();    

View on GitHub (pinned to be573f6f94)