当返回类型为HttpResponseMessage时,Web Api Get()路由不起作用

Dis*_*nky 2 c# asp.net-mvc asp.net-mvc-routing asp.net-web-api

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

我想要的:转到URL:

http://xxx/api/helloworld/1
Run Code Online (Sandbox Code Playgroud)

回应:"Hello world!"

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

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

什么不起作用;

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;
}
Run Code Online (Sandbox Code Playgroud)

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

No HTTP resource was found that matches the request URI "http://xxx/api/helloworld/1"
Run Code Online (Sandbox Code Playgroud)

仅对此特定返回类型显示此错误.现在,我在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}"
);
Run Code Online (Sandbox Code Playgroud)

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

Dis*_*nky 5

找到了原因!我根据模板创建了一个空白的api控制器.提示一点复制/粘贴以缩小原因.它是微妙的,我发布的代码工作,因为我更改了公开发布的变量名称 - 这最终是问题的原因.去搞清楚.

要复制,请按照正常情况创建模板.这将创建一个方法;

public string Get(int id)
Run Code Online (Sandbox Code Playgroud)

将此更改为;

public string Get(int personID)
Run Code Online (Sandbox Code Playgroud)

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

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

请注意routeTemplate和constraint参数中的"{personID}".该字段的名称必须与参数名称的名称相匹配.在查找如何下载文件或只是通常查看web api时,它从未在文档中实际说明这一点.它可能在进入routing/mvc的高级细节时会发生,但我不得不说这很容易让n00b不熟悉.请注意,我更有经验的同事也没有发现这一点:-).我希望这能帮助其他人同样的痛苦!