asp.net WebForms的WebApi路由返回404

时间:2014-05-07 22:27:29

标签: c# ajax asp.net-web-api

我在asp.net WebForms应用程序中配置WebApi路由时遇到了一些麻烦。

global.asax文件中,我有类似的内容:

void Application_Start(object sender, EventArgs e)
{
    GlobalConfiguration.Configure(WebApiConfig.Register);
}

我有另一个包含此代码的文件:

using System.Web.Http;

namespace WebConfig
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                        name: "DefaultApi",
                        routeTemplate: "api/{controller}",
                        defaults: new { id = System.Web.Http.RouteParameter.Optional });
        }
    }
}

然后,在根目录中,我有一个名为api的文件夹,在该文件夹中我有一个文件,其中包含一个看起来像这样的类:

public class MyController : ApiController
{
    [Route("MyController")]
    [HttpPost]
    public HttpResponseMessage Post([FromBody]string value)
    {....}

最后,在我的客户端代码中,我有这个ajax调用:

$.ajax({
    url: "/api/MyController",
    contentType: "application/json; charset=utf-8",
    type: "POST",
    dataType: "json",
    cache: "false",
    data: someData});

但是,当我运行此代码时,我得到的只是404错误。我需要在路由机制中进行哪些更改才能使其工作?

感谢。

8 个答案:

答案 0 :(得分:2)

我认为其他人非常接近。试试这个:

[RoutePrefix("api")]  // or maybe "api/", can't recall OTTOMH...
public class MyController : ApiController
{
    [Route("MyController")]
    [HttpPost]
    public HttpResponseMessage Post([FromBody]string value)

然后请求/api/MyController

如果这不起作用,请使用RouteDebugger分析您的路线,以及拒绝匹配的原因。使用您在RouteDebugger中看到的内容修改您的问题,以便我可以追踪不匹配的内容。

此外,您可能需要在MapHttpAttributeRoutes功能中调用Register - 但不确定。


修改

现在我再次看到它,我想我发现它有更多问题。

首先,让我们从模板开始:

以下是您的问题(来自您的问题):

config.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}",
                    defaults: new { id = System.Web.Http.RouteParameter.Optional });

这里的奇怪部分是您的模板没有{id}段,但定义为可选。听起来模板中缺少它,并且路线应该更改为:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = System.Web.Http.RouteParameter.Optional });

请注意,您还删除了默认操作 - 我不确定MVC是否自动使用常规方法来定位名为Post的方法,但我认为它确实如此。

第二个问题是您的方法签名(再次来自您的问题):

public HttpResponseMessage Post([FromBody]string value)

它定义了Post,它接受​​名为value的参数,而您的路由定义了名为id的参数。因此存在另一种不匹配。您可以重命名变量或装饰(见下文)。此外,{id}被标记为可选,但我相信(在这里我不记得确切的OTTOMH)你需要为那些没有提供{id}的情况给出值的默认值,所以结合一起:

public HttpResponseMessage Post([FromBody(Name="id")]string value = null)

这个应该修复它,虽然可能会有更多问题......但让我们从这些开始。

答案 1 :(得分:1)

url: "/api/MyController"更改为url: "/api/My"

答案 2 :(得分:1)

您是否考虑过使用Route属性?我发现它们比路线配置更容易。

public class MyController : ApiController
{
    [Authorize]
    [Route("MyController")]
    [HttpPost]
    public HttpResponseMessage Post([FromBody]string value)
    {....}
}

也许您还可以尝试在mvc4也支持的专用RouteConfig类中配置路由。我的路由配置设置如下所示:

/// <summary>
/// The route config class
/// </summary>
public class RouteConfig
{
    /// <summary>
    /// Registers the routes.
    /// </summary>
    /// <param name="routes">The routes.</param>
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

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

答案 3 :(得分:1)

您的RouteAttribute会覆盖配置设置,因此您有两种选择:

1)删除RouteAttribute并使用网址:/api/my

2)保留RouteAttribute并使用网址/MyController(在这种情况下忽略配置设置)

从我看到的评论中,您要导航到:api/MyController。所以第三个选项没有经过测试,但我认为它可能有用:

3)[Route("api/MyController")]

答案 4 :(得分:1)

在Controller类上使用[RoutePrefix]

[RoutePrefix("api/My")]
public class MyController : ApiController
{
    [Route("MyController")]
    [HttpPost]
    public HttpResponseMessage Post([FromBody]string value)
    {....}
}

然后你应该能够导航到api / My / MyController

答案 5 :(得分:1)

[Route("MyController")]更改为[Route("api/MyController")]

然后它将按预期工作。

答案 6 :(得分:1)

好的,经过两周多的想知道为什么看似简单的东西不起作用,我终于明白了!!!!!

问题在于这句话:

  

然后,在根目录中,我有一个名为api的文件夹,在该文件夹中   有一个文件包含 ... Web API控制器文件

解决方案原来是一个10秒钟的修复:

  

将MyWebAPIController.cs文件放在App_Code文件夹中

我拥有它的方式,.cs文件位于名为/api的根目录中,因为我错误地认为如果您想从客户端/api/MyController调用您需要创建的Web服务与该路径匹配的目录,然后将控制器放在该目录中。相反,您必须将控制器文件放在App_Code目录中。

LB2的回答确实帮助我了解属性,同时使用[RoutePrefix][Route]

[RoutePrefix("api")]
public class MyController : ApiController
{
    [Route("MyController")]
    public HttpResponseMessage Post([FromBody]string value)

然后你可以用它来调用它:

$.ajax({
    url: "/api/MyController",
    type:POST,
    ...});

谢谢大家研究这个问题!!

答案 7 :(得分:0)

我的挑战略有不同。我的设置是asp.net webforms项目并使用VS2013。我想介绍Web Api。曲线球是我的Web表单实现在VB.net中。

我想用C#编写API,所以我必须通过web.config启用codeSubDirectories选项。

<codeSubDirectories>
    <add directoryName="VBCode"/>
    <add directoryName="CSCode"/>        
</codeSubDirectories>

我分别在App_Code文件夹下创建了两个文件夹(VBCode和CSCode)。

然后我将所有的vb.net类移动到VBCode子目录。

在CSCode下创建了UserController.cs并编写了常规的web api代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace WebAPIDemo
{

public class UserController : ApiController
{
    static IUserRepository _repo = new UserRepository();
    // GET api/<controller>

    public IEnumerable<Users> GetAllUsers()
    {
        return _repo.GetAllUsers();            
    }

    // GET api/<controller>/5
    public IHttpActionResult GetUserById(int id)
    {

        return Json(_repo.GetUserById(id));
    }

修改了global.asax

<%@ Application Language="VB" %>
<%@ Import Namespace="System.Web.Routing" %>
<%@ Import Namespace="System.Web.Http" %>

<script RunAt="server">

    Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
        ' Code that runs on application startup
        RouteTable.Routes.MapHttpRoute(
             "defaultApi",
            "api/{controller}/{action}/{id}",
            defaults:=New With {.id =     System.Web.Http.RouteParameter.Optional})

    End Sub

api调用有和没有这个装饰器[RoutePrefix(&#34; api&#34;)]。

花了几个小时来弄清楚这个实现。

Call 1:
http://localhost:60203/api/user/getuserbyid/2

Result:
{"Id":2,"FirstName":"Alan","LastName":"Wake","Company":"XYZ Corp","Email":"alan@xyz.com","PhoneNo":"64649879"}

Call 2:
http://localhost:60203/api/user/getallusers

Result:
<ArrayOfUsers xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/WebAPIDemo">
<Users>
<Company>ABC</Company>
<Email>madhur@abc.com</Email>
<FirstName>Madhur</FirstName>
<Id>1</Id>
<LastName>Kapoor</LastName>
<PhoneNo>65431546</PhoneNo>
</Users>
<Users>
<Company>XYZ Corp</Company>
<Email>alan@xyz.com</Email>
<FirstName>Alan</FirstName>
<Id>2</Id>
<LastName>Wake</LastName>
<PhoneNo>64649879</PhoneNo>
</Users>
</ArrayOfUsers>