【问题标题】:Problem with null object reference in Url.Action in MVC3 projectMVC3 项目中 Url.Action 中的空对象引用问题
【发布时间】:2011-07-24 12:07:15
【问题描述】:

我正在尝试在网站上为我的支付处理器设置一个模拟场景。通常,我的站点会重定向到用户付费的处理器站点。然后处理者重定向回我的站点,我等待处理者的即时付款通知 (IPN)。然后,处理器发布到我的NotifyUrl,它路由到我的支付控制器(PayFastController)上的Notify 操作。为了模拟,我重定向到一个本地操作,在点击确认后,它会生成一个线程来发布 IPN,就好像由处理器发布一样,然后重定向回我的注册过程。

我的模拟处理器控制器使用以下两种方法来模拟处理器的响应:

[HttpGet]
public RedirectResult Pay(string returnUrl, string notifyUrl, int paymentId)
{
    var waitThread = new Thread(Notify);
    waitThread.Start(new { paymentId, ipnDelay = 1000 });

    return new RedirectResult(returnUrl);
}

public void Notify(dynamic data)
{
    // Simulate a delay before PayFast 
    Thread.Sleep(1000);

    // Delegate URL determination to the model, vs. directly to the config.
    var notifyUrl = new PayFastPaymentModel().NotifyUrl;
    if (_payFastConfig.UseMock)
    {
        // Need an absoluate URL here just for the WebClient.
        notifyUrl = Url.Action("Notify", "PayFast", new {data.paymentId}, "http");
    }

    // Use a canned IPN message.
    Dictionary<string, string> dict = _payFastIntegration.GetMockIpn(data.paymentId);
    var values = dict.ToNameValueCollection();
    using (var wc = new WebClient())
    {
        // Just a reminder we are posting to Trocrates here, from PayFast.
        wc.UploadValues(notifyUrl, "POST", values);
    }
}

但是,我收到“对象引用未设置为对象的实例”。以下行的异常:

notifyUrl = Url.Action("Notify", "PayFast", new {data.paymentId}, "http");

data.paymentId 具有有效值,例如112,所以我没有将任何空引用传递给Url.Action 方法。我怀疑我通过在新线程上调用Notify 在某处丢失了某种上下文。但是,如果我只使用 notifyUrl = Url.Action("Notify", "PayFast");,我会避免异常,但我会得到一个相对操作 URL,其中我需要采用 protocol 参数的重载,因为只有该重载才能为我提供 WebClient.UploadValues 所说的绝对 URL它需要。

【问题讨论】:

    标签: asp.net asp.net-mvc asp.net-mvc-3 asp.net-mvc-routing


    【解决方案1】:

    当您在线程中时,您将无法再访问 HttpContext 和 Url 助手所依赖的 Request 属性。所以你永远不应该在线程中使用任何依赖 HttpContext 的东西。

    您应该在调用线程时将所有需要的信息传递给线程,如下所示:

    waitThread.Start(new { 
        paymentId, 
        ipnDelay = 1000,
        notifyUrl = Url.Action("Notify", "PayFast", new { paymentId }, "http")
    });
    

    然后在线程内部回调:

    var notifyUrl = new PayFastPaymentModel().NotifyUrl;
    if (_payFastConfig.UseMock)
    {
        // Need an absoluate URL here just for the WebClient.
        notifyUrl = data.notifyUrl;
    }
    

    【讨论】:

    • 谢谢@Darin,我实际上是在发布我的问题后才发现的。我将 URL 构建从 Notify 方法移到 Pay 方法中,并且按照您的建议,我现在将 URL 传递给 Notify
    猜你喜欢
    • 1970-01-01
    • 2020-05-11
    • 1970-01-01
    • 1970-01-01
    • 2011-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-22
    相关资源
    最近更新 更多