为什么找不到我的控制器操作?

Why is my Controller Action not being found?

我的 Web API 项目中有一个控制器,其开头如下:

[RoutePrefix("api/pricecompliance")]
public class PriceComplianceController : ApiController

...并且具有此路由的 Get 方法:

[Route("api/pricecompliance/{unit}/{year}/{month}")] 
public HttpResponseMessage Get(string unit, string year, string shortmonth)

但是,尝试导航到此 URL:

http://localhost:52194/api/pricecompliance/GRAMPS/2016/Mar

...给我 Web API 的 404 页面。

如果我减少到此的路由(因为控制器已经假设为 "api/pricecompliance" 路由前缀):

[Route("{unit}/{year}/{month}")]

..我得到,“找不到与请求 URI 匹配的 HTTP 资源 'http://localhost:52194/api/pricecompliance/GRAMPS/2016/Mar'."

为什么找不到方法?我有其他遵循相同模式的控制器,并且发现它们对应的 GET 方法很好。

更新

在方法前面加上可能多余的“[HttpGet]”也无济于事。

更新 2

我仍然看不出代码有何不同,以至于一个有效而另一个无效。这是相关的控制器代码:

PriceCompliance 控制器(不工作):

[RoutePrefix("api/pricecompliance")]
public class PriceComplianceController : ApiController
. . .

[Route("{unit}/{year}/{month}")]
[HttpGet]
public HttpResponseMessage Get(string unit, string year, string shortmonth)
{
    byte[] excelContents;
    . . .

ProduceUsage 控制器(正在工作):

[RoutePrefix("api/produceusage")]
public class ProduceUsageController : ApiController
. . .

    [Route("{unit}/{shortmonth}/{year}")]
    public HttpResponseMessage Get(string unit, string shortmonth, string year)
    {
        byte[] excelContents;
        . . .

以下是提供 HTML 的方法的调用方式:

PriceCompliance(不工作):

var htmlStr = ConvertPriceComplianceFileBaseNameListToHtmlPartial(_FileBaseNameList, _unit);
return htmlStr;

ProduceUsage(正在工作):

var htmlStr = ConvertProduceUsageFileBaseNameListToHtmlPartial(_FileBaseNameList, _unit);
return htmlStr;

下面是这些方法:

价格合规性(无效):

internal static string ConvertPriceComplianceFileBaseNameListToHtmlPartial(List<string> _FileBaseNameList, string unit)
{
    string year;
    string shortmonth;

    StringBuilder builder = new StringBuilder();
    builder.Append("<h2>");
    builder.Append("Price Compliance");
    builder.Append("</h2>");
    builder.Append("<p></p>");

    // Create links for each report
    foreach (String fileBaseName in _FileBaseNameList)
    {
        year = GetElement(3, fileBaseName);
        shortmonth = GetElement(4, fileBaseName);
        string fileBaseNamePrettified = PrettifyPriceComplianceFBN(fileBaseName);
        builder.Append("<p></p>");
        builder.Append(string.Format("<a href=\"pricecompliance/{0}/{1}/{2}\">{3}</a>", unit, shortmonth, year, fileBaseNamePrettified)); 
        //http://localhost:52194/api/pricecompliance/GRAMPS/2016/Mar
        builder.Append("<p></p>");
    }
    return builder.ToString();
}

产品使用(有效):

internal static string ConvertProduceUsageFileBaseNameListToHtmlPartial(List<string> _FileBaseNameList, string unit)
{
    string year;
    string shortmonth;

    StringBuilder builder = new StringBuilder();
    builder.Append("<h2>");
    builder.Append("Produce Usage");
    builder.Append("</h2>");
    builder.Append("<p></p>");

    // Create links for each report
    foreach (String fileBaseName in _FileBaseNameList)
    {
        shortmonth = GetElement(3, fileBaseName);
        year = GetElement(4, fileBaseName);
        string fileBaseNamePrettified = PrettifyProduceUsageFBN(fileBaseName);
        builder.Append("<p></p>");
        builder.Append(string.Format("<a href=\"produceusage/{0}/{1}/{2}\">{3}</a>", unit, shortmonth, year, fileBaseNamePrettified));
        builder.Append("<p></p>");
    }

    return builder.ToString();
}

我不是在摸索如何找到一个而另一个却找不到,因为它们是如此克隆。

您的路由参数名为 month 但您的方法参数名为 shortmonth:

[Route("{unit}/{year}/{month}")]
[HttpGet]
public HttpResponseMessage Get(string unit, string year, string shortmonth)

这可能是您的 404 错误背后的原因,模型绑定无法绑定 shortmonth 参数(这不是可选的),因此会报错。