24

The ASP.NET MVC controller action methods are primarily used for handling 'business' operations but it can be used for lots more.

I thought it would be fun to see what creative, useful things people have created actions for that may be practical or useful for others.

Here's my contribution :

Javascript file concatenator - to reduce number of http requests:

    [OutputCache(Duration = 5 * 60, VaryByParam="")]  // DONT USE "None" here *
    public ContentResult RenderJavascript(){

        StringBuilder js = new StringBuilder();
        StringWriter sw = new StringWriter(js);

        // load all my javascript files
        js.AppendLine(File.ReadAllText(Request.MapPath("~/Scripts/jquery.hoverIntent.minified.js")));
        js.AppendLine(File.ReadAllText(Request.MapPath("~/Scripts/jquery.corner.js")));
        js.AppendLine(File.ReadAllText(Request.MapPath("~/Scripts/rollingrazor.js")));

        return new ContentResult()
        {
            Content = js.ToString(),
            ContentType = "application/x-javascript"
        };
    }

Map a route to it :

  // javascript
  routes.MapRoute(
     "js-route",
     "dynamic/js",
     new { controller = "Application", action = "RenderJavascript" }
  );

Refer to it from your master page :

    <script type="text/javascript" src="/dynamic/js"></script>

Be warned I've set a cache for the output, so if you're changing your JS and refreshing the page you might want to disable the cache!

I jsut need to come back and figure out how to gzip it.

* You shouldn't use VaryByParam="None" because that causes the Vary header to be send, which causes the browser to go back and check for a new version. If you really have to change your js content then your users are just goin to have to wait 5 minutes for it!

Community
  • 1
  • 1
Simon_Weaver
  • 120,240
  • 73
  • 577
  • 618
  • Ha! This code actually fails with RC1. They added a new File() method on Controller which means you need to replace File with System.IO.File – Simon_Weaver Jan 28 '09 at 03:14
  • 1
    Wouldn't .NET 3.5 SP1 Script Combining work here? http://www.asp.net/Learn/3.5-SP1/video-296.aspx – bzlm Mar 01 '09 at 18:41
  • This would be a lot nicer if it could be altered to render script files dynamically, depending on which ones were needed on each page. – Dan Atkinson May 06 '09 at 09:49
  • oops! i thought this was my question about clever things with an HtmlExtension methods and i just gave it 150 bounty. oh well! – Simon_Weaver Jun 18 '09 at 01:18
  • for asset management, check out this approach: http://weblogs.asp.net/rashid/archive/2009/05/02/script-and-css-management-in-asp-net-mvc-part-2.aspx – Arnis Lapsa Jun 18 '09 at 12:53
  • @bzlm: I don't think so. It appears to me that Script combining is only suitable for ASP.NET webforms because it requires a scriptmanager. This thread is a bout ASP.NET MVC. – Adrian Grigore Aug 19 '09 at 07:49
  • But you could use script combining for ASP.NET MVC here: http://weblogs.asp.net/gunnarpeipman/archive/2009/07/04/asp-net-mvc-how-to-combine-scripts-and-other-resources.aspx – Adrian Grigore Aug 19 '09 at 07:55
  • ...or includecombiner http://github.com/petemounce/includecombiner/tree/master – Adrian Grigore Aug 19 '09 at 08:16

5 Answers5

14

Does a HTTP 301 Redirect count as clever?

public class PermanentRedirectResult : ActionResult
{
    public string Url { get; set; }

    public PermanentRedirectResult(string url)
    {
        if (string.IsNullOrEmpty(url))
        {
            throw new ArgumentException("url is null or empty", "url");
        }
        this.Url = url;
    } 

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        context.HttpContext.Response.StatusCode = 301;
        context.HttpContext.Response.RedirectLocation = Url;
    }
}
Michael Stum
  • 167,397
  • 108
  • 388
  • 523
  • sure :) and now you have to vote ME up although i'm always scared of those 301 things but I'm sure I'll suddenly find a need for one within the next 24 hours! – Simon_Weaver Jan 28 '09 at 01:41
3

View result with email confirmation:

public abstract class ViewResultWithConfirmationEmail: ViewResult
{
    protected readonly string toAddress;

    protected ViewResultWithConfirmationEmail(string toAddress)
    {
        this.toAddress = toAddress;
    }

    protected abstract MailMessage CreateEmail(ControllerContext context);

    protected override void ExecuteResult(ControllerContext context)
    {
        MailMessage message = CreateEmail(context);
        var smtpClient = new SmtpClient();
        smtpClient.Send(message);

        base.ExecuteResult(context);
    }
}

Some of the implementation details have been omitted here, but I could use this to implement a RegistrationSuccessResult class, for example, that would send an email message with the appropriate text after a successful user registration.

The reason I chose to send the message in a subclassed ViewResult instead of in the action method itself was to make it easier to separate my unit tests.

John G
  • 3,313
  • 21
  • 12
3

A partial implementation of less, a css syntax extender

It actually support only constants and what they called mixins, the source are here.

In this post I explained how to use it in mvc (the post is in italian but just look at the source):

you can just look here at the result

kentaromiura
  • 6,229
  • 2
  • 19
  • 15
2

Actually, not an "action" method, but a custom controller that implements a route-base RPC implementation. It identifies the contract and method from the route-data and passes the call onto the server-side service implementation. Pretty efficient (and yes, there are valid reasons that I'm not just using WCF or SOAP).

Marc Gravell
  • 927,783
  • 236
  • 2,422
  • 2,784
0

Not sure how many of you are using areas but an XCopy script is pretty necessary when making View changes in an Area. Areas compile into the parent project but only on compile (not on save) so to keep the dev agility, you'll need to run an XCopy.

RailRhoad
  • 2,048
  • 1
  • 24
  • 38
  • you're saying the action method itself calls XCopy ? interesting idea (as long as its enabled only during development phase). good solution to the problem. i avoided separate area projects due to this limitation – Simon_Weaver Sep 09 '09 at 22:18