2011-07-24 23 views
1

我想为我的付款处理器在网站上设置一个模拟场景。通常,我的网站会重定向到用户付款的处理器站点。然后处理器重定向回我的站点,并等待处理器的即时付款通知(IPN)。然后处理器发布到我的NotifyUrl,该路由转到我的支付控制器(PayFastController)上的Notify操作。为了模拟,我重定向到一个本地动作,点击一个构象后,产生一个线程来发布IPN,就好像由处理器发布一样,然后重定向到我的注册过程。MVC3项目的Url.Action中的空对象引用问题

我的模拟处理器的控制器使用以下两种方法来模拟处理器的回应:“对象引用未设置到对象的实例”

[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,其中我需要使用参数的超载,因为只有该超载才能提供WebClient.UploadValues所需的绝对URL。

回答

2

当您在线程中时,您不再有权访问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; 
} 
+0

感谢@Darin,其实我刚刚发现发布我的问题后出来。我将URL构建从'Notify'方法移到'Pay'方法中,并且按照您的建议,我现在将URL传递给'Notify'。 – ProfK