2011-07-24 4 views
1

Webサイトの支払い処理担当者のために模擬シナリオを設定しようとしています。通常、私のサイトはユーザーが支払うプロセッササイトにリダイレクトされます。その後、プロセッサは自分のサイトにリダイレクトされ、プロセッサからの即時支払い通知(IPN)を待つ。その後、プロセッサは自分のNotifyUrlに投稿します。これは、ペイメントコントローラ(PayFastController)のNotifyアクションにルーティングされます。模擬するには、ローカルアクションにリダイレクトします。これをクリックすると、プロセッサによってポストされたようにIPNをポストするスレッドが生成され、自分の登録プロセスにリダイレクトされます。MVC3プロジェクトのUrl.Actionでヌルオブジェクト参照の問題が発生しました

私のモックプロセッサコントローラはプロセッサの応答をシミュレートするために、次の2つのメソッドを使用します。

[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メソッドへのnull参照を渡していません。私は、新しいスレッドで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、私は実際にちょうど見つかりましたそれは私の質問を投稿した後です。私は 'Notify'メソッドからURLビルドを' Pay'メソッドに移しました。あなたがお勧めするように、私は 'Notify'にURLを渡します。 – ProfK

関連する問題