Проблема с нулевой ссылкой на объект в Url.Action в проекте MVC3 - PullRequest
1 голос
/ 24 июля 2011

Я пытаюсь настроить сценарий насмешки для моего обработчика платежей на веб-сайте.Обычно мой сайт перенаправляет на сайт процессора, где пользователь платит.Затем процессор перенаправляет обратно на мой сайт, и я жду немедленного уведомления о платеже (IPN) от процессора.Затем процессор отправляет сообщение на мой NotifyUrl, который направляет действие Notify на моем контроллере платежей (PayFastController).Чтобы подделать, я перенаправляю на локальное действие, которое после щелчка подтверждения порождает поток для публикации 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, поскольку только эта перегрузка дает мне абсолютный URL, который говорит WebClient.UploadValuesэто нужно.

1 Ответ

2 голосов
/ 24 июля 2011

Когда вы находитесь внутри потока, у вас больше нет доступа к HttpContext и свойству Request, на которое полагается помощник Url.Таким образом, вы никогда не должны использовать ничего, что зависит от 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;
}
...