【问题标题】:MVC routing my GET request to the wrong actionMVC 将我的 GET 请求路由到错误的操作
【发布时间】:2013-01-09 18:57:25
【问题描述】:

我的应用程序中存在 URL 路由问题。我试图解决这个问题,但还没有真正取得任何进展。

所以,我在客户端发出以下 AJAX 请求:

$.ajax({
    type: 'GET',
    url: programState.getBaseUrl() + 'Playlist/GetPlaylistsByUserId',
    dataType: 'json',
    data: {
        userId: user.get('id')
    },
    success: function (data) {
        console.log("JSON data:", data);
    },
    error: function(error) {
        console.error(error);
    }
});

这是网络:

这是服务器错误:

这是控制器的 GET 和 GetPlaylistsByUserId 方法:

[HttpGet]
public ActionResult Get(Guid id)
{
    Playlist playlist = PlaylistDao.GetById(id);

    return new JsonDataContractActionResult(playlist);
}

[HttpGet, ActionName("GetPlaylistsByUserId")]
public ActionResult GetPlaylistsByUserId(Guid userId)
{
    IList<Playlist> playlists = PlaylistDao.GetByUserId(userId);

    return new JsonDataContractActionResult(playlists);
}

最后,这是我的路线:

routes.MapRoute(
    "getPlaylistsByUserId",
    "{controller}/{userId}",
    new { controller = "Playlist", action = "GetPlaylistsByUserId" },
    new { httpMethod = new HttpMethodConstraint("GET") }
);

routes.MapRoute(
    "post-Playlist",
    "{controller}",
    new { controller = "Playlist", action = "create" },
    new { httpMethod = new HttpMethodConstraint("POST") }
    );

routes.MapRoute(
    "get-Playlist",
    "{controller}/{action}/{id}",
    new { controller = "Playlist", action = "get" },
    new { httpMethod = new HttpMethodConstraint("GET") }
    );

routes.MapRoute(
    "put-Playlist",
    "{controller}",
    new { controller = "Playlist", action = "update" },
    new { httpMethod = new HttpMethodConstraint("PUT") }
    );

routes.MapRoute(
    "delete-Playlist",
    "{controller}/{id}",
    new { controller = "Playlist", action = "delete" },
    new { httpMethod = new HttpMethodConstraint("DELETE") }
    );

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new {controller = "Home", action = "Index", id = UrlParameter.Optional}
    );

尽我所能 - 我将我的 URL 路由到我的“获取”操作,但我打算将它路由到“GetPlaylistsByUserId”操作。我相信这会发生,因为服务器错误表明它正在为方法“Get”寻找参数“id”。

不过,我不确定为什么会发生这种情况,因为我似乎很清楚地映射了我的其他操作...?

【问题讨论】:

  • 尝试您的原始代码,但使用可为空的 Guid?作为参数。查看它是否通过正确的 Action 处理程序,然后检查 userid.HasValue

标签: c# asp.net-mvc-4 routing


【解决方案1】:

将路由与请求进行比较 - 您正在请求一个与路由不匹配的操作名称。就目前而言,您的路由希望您的 ajax 请求转到.../Playlist/SomeGuid,而不是Playlist/GetPlaylistsByUserId?userId=SomeGuid

如果您想将所有请求路由到您的 Playlist 控制器到 GetPlaylistsByUserId 操作(如果未指定操作),您想要的路由是:

routes.MapRoute(
    "getPlaylistsByUserId",
    "Playlist",
    new { controller = "Playlist", action = "GetPlaylistsByUserId" },
    new { httpMethod = new HttpMethodConstraint("GET") }
);

注意 userId 的省略 - 这是作为查询字符串传递的,不需要包含在您的路由中。 MVC 会自动绑定这个。

然而,就目前而言,您正在请求一个动作名称,因此以下路线将选择它:

routes.MapRoute(
    "getPlaylistsByUserId",
    "Playlist/{action}",
    new { controller = "Playlist", action = "GetPlaylistsByUserId" },
    new { httpMethod = new HttpMethodConstraint("GET") }
);

您也可以使用{controller}/{action},但我猜您不希望所有控制器都默认使用名为GetPlaylistsByUserId 的操作。

【讨论】:

  • 嘿,尝试按照您的示例..遇到其他路由问题。当我遇到困难或有更多内容要补充时,我会通知你。
  • 我已经接受了你的解决方案,因为我指出 {controller/{action} 不是同一个动作播放列表/{action}
【解决方案2】:

您的问题是请求网址看起来像

Playlist/GetPlaylistsByUserId?userid=51d77etc...

您的路由设置为:

routes.MapRoute(
    "getPlaylistsByUserId",
    "{controller}/{userId}",
    new { controller = "Playlist", action = "GetPlaylistsByUserId" },
    new { httpMethod = new HttpMethodConstraint("GET") }
);

它们不匹配。

要使用此路由,url 应如下所示:

Playlist?userid=51d77etc...

或者你的 url 应该保持不变并且路由映射应该是

routes.MapRoute(
    "getPlaylistsByUserId",
    "{controller}/{action}/{userId}",
    new { controller = "Playlist", action = "GetPlaylistsByUserId" },
    new { httpMethod = new HttpMethodConstraint("GET") }
);

【讨论】:

  • 感谢您的详细解释。我同意并尝试了你的底层代码。但是,我仍然收到同样的错误。有趣的是,如果我将 GetPlaylistsByUserId 更改为接受一个字符串并使我的 userId 参数是可选的——我将进入该操作。我仍然认为它与其他 GET 混淆了
  • 请注意我的回答 - 您将 userId 作为查询字符串值而不是路由值传递。因此,它不应出现在您的路由中。
  • 是的,我也试过了。我目前遇到了不同的错误——它至少正在路由到正确的操作,但服务器正在使用空 GUID 初始化路由并且它出错了。
【解决方案3】:
routes.MapRoute(
    "getPlaylistsByUserId",
    "{controller}/{userId}",
    new { controller = "Playlist", action = "GetPlaylistsByUserId" },
    new { httpMethod = new HttpMethodConstraint("GET") }
);

我不确定这是否可能,但有没有可能是因为您的 Url 模式中没有 {action}

routes.MapRoute(
    "getPlaylistsByUserId",
    "{controller}/{action}/{userId}",
    new { controller = "Playlist", action = "GetPlaylistsByUserId" },
    new { httpMethod = new HttpMethodConstraint("GET") }
);

【讨论】:

    【解决方案4】:
    routes.MapRoute(
        "getPlaylistsByUserId",
        "{controller}/{userId}",
        new { controller = "Playlist", action = "GetPlaylistsByUserId" },
        new { httpMethod = new HttpMethodConstraint("GET") }
    );
    

    应该改为

    routes.MapRoute(
        "getPlaylistsByUserId",
        "{controller}/GetPlaylistsByUserId/{userId}",
        new { controller = "Playlist", action = "GetPlaylistsByUserId" },
        new { httpMethod = new HttpMethodConstraint("GET") }
    );
    

    【讨论】:

      猜你喜欢
      • 2018-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-02
      • 2016-01-14
      • 2018-05-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多