你用过ASP.NET MVC Action方法做了哪些聪明的事情?

24

ASP.NET MVC控制器动作方法主要用于处理“业务”操作,但它也可以用于更多的操作。

我认为看看人们为了别人可能实用或有用的创造性操作而创建的操作会很有趣。

这是我的贡献:

Javascript文件连接器 - 用于减少http请求的数量:

    [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"
        };
    }

将路由映射到它:

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

将其从您的主页面引用:

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

注意,我已经为输出设置了缓存,所以如果您更改JS并刷新页面,则可能需要禁用缓存!

我只需要回来弄清楚如何进行gzip压缩。

*不应该使用VaryByParam="None",因为这会导致发送Vary头,从而使浏览器返回并检查新版本。 如果您真的必须更改JS内容,那么您的用户将不得不等待5分钟!


哈!这段代码实际上在RC1中失败了。他们在控制器上添加了一个新的File()方法,这意味着你需要用System.IO.File替换File。 - Simon_Weaver
1
.NET 3.5 SP1脚本合并在这里不起作用吗?http://www.asp.net/Learn/3.5-SP1/video-296.aspx - bzlm
针对资产管理,可以参考这种方法:http://weblogs.asp.net/rashid/archive/2009/05/02/script-and-css-management-in-asp-net-mvc-part-2.aspx - Arnis Lapsa
@bzlm:我不这么认为。在我看来,脚本组合只适用于ASP.NET WebForms,因为它需要一个ScriptManager。这个线程是关于ASP.NET MVC的。 - Adrian Grigore
...或者包含合并器 http://github.com/petemounce/includecombiner/tree/master - Adrian Grigore
显示剩余3条评论
5个回答

14

一个 HTTP 301 重定向 算不算聪明?

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;
    }
}

当然 :) 现在你必须给我投票,虽然我总是害怕那些301的东西,但我相信在接下来的24小时内我会突然发现需要一个! - Simon_Weaver

3

3

通过电子邮件确认查看结果:

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);
    }
}

这里省略了一些实现细节,但我可以使用这个来实现一个RegistrationSuccessResult类,例如,在成功注册用户后发送带有适当文本的电子邮件消息。
我之所以选择在子类化的ViewResult中发送消息而不是在操作方法本身中发送消息,是为了更容易地分离我的单元测试。

2
实际上,这并不是一个“操作”方法,而是一个自定义的控制器,它实现了基于路由的RPC实现。它通过路由数据识别合同和方法,并将调用传递给服务器端服务实现。相当高效(是的,我没有只使用WCF或SOAP有有效理由)。

0

不确定有多少人正在使用区域,但在区域中进行视图更改时,XCopy脚本是非常必要的。区域会编译到父项目中,但仅在编译时(而非保存时)进行,因此为了保持开发敏捷性,您需要运行XCopy。


你是说动作方法本身调用XCopy?有趣的想法(只要它仅在开发阶段启用)。这是解决问题的好方法。我因为这个限制而避免了使用单独的区域项目。 - Simon_Weaver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接