I have a Controller in my Web API project that begins like so:
[RoutePrefix("api/pricecompliance")]
public class PriceComplianceController : ApiController
...and has a Get method with this routing:
[Route("api/pricecompliance/{unit}/{year}/{month}")]
public HttpResponseMessage Get(string unit, string year, string shortmonth)
However, attempts to navigate to this URL:
http://localhost:52194/api/pricecompliance/GRAMPS/2016/Mar
...gives me Web API's 404 page.
If I reduce the route to this (since the controller already presumedly assumes the "api/pricecompliance" route prefix):
[Route("{unit}/{year}/{month}")]
..I get, "No HTTP resource was found that matches the request URI 'http://localhost:52194/api/pricecompliance/GRAMPS/2016/Mar'."
Why is the method not being found? I have other controllers that follow the same pattern, and their corresponding GET methods are found fine.
Prepending the presumably superfluous "[HttpGet]" to the method does nothing to help matters, either.
I still can't see how the code differs so that one works and the other doesn't. Here is the pertinent controller code:
PriceCompliance controller (not working):
[RoutePrefix("api/pricecompliance")]
public class PriceComplianceController : ApiController
. . .
[Route("{unit}/{year}/{month}")]
[HttpGet]
public HttpResponseMessage Get(string unit, string year, string shortmonth)
{
byte[] excelContents;
. . .
ProduceUsage controller (is working):
[RoutePrefix("api/produceusage")]
public class ProduceUsageController : ApiController
. . .
[Route("{unit}/{shortmonth}/{year}")]
public HttpResponseMessage Get(string unit, string shortmonth, string year)
{
byte[] excelContents;
. . .
Here is how the methods that provide the HTML are called:
PriceCompliance (not working):
var htmlStr = ConvertPriceComplianceFileBaseNameListToHtmlPartial(_FileBaseNameList, _unit);
return htmlStr;
ProduceUsage (is working):
var htmlStr = ConvertProduceUsageFileBaseNameListToHtmlPartial(_FileBaseNameList, _unit);
return htmlStr;
And here are those methods:
Price Compliance (not working):
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();
}
Produce Usage (is working):
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();
}
I'm not grokking how one can be found and the other not when they are so clone-like.
Your route parameter is called month
but your method parameter is called shortmonth
:
[Route("{unit}/{year}/{month}")] [HttpGet] public HttpResponseMessage Get(string unit, string year, string shortmonth)
This might be the reason behind your 404 errors, the model binding cannot bind shortmonth
parameter (which is not optional) and thus complains.