RHarris
RHarris

Reputation: 11187

WCF Service works locally but gives 404 on server

I've seen a number of posts about this, but can't seem to actually find an answer.

[Disclaimer: I don't know a lot about WCF -- Although I have access to the code, this is an existing project that I'm trying to connect to.]

I've created a html/javascript client to access an existing WCF Service API. Each is a separate application so when I run locally, the client and server are both running on localhost but with different port numbers. This works. The client app is able to call a WCF service with a call like: https://localhost:4435/sessions.svc/getsession?sessionPK=3.

When I install both apps on a server (both running on the same server as different virtual applications), the service is indeed running -- I can hit https://myserver.com/api/sessions.svc from a web-browser and I get a page back from the service telling me that its working.

However, now when the client tries to access the service the same way that it did locally (https://myserver.com/api/sessions.svc/getsession?sessionPK=3), I get a 404 Not Found error.

Client and WCF Service are both hosted on the same server with the same root domain -- so CORS shouldn't be an issue.

Here are some code snippets:

** WCF Service **

[ServiceContract]
public interface ISessions
{
    [OperationContract]
    [WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
    string GetSession(int? sessionPK);

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Sessions : BaseService, ISessions
    {
        public string GetSession(int sessionPK)
        {
          ...
        }
}

** Web.Config for Service **

<service behaviorConfiguration="BehaviorConfig" name="Sessions">
  <endpoint address="" binding="webHttpBinding" behaviorConfiguration="json"  contract="ISessions">
    <identity>
      <dns value="localhost"/>
    </identity>
  </endpoint>
  <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>

** Client **

export class DataService {

   constructor(private http : HttpClient){
     this.http.configure(config => {
      config.withBaseUrl("https://myserver.com/api/");
      config.withHeader("Accept", "application/json");
      config.withHeader("Content-Type", "application/json");
      config.withCredentials(true);
    })
  }

  public async getSessionById(id : number = 0){
    try{
       let result = this.http.get(`sessions.svc/getsession?sessionPK=${id}`);
       if(!result.isSuccess)
          throw response;

       ...
    }
    catch(error : any){
       ...
    }
}

Update

In response to Peter, I get the same response from https://myserver.com/api/sessions.svc as I do from https://myserver.com/api/sessions.svc?wsdl. It is a page like this:

enter image description here

The service doesn't seem to return a list of the operations it exposes. Incidentally, it performs exactly the same way on localhost.

Upvotes: 0

Views: 941

Answers (2)

RHarris
RHarris

Reputation: 11187

Turns out, I was running HTTP locally and HTTPS on the server. I resolved my issue by adding the following:

 <webHttpBinding>
   <binding>
     <security mode="Transport"></security>
   </binding>
 </webHttpBinding>

Upvotes: 1

Ding Peng
Ding Peng

Reputation: 3964

If CORS is not a problem, the URI or format of your access service may be wrong.You can open the help document in the service to see how to request the interface:

        <endpointBehaviors>
            <behavior name="ESEndPointBehavior">
                <webHttp helpEnabled="true"/>
            </behavior>
        </endpointBehaviors>

Access help documents:

enter image description here

This is the design of the service interface:

      [OperationContract]
    [WebGet(UriTemplate = "user/?name={name}",RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
    Result GetUserData(string name);

I didn't set bodystyle to WebMessageBodyStyle.Wrapped Because WebMessageBodyStyle.Wrapped It is mainly used to encapsulate body, but there is no body in get method.And set "WebMessageBodyStyle.Wrapped" the help document will not generate the correct request format.It will be like this:

enter image description here

Normal help documents should look like this:

enter image description here

It contains the URI and format of the request.

Upvotes: 0

Related Questions