Использование Postal и Hangfire на дочернем сайте

Я пытался использовать Postal на своем сайте MVC5. Когда я размещаю свою веб-страницу на дочернем сайте, т.е. http://localhost/Subsite, я получаю сообщение об ошибке

  • Виртуальный путь '/' сопоставляется с другим приложением, что не разрешено

Я отладил его до того, что при создании ControllerContext HttpContext не устанавливается правильно. Поскольку я запускаю Postal из Hangfire, HttpContext.Current всегда равен нулю. Postal создает ContollerContext, используя приведенный ниже код.

        ControllerContext CreateControllerContext()
    {
        // A dummy HttpContextBase that is enough to allow the view to be rendered.
        var httpContext = new HttpContextWrapper(
            new HttpContext(
                new HttpRequest("", UrlRoot(), ""),
                new HttpResponse(TextWriter.Null)
            )
        );
        var routeData = new RouteData();
        routeData.Values["controller"] = EmailViewDirectoryName;
        var requestContext = new RequestContext(httpContext, routeData);
        var stubController = new StubController();
        var controllerContext = new ControllerContext(requestContext, stubController);
        stubController.ControllerContext = controllerContext;
        return controllerContext;
    }

    string UrlRoot()
    {
        var httpContext = HttpContext.Current;
        if (httpContext == null)
        {
            return "http://localhost";
        }

        return httpContext.Request.Url.GetLeftPart(UriPartial.Authority) +
               httpContext.Request.ApplicationPath;
    }

Как я могу указать UrlRoot, чтобы вместо того, чтобы извлекать значение по умолчанию для локального хоста, чтобы извлекать его на основе моего дочернего сайта?


person Jeff    schedule 14.02.2016    source источник


Ответы (2)


Я следовал инструкциям здесь http://docs.hangfire.io/en/latest/tutorials/send-email.html для отправки моей электронной почты. Метод в учебнике ниже

    public static void NotifyNewComment(int commentId)
{
// Prepare Postal classes to work outside of ASP.NET request
var viewsPath = Path.GetFullPath(HostingEnvironment.MapPath(@"~/Views/Emails"));
var engines = new ViewEngineCollection();
engines.Add(new FileSystemRazorViewEngine(viewsPath));

var emailService = new EmailService(engines);

// Get comment and send a notification.
using (var db = new MailerDbContext())
{
    var comment = db.Comments.Find(commentId);

    var email = new NewCommentEmail
    {
        To = "[email protected]",
        UserName = comment.UserName,
        Comment = comment.Text
    };

    emailService.Send(email);
}
}

Я обнаружил, что проблема в том, что FileSystemRazorViewEngine не использовался для почты. Чтобы заставить это работать, я должен был убедиться, что FileSystemRazorViewEngine был первым доступным движком. Затем я удалил его, потому что не хотел, чтобы он был движком по умолчанию. Ниже мой обновленный метод.

    public static void NotifyNewComment(int commentId)
{
// Prepare Postal classes to work outside of ASP.NET request
var viewsPath = Path.GetFullPath(HostingEnvironment.MapPath(@"~/Views/Emails"));
var eng = new FileSystemRazorViewEngine(viewsPath));
ViewEngines.Engines.Insert(0, eng);

var emailService = new EmailService(engines);

// Get comment and send a notification.
using (var db = new MailerDbContext())
{
    var comment = db.Comments.Find(commentId);

    var email = new NewCommentEmail
    {
        To = "[email protected]",
        UserName = comment.UserName,
        Comment = comment.Text
    };

    emailService.Send(email);
    ViewEngines.Engines.RemoveAt(0)
}
}
person Jeff    schedule 15.02.2016

Ниже приведено еще одно возможное решение, которое я считаю более элегантным, чем приведенное выше. Это также устраняет проблему, возникающую при доступе к приложению MVC во время выполнения фонового процесса.

public static void SendTypedEmailBackground()
{
    try
    {
        var engines = new ViewEngineCollection();
        var viewsPath = Path.GetFullPath(HostingEnvironment.MapPath(@"~/Views/Emails"));

        var eng = new FileSystemRazorViewEngine(viewsPath);
        engines.Add(eng);

        var email = new WebApplication1.Controllers.EmailController.TypedEmail();
        email.Date = DateTime.UtcNow.ToString();
        IEmailService service = new Postal.EmailService(engines);
        service.Send(email);

    }
    catch(Exception ex)
    {
        throw ex;
    }
}
person Jeff    schedule 08.04.2016
comment
Спасибо за это .. Я получаю сообщение об ошибке (невозможно преобразовать null в 'bool', потому что это ненулевой тип значения). Любая идея, почему это произойдет? - person TsTeaTime; 02.10.2017