smsohan / MvcMailer

A Mailer for ASP.Net MVC that forms the Email Body using MVC Views (Razor etc.) following Ruby on Rails ActionMailer style
MIT License
584 stars 178 forks source link

Mvc Mailer in area #34

Open RikkiMo opened 12 years ago

RikkiMo commented 12 years ago

In my project i wan't to use MvcMailer, it's really nice. For the structure of my project i wan't to put the mailer controllers + views in a separate area. But after i have done this the e-mail body stay's empty, so the PopulateBody method can't find the view, i think he is looking in the root view folder instead of the area view folder. Is is possible to use Mvc Mailer in a separate area?

Dav-id commented 12 years ago

This is an issue I have also experienced. I have had to temporarily move the mailing code out of the area but I would like a long term solution to this.

RikkiMo commented 12 years ago

Then i think the right solution for me is to put the mailer in a separate project instead of an area.

dusda commented 12 years ago

I have also had this problem. For structural reasons, having to store the email views in the root of my application is annoying; it would be great to have area support for it.

ocdi commented 11 years ago

I had the reverse issue of this, using the mailer from within a controller area caused the views to be searched in the same area, yet the mailer was outside. Its because MailerBase creates its ControllerContext on demand with this code:

if (this.ControllerContext == null)
    this.CreateControllerContext();

This in turn uses

this.ControllerContext = new ControllerContext(this.CurrentHttpContext, RouteTable.Routes.GetRouteData(this.CurrentHttpContext), (ControllerBase) this);

For me I create my own ControllerContext in the constructor of my class, adding an new RouteData() to ensure no area is polluting it - for your case you could add the area you are after, like:

var data = new RouteData();
data.Values.Add("Area", "Mailers");
ControllerContext = new ControllerContext(base.CurrentHttpContext, data, this)

Hope this helps.

khebbie commented 11 years ago

ocdi's answer is pretty close, I got it working like so: //Ensure MvcMailer uses views from the Mails area var data = new RouteData { Route = RouteTable.Routes["Mails_default"] }; ControllerContext = new ControllerContext(CurrentHttpContext, data, this);

So what this says is that a route called "Mails_default" exists where the mails reside

ctolkien commented 11 years ago

Just hit this issue as well :+1:

pholly commented 10 years ago

I also ran into this issue because I'm creating a UserMailer from within a Web Api 2 Area, which doesn't include the area name in its route data.

I used @ocdi 's method and changed data.Values.Add("Area", "Mailers") to data.DataTokens["area"] = "MyAreaName" and it worked.

Using Web Api 2 and MVC 5.

So for anyone skimming, this is what my UserMailer constructor looks like:

public UserMailer()
        {
            MasterName = "_Layout";
            var data = new RouteData();
            data.DataTokens["area"] = "MCCI";
            this.ControllerContext = new System.Web.Mvc.ControllerContext(this.CurrentHttpContext, data, this);
        }