Perutean URL MVC, rute ke rute yang salah, mengapa?

Pertanyaan:

Ini adalah RegisterRoutes saya:

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


            routes.Add("ImagesRoute", new Route("graphics/{*filename}", new HttpRuntime.Routing.ImageRouteHandler()));


            // insert_dateti
            routes.MapRoute(
                "Default", // Routenname
                "{controller}/{action}/{id}", // URL mit Parametern
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameterstandardwerte
                //new { controller = "Home", action = "Splash", id = UrlParameter.Optional } // Parameterstandardwerte
                //new { controller = "Folders", action = "Content", id = UrlParameter.Optional } // Parameterstandardwerte
            );



        } // End Sub RegisterRoutes

Dan ini adalah pengendali rute saya

using System;
using System.IO;
using System.Web;
using System.Linq; 
using System.Web.UI;
using System.Web.Routing;
using System.Web.Compilation; 
using System.Collections.Generic; 


namespace HttpRuntime.Routing
{ 


    public class ImageRouteHandler : IRouteHandler 
    {


        public string MapRemoteLocation(string strPath)
        {
            if (string.IsNullOrEmpty(strPath))
                return "";

            string strBaseURL = "http://madskristensen.net/themes/standard/";
            return strBaseURL + strPath;
        }

        public IHttpHandler GetHttpHandler(RequestContext requestContext) 
        { 


            string filename = requestContext.RouteData.Values["filename"] as string; 

            if (string.IsNullOrEmpty(filename)) 
            {
                // return a 404 HttpHandler here
                requestContext.HttpContext.Response.StatusCode = 404;
                requestContext.HttpContext.Response.End();
                return null;
            } // End if (string.IsNullOrEmpty(filename)) 
            else 
            { 
                requestContext.HttpContext.Response.Clear();
                requestContext.HttpContext.Response.ContentType = GetContentType(filename);
                requestContext.HttpContext.Response.Redirect(MapRemoteLocation(filename));


                // find physical path to image here.   
                //string filepath = requestContext.HttpContext.Server.MapPath("~/test.jpg");


                // string stPath = requestContext.HttpContext.Request.Url.AbsolutePath;
                //requestContext.HttpContext.Response.WriteFile(filepath); 
                //requestContext.HttpContext.Response.End();
            } // End Else of if (string.IsNullOrEmpty(filename)) 

            return null; 
        } // End Function GetHttpHandler


        public static void MsgBox(object obj)
        {
            if (obj != null)
                System.Windows.Forms.MessageBox.Show(obj.ToString());
            else
                System.Windows.Forms.MessageBox.Show("obj is NULL");
        } // End Sub MsgBox


        private static string GetContentType(String path) 
        { 
            switch (Path.GetExtension(path)) 
            { 
                case ".bmp": return "Image/bmp"; 
                case ".gif": return "Image/gif"; 
                case ".jpg": return "Image/jpeg"; 
                case ".png": return "Image/png"; 
                default: break;
            } // End switch (Path.GetExtension(path))  
            return "";
        } // End Function GetContentType


    } // End Class ImageRouteHandler : IRouteHandler 


}  // End Namespace HttpRuntime.Routing

Tujuannya adalah, ketika saya memiliki ini di /Home/Index.cshtml

<img src="graphics/mads2011.png?v=123" title="Compose E-Mail" alt="Compose E-Mail" />

itu mengunduh gambar dari host jarak jauh.

Ini berfungsi dengan baik selama saya punya

routes.Add("ImagesRoute", new Route("graphics/{filename}", new HttpRuntime.Routing.ImageRouteHandler()));

Tapi ketika saya mengubahnya menjadi

routes.Add("ImagesRoute", new Route("graphics/{*filename}", new HttpRuntime.Routing.ImageRouteHandler()));

untuk mengizinkan subfolder, maka ia mengalihkan setiap tindakan url ke/grafik.

misalnya ketika aku punya

$(function () {
        $("#divJsTreeDemo").jstree({ 
        "json_data" : {
            "ajax" : {
                 "url": "@Url.Action("GetNodesJson", "Home")"
                 //"url": "@Url.Action("GetTreeData", "Home")"
                ,"async" : true

di Beranda/Index.cshtml

URL untuk panggilan AJAX pada halaman HTML yang dihasilkan menjadi

"url": "/graphics?action=GetNodesJson&amp;controller=Home"

Kenapa ini ? Dan bagaimana cara memperbaikinya? Jika saya memindahkan ImagesRoute saya ke bawah, JavaScript merutekannya dengan benar, tetapi kemudian saya tidak bisa mendapatkan gambar jarak jauh lagi, karena gambar tersebut dialihkan ke pengontrol "grafis", yang tidak ada --> Pengecualian tidak ada tampilan seperti itu...


person Stefan Steiger    schedule 05.10.2011    source sumber
comment
Saya sangat menyukai aspnetmvc... Saya sangat benci routing. Aku merasakan sakitmu. Maaf saya tidak bisa membantu.   -  person Jamiec    schedule 05.10.2011
comment
Oh, 1 kemungkinan bantuan adalah saya menggunakan debugger rute dari mvccontrib.codeplex.com saat melakukan perutean masalah.   -  person Jamiec    schedule 05.10.2011


Jawaban (1)


Saat membuat link dari rute, ImagesRoute Anda yang menggunakan {*filename} akan memenuhi semua ketentuan, sehingga rute tersebut akan selalu digunakan untuk membuat link jika mendahului rute Default di tabel rute Anda. Namun, saat memproses permintaan, ini berfungsi seperti yang diharapkan, karena rute ImagesRoute hanya akan dipenuhi oleh permintaan yang dimulai http://mysite.com/graphics/...

Untuk memperbaikinya, Anda perlu memindahkan ImagesRoutes ke bawah rute default, dan kemudian Anda perlu menambahkan RouteConstraint ke rute Default, sehingga permintaan apa pun yang dimulai dengan graphics akan menggagalkan rute Default.

Ubah rute Default Anda sebagai berikut:

routes.MapRoute(
    "Default", // Routenname
    "{controller}/{action}/{id}", // URL mit Parametern
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // defaults
    new { controller = @"^(?!graphics).+" } // constraint
);
person counsellorben    schedule 05.10.2011
comment
Bagus, berhasil! Terima kasih banyak ! Meskipun saya harus mengatakan saya masih tidak mengerti mengapa @Url.Action(GetNodesJson, Home) yang /Home/GetNodesJson memenuhi /graphics/whatever. Atau terlebih lagi mengapa @Url.Action(ActionName, ControllerName) berubah menjadi grafis/namapengontrol/ActionName. Entah bagaimana, saya kira, itu hanya mengisi rute2 yang diperluas ke rute1... Saya kira saya harus membaca sumber MVC untuk memahami bagian perutean itu. - person Stefan Steiger; 06.10.2011
comment
Karena parameter URL ImagesRoute Anda terdiri dari satu pencocokan serakah, parameter tersebut cocok dengan tautan apa pun yang akan dibuat oleh MVC. Di sisi pembuatan tautan, semuanya cocok dengan rute tersebut. Harap tandai sebagai telah dijawab. Terima kasih. - person counsellorben; 06.10.2011