Question

Any idea why the last two URI templates report endpoint not found?

v1/version
v1/locations/{id}
v1/locations/{id}/signals
v1/locations&q={searchText}
v1/locations/signals/{signalIds}
v1/signals/{id}
v1/locations/{id}/visits
v1/locations/{locationId}/visits/{id}

All the previous 6 routes work fine, but when I added the last 2 routes, they respond with 404 "Endpoint not found" WCF framework messages. All 8 routes are GET methods, and I've verified with Fiddler that I am indeed using GET verbs. I can't see what is different from the other REST methods that are still working.

Test URL that successfully gets Location Id=2

GET http://localhost:57004/AppsService.svc/v1/locations/2

returning this correct JSON:

{
    "Id": 2,
    "Identifier": "L85",
    "Name": "The Huge Lake",
    "Signals": null
}

Here is a test URL from that attempts to get all "Visit" objects from Location ID=2

GET http://localhost:57004/AppsService.svc/v1/locations/2/visits

That URL fails with a 404 framework exception:

<HTML>
    <HEAD>
        <STYLE type="text/css">#content{ FONT-SIZE: 0.7em; PADDING-BOTTOM: 2em; MARGIN-LEFT: 30px}BODY{MARGIN-TOP: 0px; MARGIN-LEFT: 0px; COLOR: #000000; FONT-FAMILY: Verdana; BACKGROUND-COLOR: white}P{MARGIN-TOP: 0px; MARGIN-BOTTOM: 12px; COLOR: #000000; FONT-FAMILY: Verdana}PRE{BORDER-RIGHT: #f0f0e0 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #f0f0e0 1px solid; MARGIN-TOP: -5px; PADDING-LEFT: 5px; FONT-SIZE: 1.2em; PADDING-BOTTOM: 5px; BORDER-LEFT: #f0f0e0 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: #f0f0e0 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e5e5cc}.heading1{MARGIN-TOP: 0px; PADDING-LEFT: 15px; FONT-WEIGHT: normal; FONT-SIZE: 26px; MARGIN-BOTTOM: 0px; PADDING-BOTTOM: 3px; MARGIN-LEFT: -30px; WIDTH: 100%; COLOR: #ffffff; PADDING-TOP: 10px; FONT-FAMILY: Tahoma; BACKGROUND-COLOR: #003366}.intro{MARGIN-LEFT: -15px}</STYLE>
        <TITLE>Service</TITLE>
    </HEAD>
    <BODY>
        <DIV id="content">
            <P class="heading1">Service</P>
            <BR/>
            <P class="intro">Endpoint not found.</P>
        </DIV>
    </BODY>
</HTML>

Here is the full service interface code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using WebAppsService.Models;

namespace WebAppsService
{
    [ServiceContract]
    public interface IAppsService
    {
        [OperationContract]
        [WebGet(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json,
            UriTemplate = "v1/version")]
        string GetVersion();

        [OperationContract]
        [WebGet(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json,
            UriTemplate = "v1/locations/{id}")]
        Location GetLocation(string id);

        // DCSR-specific Location APIs
        [OperationContract]
        [WebGet(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json,
            UriTemplate = "v1/locations/{id}/signals")]
        List<Signal> GetLocationSignals(string id);

        [OperationContract]
        [WebGet(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json,
            UriTemplate = "v1/locations&q={searchText}")]
        List<Location> GetLocations(string searchText);

        [OperationContract]
        [WebGet(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json,
            UriTemplate = "v1/locations/signals/{signalIds}")]
        List<Location> GetLocationsContainingSignals(string signalIds);

        [OperationContract]
        [WebGet(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json,
            UriTemplate = "v1/locations/{id}/visits")]
        List<Visit> GetVisits(string id);

        [OperationContract]
        [WebGet(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json,
            UriTemplate = "v1/locations/{locationId}/visits/{id}")]
        Visit GetVisit(string locationId, string id);

        [OperationContract]
        [WebGet(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json,
            UriTemplate = "v1/signals/{id}")]
        Signal GetSignal(string id);
    }
}

Any ideas?

Was it helpful?

Solution

Found the problem: me.

After I had debugged endpoint #6, I changed the project's OutputPath property from the default of "bin" to "$(SolutionDir)\$Configuration)", a pattern we use for all our projects.

It turns out that when you debug a web project from VS, it always looks in the relative "bin\" folder for the assemblies when it launches the project via IIS or the Cassini standalone web server. The project's OutputPath property is just ignored without complaint.

So I was left debugging a stale version of my assembly that only contained routes to the first 6 endpoints. sheesh

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top