简体   繁体   中英

WebAPI returns 404 (Not Found)

I have created a simple Web API to return an HTML string from domain/api/html/footer :

public class htmlController : ApiController
{
    // GET api/html
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }

    // GET api/html/section
    public string Get(string id)
    {
        if (id == "footer") return "<div>FOO</div>";
        return null;
    }
}

Untouched WebApiConfig.cs :

public static void Register(HttpConfiguration config)
{
    config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}/",
            defaults: new { id = RouteParameter.Optional }
        );
}

I added the WebAPI to the domain/api/ folder of a domain that includes a separate project (on its root folder).

Can it be that the WebAPI project expects to be in the root folder? If so, how can i fix it to work on the /api/ folder? If not, what can be happening? ( Both /api/html and /api/html/footer/ work fine when i run it from Visual Studio! )

EDIT:

Can this be some IIS setting (ie, it doesn't encounter an index.htm/default.aspx/etc page)? Navigating to domain/api/ says not found right away, despite the /api/ dir being there. Or perhaps in Web.config , most likely the <system.webServer> section, but the solutions offered (ie, change path of ExtensionlessUrlHandler to * instead of *. ) on SO, etc didn't work. In this example i gave, the server delivers a 500 error.

You have to set the route path.

With this code you posted:

public class htmlController : ApiController
{
    // GET api/html
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }

    // GET api/html/section
    public string Get(string id)
    {
        if (id == "footer") return "<div>FOO</div>";
        return null;
    }
}

You have these routes: GET: api/html GET: api/html/id

If you want some of this methods called from the route api/html/footer , you'll need to configure it. You can do something like:

[RoutePrefix("api/html")]
public class htmlController : ApiController
{
    // GET api/html
    [Route("footer")]
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }

    // GET api/html/section
    [Route("footer/{id}")]
    public string Get(string id)
    {
        if (id == "footer") return "<div>FOO</div>";
        return null;
    }
}

Edit .Net 4

I have created the folders domain/api on the root of the project and added the controller the same way you did:

public class HtmlController : ApiController
{
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }

    public string Get(string id)
    {
        if (id == "footer") return "<div>FOO</div>";
        return null;
    }
}

控制器的文件夹

And I'm using .net framework 4

在此处输入图片说明

Here's the result when I call api/html/footer :

结果

Have you created a WebApiConfig and added to your Global.asax ?

public class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        config.Routes.MapHttpRoute(
            name: "DefaultApiWithAction",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new
            {
                id = RouteParameter.Optional,
                action = RouteParameter.Optional
            }
        );
    }
}

public class Global : System.Web.HttpApplication
{

    protected void Application_Start(object sender, EventArgs e)
    {

        WebApiConfig.Register(GlobalConfiguration.Configuration);
    }

    // ... the rest of your global.asax
}

Based on what you are saying about adding it to domain/api then according to config your api is now configured for domain/api/api/html/footer . VS by default debugs on a root unless configured otherwise.

If there are not going to be any normal MVC calls you could safely change the routeTemplate to routeTemplate: "{controller}/{id}/"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM