1

I am using ActionMailer.net to send emails from my mvc 4 application.

This works when my initiating controller and the actionmailer controller and view are in the same Area. But fails when they are not as it cannot find the view.

This heirarchy works:

Area: Emails
   Controller:ManageOrders
   Controller:SendEmails
   View: OrderAck.html.cshtml

But this does not:

Area: OrderMgmt
   Controller:ManageOrders

Area: Emails  
   Controller:SendEmails
   View: OrderAck.html.cshtml

Since I want to centralize my code and not repeat it, I will have the need to send the same Order Acknowledgement email from multiple areas within my application.

Putting the path as part of the view name in the Email() method parameter does not work:

return Email("~/OrderMgmt/OrderAck", orderAck);

How else can I achieve this?

UPDATE: Here's the code:

The originating controller initiated by user submitting form: Areas\Mobile\Controllers\MakePartForWorkReleaseController.cs

[HttpPost]
    public ActionResult PullList(ContainerPullListViewModel ContainerPullListViewModel)
    {
        if (ModelState.IsValid)
        {
            var emailResult = manageOrdersController.SendOrderCompleteEmail(ContainerPullListViewModel.OrderId, baseUrl, ControllerContext);             
        }
    }

Here is the standard send email controller action the above calls, which is in a different area: Areas\OrderMgmt\Controllers\ManageOrdersController.cs

public JsonResult SendOrderCompleteEmail(int id, string baseUrl, ControllerContext controllerContext)
{
   string recipients = "";
   OrderAcknowledgementViewModel orderAck = new OrderAcknowledgementViewModel();

   //Call ActionMailer action controller to send email
   new OrderMgmtEmailController().OrderComplete(notifyList, orderAck).Deliver();
}

Here is the actionmailer.net controller action that actually sends the email: Areas\OrderMgmt\Controllers\OrderMgmtEmailController.cs

Note when I examine: HttpContextBase.Request.RequestContext.RouteData.DataTokens["area"] it returns "Mobile", which is the initiating controller's area, not the current controller area. I believe this is where the Email method is looking for the view based on this

public EmailResult OrderComplete(IEnumerable<CustomerContact> recipientList, OrderAcknowledgementViewModel orderAck)
{
   return Email("~/Areas/OrderMgmt/Views/OrderMgmtEmail/OrderComplete", orderAck);
}

And the view is in: Areas\OrderMgmt\Views\OrderMgmtEmail\OrderComplete.html.cshtml

And the error I am getting is:

You must provide a view for this email.  Views should be named ~/Areas/OrderMgmt/Views/OrderMgmtEmail/OrderComplete.txt.cshtml or ~/Areas/OrderMgmt/Views/OrderMgmtEmail/OrderComplete.html.cshtml (or aspx for WebFormsViewEngine) depending on the format you wish to render..
crichavin
  • 4,672
  • 10
  • 50
  • 95

1 Answers1

0

I played around with ActionMailer.net for a bit, it seems to require a strict structure.

I assume your controller looks something like this public EmailResult OrderComplete(OrderAcknowledgementViewModel orderAck) { To.Add(); From = ; Subject = ; return Email("OrderComplete", orderAck); }

So if that's what your controller looks like this is what you need to do.

Create a folder in Areas//Views/ and then place the OrderComplete.html.cshtml view into that new folder.

SLin
  • 375
  • 6
  • 18
  • @ChadRichardson Hey Chad, try creating a new folder in the areas/views section with the name of your controller and put the view in that folder as I mention above. – SLin Apr 11 '13 at 02:53
  • Thanks SLin, but I don't want to do that. I have a logical setup for my code and don't want to change it. As such, I've decided not to use ActionMailer.net and simply created a method to return a view as a string, that I use to populate the body of my email and send the email with my own code. It's much more flexible that way and seems simpler overall. – crichavin Apr 11 '13 at 20:55