1

I have a controller function which accepts a strongly typed model as parameter. When i enter ANY url mapping to the controller but not on a specific action on the post request , then the controller executes this function instead of returning a 404 code.

When i Change the function's parameter to a primitive type variable then the problem does not occur. (i have tried using other strongly typed models as parameters and again the problem occurs)

Here's the function.

 public class PhoneApiController : ApiController
 {
    [HttpPost]
    public HttpResponseMessage RegisterApp(RegisterAppInfo appInfo)
    {


        var resp = Request.CreateResponse(HttpStatusCode.OK, new
        {
            Success = true,
            AppId = 1000,
            IdAlias = "QAUBC9",
            appInfo = appInfo 
        });
        return resp;

    }
}

So when i enter for example localhost:51464/Api/PhoneApi/Sajsdkasjdklajsasd

the function executes normally.!

I am using the default Route config

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

I don't know if this is a bug or i am doing something wrong.

4

3 回答 3

3

URI/Api/PhoneApi/Sajsdkasjdklajsasd确实将您的路由模板api/{controller}/{id}{controller}匹配PhoneApi{id}匹配匹配Sajsdkasjdklajsasd。我假设您正在对这个 URI 进行 POST。因此,Web API 将您的请求映射到控制器类中RegisterApp的操作方法。[HttpPost]PhoneApiController

至于 URI 中的垃圾内容,它被映射到{id}. 但是您的参数是RegisterAppInfo,它是一种复杂类型,并且是从请求正文而不是 URI 绑定的。这就是为什么当您拥有复杂类型时它可以工作的原因。简单类型从 URI、查询字符串绑定。

如果您将操作方法​​设置为public HttpResponseMessage RegisterApp(string id, Abc appInfo),您将看到此id参数填充有“Sajsdkasjdklajsasd”。

于 2013-07-01T16:33:09.563 回答
3

对于 MVC 4.5,这是唯一有效的

目前有一个关于此的错误

以下是一种解决方法,以使以下路线类型正常工作

api/{controller}/ //Get All
api/{controller}/{Id} //Get for id 
api/{controller}/{Id}/{Action}/  //Get all for action for controller with Id

您需要执行以下操作。

将您的路由更改为。(注意默认操作..)

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

在您的控制器中,将基本方法更改为

[ActionName("DefaultAction")]
public string Get()
{
}

[ActionName("DefaultAction")]
public string Get(int id)
{
}

[ActionName("SpaceTypes")]
public string GetSpaceTypes(int id)
{
}

现在一切都应该按预期工作..

感谢 Kip Streithorst 完整的这个,以获得完整的解释

于 2013-07-02T13:33:39.967 回答
0

Web API 中路由的工作方式是:

  1. 首先,它将 URI 与路由模板匹配。在这个阶段,它不会查看您的控制器操作
  2. 然后它寻找匹配的控制器
  3. 然后它寻找一个方法,其中(a)动作匹配(在这种情况下为 POST)和(b)每个简单的参数类型都与来自 URI 的值匹配。
  4. 如果有一个复杂的参数类型,它会尝试从请求正文中读取它。

默认情况下,Web API 尝试从 URI 绑定“简单”参数类型(如 int),并尝试从请求正文中读取复杂类型。

详情见这里:http ://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection

于 2013-07-01T16:39:28.593 回答