Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ControllerContext and ViewData Outside Scope of Controller - MVC3 C#

I am rendering PartialViews/Models with the method below in order to template emails that get sent out.

I am using the code below to convert the partial and model into an html string that I can pass to my email sending code.

public class BaseController : Controller
{
    public string RenderPartialViewToString(string viewName, object model)
    {
        if (string.IsNullOrEmpty(viewName))
            throw new ArgumentException("No View Path Provided.");

        ViewData.Model = model;

        using (StringWriter sw = new StringWriter())
        {
            ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
            ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
            viewResult.View.Render(viewContext, sw);

            return sw.GetStringBuilder().ToString();
        }
    }
}

Currently, this lives in the BaseController, I would like to move it out into a helper method so that I can move my email model building out/sending out of the controller too.

The problem is I don't have access to ViewData/TempData/ControllerContext

I can new up a ControllerContext but I don't know what to do about ViewData/TempData.

This is how I would use what I have in the Controller currently:

//Do Stuff in Controller

var html = RenderPartialViewToString("~/Views/Mail/_ForgotPassword.cshtml", new MailModel { Username = "Skrillex", SomethingElse = "foo" });

//Send the Email
like image 291
Jason Avatar asked Nov 04 '22 06:11

Jason


1 Answers

I think you are on the right track, but the problem is your eagerness to complete separation, it is rather too eager.

You are using Razor view engine to render your rich text HTML email. A very noble approach. However, this means that you will be very close to your presentation layer and running this from outside a controller - in my view - does not make a lot of sense.

I believe you need to make (if not already made):

  • Your email Razor view as strongly typed
  • Let the rendering called in the controller as usual
  • Rendering would be as simple as passing the model to the Render method
  • Take out the building of your email model out to the helper you wish. This would not require any presentation layer logic and as such oblivious to it.

So the point is, calling of the rendering does not need to go out of the controller, building of the email model should.

Now if you are doing all of that it means I have not understood your question and requires more explanation.

like image 112
Aliostad Avatar answered Nov 09 '22 06:11

Aliostad