【问题标题】:$.ajax call receives Resource not Found but the MVC debug says route is hit?$.ajax 调用收到 Resource not Found 但 MVC 调试说路由被命中?
【发布时间】:2012-10-17 00:42:11
【问题描述】:

我会尽可能详细地解释我的设置。

1) 我正在使用一个区域 (MVC 4)。这是文件夹和文件设置: 2)我默认直接解析到我的区域(不是根视图中的 Home 控制器)(我真的不需要与这个问题无关的 Home 控制器,只是一些背景信息) 3) 我的 global.asax 路由注册如下所示:

   protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RouteConfig.RegisterRoutes(RouteTable.Routes);

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }

4) 我的 route.config 如下所示:

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

    // Purposely not going to use the Home Controller (just a convention I want in place)
    routes.MapRoute("Default", "", new { area = "Search", controller = "Member", action = "Index", id = UrlParameter.Optional }).DataTokens.Add("area", "Search");
}

5) 我所在区域的注册路由如下:

   public class MemberAreaRegistration : AreaRegistration
    {

        public override string AreaName
        {
            get { return "Search"; }
        }


        public override void RegisterArea(AreaRegistrationContext context)
        {
            context.MapRoute("Search_Member_GetMemberByContractNumber", "Search/Member/{id}", defaults: new { controller = "Member", action = "GetMemberByContractNumber", id = UrlParameter.Optional });
            context.MapRoute("Search_Default", "Search/{controller}/{action}/{id}", defaults: new { controller = "Member", action = "Index", id=UrlParameter.Optional});
        }

    }

6) 我有一个执行此操作的控制器:

[HttpGet]
public JsonResult GetMemberByContractNumber(int contractNumber)
{
    Member memberDto = MemberCRUD.RetrieveMember(contractNumber);

    JsonResult member = Json(memberDto, JsonRequestBehavior.AllowGet);

    Json(JsonConvert.SerializeObject(member));

    return member;
} 

7) 我有一个试图向该操作发送 ajax 请求的视图:

// Get the results & Bind to grid
$(function () {
    var members = [];
    $.getJSON('Search/Member/26049', function (data) {
        members = data;
        grid = new Slick.Grid("#searchResults-Grid", members, columns, options);
    });
});

工作原理:我可以运行该网站,它会触发我的会员的 Index() 操作并加载会员的索引视图。这不是这里的问题。

问题是什么:我无法解决这个问题...它在 jQuery getJSON 请求“Search/Member/26049”中找不到我的控制器和操作

** 我在 FireBug 中遇到的错误**:

http://localhost/OurappName/Search/Member/26049 404 Not Found
        19ms
in the response:
<b> Requested URL: </b>/ballysearch/Search/Member/26049<br><br>

我尝试过什么:最初在我所在地区的路线配置中,我在最后有第一行,因此尝试将其向上移动。我说的是 context.MapRoute("Search_Member_GetMemberByContractNumber", "Search/Member/{id}".. 我在默认路线之后就有了。然后切换了,因为我认为它总是会明显到达我的默认路线..在这种情况下,这实际上应该只是一条“包罗万象”的路线。

我已经尝试了 getJSON 中 url 的几种变体,例如: '成员/26049'

非常确定我的控制器的操作与它的设置方式一样。

我知道这可能是路线问题,但我不明白它是什么。

更新:

这是路由调试结果

更新:

现在看来,我可能一直认为这是一个路线问题,但至少现在没关系,所以不确定“资源”这个错误是什么意思

这是我现在拥有的似乎在我的 MemberAreaRegistration.cs 中工作的路线

context.MapRoute("Search_Member", "Search/Member/{contractNumber}", new { controller = "Member", action = "GetMemberByContractNumber", contractNumber = UrlParameter.Optional }); context.MapRoute("Search_Default", "Search/{controller}/{action}/{id}", new {controller="Member", action = "Index", id = UrlParameter.Optional });

现在不知道为什么我会收到此资源错误。在 Firebug 中,有一些附加信息,但如果是这种情况,我仍然不明白我的控制器代码有什么问题,或者如果这也是一个问题,我的 jQuery 代码......我没有看到:

[HttpException]: The controller for path &#39;/OurAppName/Search/Member/1234&#39; was not found or does not implement IController.

仍然从 firebug 中获取更多错误视图:

更新 ------------------------------------------- 2012 年 10 月 27 日:

想在此发布我当前的尝试详细信息

我的路线在我的 Route.Config 中是这样设置的:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.IgnoreRoute("favicon.ico");
        routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });
        routes.IgnoreRoute("{*staticfile}", new { staticfile = @".*\.(css|js|gif|jpg)(/.*)?" });
        routes.IgnoreRoute("{*robotstxt}", new { robotstxt = @"(.*/)?robots.txt(/.*)?" });

        // Purposely not going to use the Home Controller, we don't need it so hence the DataTokens to tell MVC to go straight to my Area called Search to look for the member controller for the default route when you first hit the View
        routes.MapRoute("Default", "", new { area = "Search", controller = "Member", action = "Index", id = UrlParameter.Optional }).DataTokens.Add("area", "Search");
    }

我的区域的注册路线:

namespace OurApp.Web.Areas.Search.Views.Member
{
    public class MemberAreaRegistration : AreaRegistration
    {

        public override string AreaName
        {
            get { return "Search"; }
        }


        public override void RegisterArea(AreaRegistrationContext context)
        {


            context.MapRoute("Search_Member", "Search/Member/{contractNumber}", new { controller = "Member", action = "GetMemberByContractNumber", contractNumber = UrlParameter.Optional });
            context.MapRoute("Search_Default", "Search/{controller}/{action}/{id}", new {controller="Member", action = "Index", id = UrlParameter.Optional });
        }

    }
}

最后是我的整个控制器代码:

namespace OurApp.Web.Areas.Search.Controllers
{

    public class MemberController : Controller
    {

        public ActionResult Index()
        {
            return View();
        }


        [HttpGet]
        public JsonResult GetMemberByContractNumber(int contractNumber)
        {
            Member memberDto = MemberCRUD.RetrieveMember(contractNumber);

            JsonResult member = Json(memberDto, JsonRequestBehavior.AllowGet);

            return Json(member, JsonRequestBehavior.AllowGet);

            return member;
        }


        [HttpGet]
        public ActionResult TestTheRoute(int daveIdTest)
        {
            return null;
        }
    }
}

1) 我的视图中没有开始表单标记。那是因为我只是想测试这个 $.ajax() 函数,稍后我将添加一个表单并从某个事件调用该调用。所以没关系,我还没有表单元素,对吧?我只是在我的视图顶部打开了 $.ajax 调用,因此它会自行触发。

2) 正如您在上面看到的那样,它似乎可以到达我的路线。我只是想知道这是否是我在回调方面形成我的 $.ajax() 调用的方式,并且可能与我的控制器方法不完全正确有关?我正在从我的行动中返回 json,但我可以假设我拥有它。我不知道,除非我可以在返回 json 的操作方法中尝试不同的方法。我不知道我的 $.ajax 调用是否需要指定回调中预期的返回类型,因为我只是在输入此内容时考虑过它,但我也会检查一下。

例如,当我像这样设置 $.ajax 调用时(见下文),我得到了响应,所以我认为这告诉我 IIS 能够在它到达我的路由和控制器之后发送响应。所以我认为这是我的操作方法没有返回正确的 json 对象,不太确定,但在这一点上,如果来自 Phil Haack 的路由调试器显示它肯定会命中我的路由,那么它不可能是...... ajax 呼叫正在击中我的路线。

   $.ajax({
        url: 'OurApp/Search/Member/26049',
        type: "GET",
        dataType: "json",
        success: function (response) 
        {
            alert('we got a mother fing response!');
            grid = new Slick.Grid("#memberSearchResults-Grid", response.data, columns, options);
        },
        error: function (e) { alert('response error: '); }
    });

所以我收到了上述错误情况的警报,它正在发生这种情况。我不知道我是否总是会得到响应...可能我认为 IIS 会响应失败的请求和成功的路由请求...?

我尝试附加到工作进程,然后在该操作方法的第一行设置调试点后刷新页面,该操作方法在我的控制器中返回 json,但该行从未被命中。我不知道为什么。我无法获得任何调试点,不是

这是来自 firebug 的请求标头,仅供参考:

GET http://localhost/OurApp/Search/Member/26049 HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Proxy-Connection: keep-alive

这里有一些响应,有趣的是,即使它显示我的路由在我的控制器上被击中,这个错误说不,它没有击中你的控制器,所以我在 wtf 的这一点上傻眼了在哪里:

HeadersResponseCacheHTML

无法找到该资源。 正文 {字体系列:“Verdana”;字体重量:正常;字体大小:.7em;颜色:黑色;} p {字体系列:“Verdana”;字体重量:正常;颜色:黑色;边距顶部:-5px} b {字体系列:“Verdana”;字体粗细:粗体;颜色:黑色;上边距:-5px} H1 {字体系列:“Verdana”;字体重量:正常;字体大小:18pt;颜色:红色} H2 {字体系列:“Verdana”;字体重量:正常;字体大小:14pt;颜色:栗色} 前 {字体系列:“Lucida 控制台”;字体大小:.9em} .marker {字体粗细:粗体;颜色:黑色;文字装饰:无;} .version {颜色:灰色;} .error {margin-bottom: 10px;} .expandable { 文字装饰:下划线;字体粗细:粗体;颜色:海军蓝;光标:手; }

<body bgcolor="white">

        <span><H1>Server Error in '/OurApp' Application.<hr width=100% size=1 color=silver></H1>

        <h2> <i>The resource cannot be found.</i> </h2></span>

        <font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">

        <b> Description: </b>HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. &nbsp;Please review the following URL and make sure that it is spelled correctly.
        <br><br>

        <b> Requested URL: </b>/OurApp/Search/Member/26049<br><br>

        <hr width=100% size=1 color=silver>

        <b>Version Information:</b>&nbsp;Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.272

        </font>

</body>

以及此请求的相关 mvc 路由调试器结果:

让我明白的是,它显示“路径的控制器 '/OurApp/Search/Member/26049; 未找到或未实现 IController。”但是如果路由调试说它正在被击中,wtf?我迷路了。同样,我无法调试它,所以它告诉我它没有击中我的控制器或控制器操作。

【问题讨论】:

    标签: jquery ajax asp.net-mvc asp.net-mvc-3 asp.net-mvc-4


    【解决方案1】:

    您的操作正在寻找参数contractNumber,而不是id

    从此更改您的路线:

    context.MapRoute("Search_Member_GetMemberByContractNumber", 
        "Search/Member/{id}", 
        defaults: new { 
            controller = "Member", 
            action = "GetMemberByContractNumber", 
            id = UrlParameter.Optional });
    

    到这里:

    context.MapRoute("Search_Member_GetMemberByContractNumber", 
        "Search/Member/{contractNumber}", 
        defaults: new { 
            controller = "Member", 
            action = "GetMemberByContractNumber", 
            contractNumber = UrlParameter.Optional });
    

    【讨论】:

    • 这只是一个发布错误,它们匹配。我不再有 id,我将 contractNumber 作为该操作中的参数名称。这不是问题。
    • 控制器的命名空间是否与区域命名空间匹配?或者更确切地说,同样加上“.Controllers”。
    • 物理controller.cs中的namespace是什么意思?
    • 是的,我认为这不是命名空间问题。我的意思是我的默认路线有效。是我为 context.MapRoute("Search_Member", "Search/Member/{contractNumber}...
    • 我的控制器的命名空间是命名空间OurAppName.Web.Areas.Search.Controllers
    【解决方案2】:

    这总是一些愚蠢的事情,对吧?我调试了或者终于能够调试了,单步执行。什么也没看到,但后来我注意到我的 MemberAreaRegistration 的命名空间被放置在我区域内的 Views 文件夹中。我将它移到 Area/Search 的根目录,现在它似乎正在找到我的控制器,因为名称空间现在更改为 Areas.Search

    【讨论】:

    • 命名空间在 MVC 路由中很重要——尤其是在使用区域时。这有点烦人,因为它根本不明显,并且在您尝试将控制器从一个区域移动到另一个区域之前,您可能不会发现,或者在一个奇怪的地方创建一个区域并且路由停止工作。这是 MVC 中路由最糟糕​​的事情......当它中断时,它不会为您提供关于它为什么中断或如何修复它的好信息。
    【解决方案3】:

    我建议将 ajax 请求的 URL 存储在可以使用 Razor 的地方并使用 @Url.Action() 进行设置。这将确保您获得有效的路线。例如,如果$.get 是点击链接的结果,我在我的视图中将链接的href 设置为@Url.Action() 的结果,然后执行$.getJSON($(this).attr('href'), ...);。如果您稍后更改路由结构,它也会有所帮助;您无需通过 JavaScript 搜索和替换...

    请求示例:

    查看:

    <div data-search-url='@Url.Action("Index", "Member", new { area = "Search", id = 26049 })' id="whatever">...</div>
    

    JavaScript:

    var members = []; // Note that this will not be populated until $.getJSON returns
    $(function () {
        $.getJSON($('#whatever').data('search-url'), function (data) {
            members = data;
            var grid = new Slick.Grid("#searchResults-Grid", members, columns, options);
        });
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-24
      • 2016-11-12
      • 1970-01-01
      • 1970-01-01
      • 2016-07-22
      • 2011-11-30
      • 2017-09-28
      • 2021-08-14
      相关资源
      最近更新 更多