【问题标题】:Web Api Get() route not working when return type is HttpResponseMessage返回类型为 HttpResponseMessage 时,Web Api Get() 路由不起作用
【发布时间】:2013-01-29 05:23:15
【问题描述】:

这让我有点头疼。最终,我试图返回一个图像,但我一直在尝试并将其简化为使用字符串。

我想要的: 转到网址:

http://xxx/api/helloworld/1

响应:“Hello world!”

以下 web api 声明适用于提供的 url;

public string Get([FromUri]int id) { return "Hello World"; }
public Task<string> Get([FromUri]int id) { return "Hello World"; }

什么不起作用;

public HttpResponseMessage Get([FromUri]int id) 
{ 
    return Request.CreateResponse<string>(HttpStatusCode.OK, "Hello World");
}

public HttpResponseMessage Get([FromUri]int id)
{
    HttpResponseMessage response = new HttpResponseMessage();

    string text = "Hello World";
    MemoryStream test = new MemoryStream();
    test.Write(ConversionUtilities.ToBytes(text) /*custom string->byte[] method, UTF-8 encoding*/, 0, text.Length);

    response.Content = new StreamContent(test);
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/plain");
    response.StatusCode = HttpStatusCode.OK;

    return response;
}

当我有一个返回类型为 HttpResponseMessage 的 Get() 时会发生以下错误;

No HTTP resource was found that matches the request URI "http://xxx/api/helloworld/1"

此错误仅针对此特定返回类型出现。现在,我在 WebApiConfig.cs 文件中的路由如下(适用于“字符串”返回类型);

// Controller with ID
// To handle routes like "/api/VTRouting/1"
config.Routes.MapHttpRoute(
    name: "ControllerAndId",
    routeTemplate: "api/{controller}/{id}",
    defaults: null,
    constraints: new { id = @"^\d+$" } // Only integers 
);

// Controllers with Actions
// To handle routes like "/api/VTRouting/route"
config.Routes.MapHttpRoute(
    name: "ControllerAndAction",
    routeTemplate: "api/{controller}/{action}"
);

// Controller Only
// To handle routes like "/api/VTRouting"
config.Routes.MapHttpRoute(
    name: "ControllerOnly",
    routeTemplate: "api/{controller}"
);

有什么想法吗?我对返回类型的行为感到困惑:-S

【问题讨论】:

  • 您的控制器名称是 HelloWorld 吗?
  • 就示例代码而言,是的。一个名为 HelloWorldController 的 ApiController 应该与上面的示例一起使用
  • 如何在同一个名为“Get”的控制器上使用相同的参数执行两个操作?您是否尝试过从本地计算机调用 Web API 或将 config.IncludeErrorDetailPolicy 设置为 Always。您可能会得到更好的错误信息。
  • 据我所知有三种方式。您可以通过参数名称进行区分,通过操作名称属性创建您的操作(仅适用于不以 Get 开头的方法),或者通过不同的方法名称(例如 Get1 和 Get2)并直接在您的 uri 中使用它们,例如 api/mycontroller/Get1。
  • 恐怕这也行不通。对于返回类型“string”和“HttpResponseMessage”,我现在得到相同的“resource not found”响应。我做了更多的调整,如果路由(完全)不正确,IIS 将返回 IIS 资源错误。我的帖子中指定的错误消息似乎来自 web-api 路由机制,它正确解释了 URL,但找不到正确的调用方法。可能暗示路由配置需要指定HttpResponseMessage返回类型?

标签: c# asp.net-mvc asp.net-web-api asp.net-mvc-routing


【解决方案1】:

找到原因了!我根据有效的模板创建了一个空白的 api 控制器。提示一些复制/粘贴以缩小原因。这是微妙的,我发布的代码有效,因为我更改了公开发布的变量名——这最终是问题的原因。去图吧。

要复制,请照常创建模板。这将创建一个方法;

public string Get(int id)

把这个改成;

public string Get(int personID)

然后尝试运行。您将收到上述错误。似乎 Get/Post/etc 参数的声明必须与路由中指定的相匹配。如果您像我一样将参数更改为“personID”,您可以通过将参数重命名回默认的“id”或使用更新名称修改路由来修复;

config.Routes.MapHttpRoute(
    name: "ControllerAndId",
    routeTemplate: "api/{controller}/{personID}",
    defaults: null,
    constraints: new { personID = @"^\d+$" } // Only integers 
);

注意 routeTemplate 和约束参数中的“{personID}”。此字段的名称必须与您的参数名称匹配。在查找如何下载文件或只是一般地查看 web api 时,它实际上从未在文档中说过这一点。在深入了解路由/mvc 的详细信息时可能会这样做,但我不得不说这很容易让一个不熟悉的 n00b 绊倒。请注意,我更有经验的同事也没有发现这一点:-)。我希望这可以帮助其他有同样痛苦的人!

【讨论】:

  • 是的,它必须与定义的路由匹配。否则它将如何为方法参数赋值?
  • @MEMark - 位置上是一种选择。
猜你喜欢
  • 2013-02-23
  • 2012-09-19
  • 2015-02-21
  • 2018-10-10
  • 2013-04-01
  • 2014-03-12
  • 2013-11-26
  • 2013-12-11
  • 1970-01-01
相关资源
最近更新 更多