使用MVC路由到自定义JavaScript

时间:2014-08-04 19:46:08

标签: asp.net-mvc asp.net-mvc-4

我想让MVC处理我项目中某些JavaScript文件的路由。具体来说,我有以下目录结构:

+-- Custom
|   +-- ViewModels
|      +-- Dashboard
|         +-- module1.js
+-- ViewModels
|   +-- Dashboard
|      +-- module1.js
|      +-- somefileX.js
|   +-- Profile
|      +-- somefileY.js

我希望将/ViewModels/Dashboard/module1.js的请求路由到/Custom/ViewModels/Dashboard/module1.js

但如果请求/ViewModels/Dashboard/somefileX.js,则该路线不会转到自定义文件夹。

如何启用此功能?我似乎需要这个routes.RouteExistingFiles = true;

2 个答案:

答案 0 :(得分:0)

有多种解决方案。

丑陋的MVC路由版看起来像:

为具有module1.js约束的文件(或所需文件列表)创建路径。

public class MatchConstraint : IRouteConstraint
{
    private List<string> _nonMatches;

    public MatchConstraint(params string[] nonMatches)
    {
        this._nonMatches = nonMatches.ToList();
    }

    public bool Match(HttpContextBase httpContext, 
                      Route route, 
                      string parameterName, 
                      RouteValueDictionary values, 
                      RouteDirection routeDirection)
    {
        if (!values.ContainsKey(parameterName))
            return false;

        var value = (string)values[parameterName];

        var isAllowed = this._nonMatches
          .Any(nm => nm.Equals(value, StringComparison.CurrentCultureIgnoreCase));

        return isAllowed;
    }
}

将约束添加到路线:

routes.MapRoute(
  name: "Javascript",
  url: "{controller}/{action}/{js}",
  defaults: new { controller = "ViewModels", 
                  action = "Dashboard", 
                  js = UrlParameter.Optional },
  constraints: new { js = new DoesNotMatchConstraint("module1.js") }
);

routes.RouteExistingFiles = true

创建一个控制器,它将返回自定义目录中的javascript文件。

public ViewModelsController
{
  public ActionResult DashBoard(string id)
  {
    // load/pass file to FileResult
    return File();
  }
}

理论上(UNTESTED)我假设如果没有找到路由,将提供现有文件。如果不是这种情况,您可以为js创建第二个catchall路由,并从标准目录返回它们。

答案 1 :(得分:0)

过了一段时间,我意识到虽然我可能会使用MVC Routing来处理查找自定义JavaScript文件......但它可能并不是最适合的。我甚至探索过创建一个自定义的IRouteHandler。

最后我决定创建一个HttpHandler。这是我提出的简化版本:

public class CustomViewModelsHandler : IHttpHandler
{
  public bool IsReusable { get { return false; } }

  public void ProcessRequest(HttpContext context)
  {
    var path = context.Request.PhysicalPath.Replace("ViewModels\\", "Custom\\ViewModels\\");
    path = (File.Exists(path) ? path : context.Request.PhysicalPath);
    context.Response.ContentType = "application/x-javascript";
    context.Response.WriteFile(path);
  }
}

在web.config中:

<add name="CustomViewModelsHandler" path="ViewModels/*.js" verb="*" type="My.Name.Space.CustomViewModelsHandler" preCondition="integratedMode,runtimeVersionv4.0" />