我在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错误。我需要在路由机制中进行哪些更改才能使其工作?
感谢。
答案 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>