почему это работает нормально в первый раз, а не во второй раз? - PullRequest
0 голосов
/ 20 мая 2011

Я использую планировщик, который будет отправлять напоминания через библиотеку actionMailer. Однако мне нужен httpcontext для работы, а ActionMailer использует mvc.

Итак, я придумал это:

// глобальный aspx.

protected void Application_Start()
{
    // Hook our DI stuff when application starts
    IKernel kernel = SetupDependencyInjection();

    // get the reminder service
    IScheduledRemindersService scheduledRemindersService = kernel.Get<IScheduledRemindersService>();
    RemindersController.iScheduledReminedrService = scheduledRemindersService;
    RemindersController.StartScheduler();
}

// Контроллер напоминания

private static HttpContext httpContext;
public static void StartScheduler()
{
    // needed for action mailer
    httpContext = System.Web.HttpContext.Current;
    iScheduledReminedrService.StartAppointmentRemindersSchedule();
}

// Служба планировщика

public void StartAppointmentRemindersSchedule()
{
    // get a scheduler and start it.
    IScheduler scheduler = GetScheduler();
    scheduler.Start();

    // setup a job
    JobDetail jobDetail = SetupJob("AppointmentRemindersJob", typeof(AppointmentRemindersJob));

    //setup a trigger
    SimpleTrigger trigger = SetupSimpleTrigger("AppointmentRemindersTrigger");

    // schedule the job
    scheduler.ScheduleJob(jobDetail, trigger);
}

// Назначение на работу

public void Execute(JobExecutionContext context)
{
    // code above to get CalendarAppointments
    RemindersController.CalendarAppointmentsReminders(calendarAppointments);
}

// Контроллер напоминания

[NonAction]
public static void CalendarAppointmentsReminders(List<CalendarAppointment> appointments)
{
    // set it to have a http context so we can send out emails through mvc mailer.
    System.Web.HttpContext.Current = httpContext;

    List<CalendarAppointmentReminderVM> vm = Mapper.Map<List<CalendarAppointment>, List<CalendarAppointmentReminderVM>>(appointments);

    foreach (var v in vm)
    {
        new EmailController().SendCalendarAppointmentNotifiation(v).DeliverAsync();
    }
}

// контроллер электронной почты

public EmailResult SendCalendarAppointmentNotifiation(CalendarAppointmentReminderVM vm)
{
    To.Add(vm.To);
    Subject = String.Format("Hi");
    return Email("SendCalendarAppointmentEmail", vm);
}

Отлично работает при первом запуске приложения и его запуске. После этого он вылетает во второй раз около

System.NullReferenceException было не обрабатывается кодом пользователя
Сообщение = ссылка на объект не установлена ​​на экземпляр объекта.
Source = WebDev.WebHost40 StackTrace: в Microsoft.VisualStudio.WebHost.Connection.get_RemoteIP () в Microsoft.VisualStudio.WebHost.Connection.get_RemoteIP () в Microsoft.VisualStudio.WebHost.Request.GetRemoteAddress () в System.Web.HttpRequest.get_IsLocal () в System.Web.HttpRequestWrapper.get_IsLocal () в System.Web.WebPages.WebPageBase.ExecutePageHierarchy () в System.Web.Mvc.WebViewPage.ExecutePageHierarchy () в System.Web.WebPages.WebPageBase.ExecutePageHierarchy (WebPageContext pageContext, автор TextWriter, WebPageRenderingBase startPage) в System.Web.Mvc.RazorView.RenderView (ViewContext viewContext, TextWriter Writer, Объект пример) в System.Web.Mvc.BuildManagerCompiledView.Render (ViewContext viewContext, писатель TextWriter) в ActionMailer.Net.EmailResult.RenderViewAsString (ControllerContext контекст, вид IView) в ActionMailer.Net.EmailResult.AddMessageViews (ControllerContext контекст) в ActionMailer.Net.EmailResult.ExecuteResult (ControllerContext контекст) в ActionMailer.Net.MailerBase.Email (String viewName, объектная модель, строка masterName) в EmailController.SendCalendarAppointmentNotifiation (CalendarAppointmentReminderVM vm) в EmailController.cs: строка 80 at RemindersController.CalendarAppointmentsReminders (Список`1 назначения) в RemindersController.cs: строка 61 в AppointmentRemindersJob.Execute (JobExecutionContext контекст) в AppointmentRemindersJob.cs: строка 40 в Quartz.Core.JobRunShell.Run ()
InnerException:

1 Ответ

0 голосов
/ 21 мая 2011

HttpContext не будет надежно доступен вне фактического http-запроса в IIS. Даже если вы установите его в статическое поле. Вы можете попытаться высмеять местный запрос, сделанный на сайте, чтобы отправить электронное письмо. Я ничего не знаю о ActionMailer, но, возможно, это способ использовать их каркас за пределами контроллера?

Чтобы смоделировать запрос, вам нужно сначала узнать URL-адрес действия, на которое вы нацеливаетесь, что-то вроде этого должно быть настройкой, настроенной разработчиком или, если возможно, автоматически сайтом.

        var client = new System.Net.WebClient();
        client.DownloadString("http://localhost/Controller/Action");

Это не рекомендуемый подход, поскольку могут возникнуть проблемы с разрешениями на открытие сокетов и тому подобное. Безусловно, лучший способ отправки электронной почты - это использование уже существующей инфраструктуры, такой как System.Net.Mail.SmtpClient

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...