Asp.Net MVC中的路由和多个视图

时间:2012-03-08 21:52:22

标签: asp.net-mvc-3 routing relative-path

我有一个控制器操作方法,需要能够提供多个视图。这些视图由XSLT生成。

现在,视图中包含图像(每个数百个),每个视图都需要有自己的文件夹,其中包含要引用的图像。这应该怎么做?

如果源XML中的图像具有简单相对路径的href(“images / image.svg”),如何在应用程序的视图中解析此路径?

如果我可以将images文件夹放在与视图相同的文件夹中,并在那里使用相对路径,那将很容易,但这不起作用,因为我正在从动作中提供多个视图。这是路由:

routes.MapRoute(
                "Parameter",
                "{controller}/{action}/{lang}/{prod}",
                new { controller = "Manuals", action = "Product", lang = "en-US", prod = "sample" }
        );

因此,如果我尝试使用img src属性的相对路径,它会解析为“/Manuals/Product/en-US/images/image.svg”

事实上,如果我把它相对于视图,图像位于“/Views/Manuals/en-US/images/image.svg”

那么在Asp.Net MVC中没有办法拥有这样的相对图像路径吗?还是我完全误解了MVC路由?

1 个答案:

答案 0 :(得分:0)

这就是我之前所做的:

public class MvcApplication : HttpApplication
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        MapRoute(routes, "", "Home", "Index");
        /* other routes */
        MapRoute(routes, "{*url}", "Documentation", "Render");
    }
}

现在,任何不匹配的路由都会传递给DocumentationController。我的文档控制器如下所示:

public class DocumentationController : Controller
{
    public ActionResult Render(string url)
    {
        var md = new MarkdownSharp.Markdown();
        // The path is relative to the root of the application, but it can be anything
        // stored on a different drive.
        string path = Path.Combine(Request.MapPath("~/"), GetAppRelativePath().Replace('/', '\\')) + ".md";
        if (System.IO.File.Exists(path))
        {
            string html = md.Transform(System.IO.File.ReadAllText(path));
            return View("Render", (object)html);
        }

        // return the not found view if the file doesn't exist
        return View("NotFound");
    }

    private  string GetAppRelativePath()
    {
        return HttpContext.Request.AppRelativeCurrentExecutionFilePath.Replace("~/", "");
    }
}

所有这一切都是为了找到降价文件并相应地渲染它们。要根据您的情况更新此内容,您可能需要执行以下操作:

    routes.MapRoute(
            "Parameter1",
            "{controller}/{action}/{lang}/{*url}",
            new { controller = "Manuals", action = "Download", lang = "en-US", prod = "sample" }
    );

确保它在{controller}/{action}/{lang}/{prod}路线之后。这应该会导致/Manuals/Product/en-US/images/image.svg甚至images/image.svg等网址(如果浏览器位于/Manuals/Product/en-US/sample中,则会调用Download操作。然后您可以调整我写的代码将URI映射到物理位置。您可能遇到的一个问题是“图像”被认为是产品,/Manuals/Product/en-US/images会认为它是产品。

图像操作可以如下所示。

public ActionResult Download(string url)
{
  /* figure out physical path */
  var filename = /* get filename form url */
  var fileStream = [...];
  Response.Headers.Remove("Content-Disposition");
  Response.Headers.Add("Content-Disposition", "inline; filename=" + filename);
  string contentType = "image/jpg";
  return File(fileStream, contentType, filename);
}

您可以在MSDN获取有关FileResult的更多信息。