Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing WCF service via HTTP

Tags:

rest

c#

wcf

service

I wrote a very simple WCF project in Visual Studio:

IBookStore:

using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;

namespace BookStore
{
    [ServiceContract]
    public interface IBookStore
    {
        [OperationContract]
        [WebGet]
        List<Book> GetBooksList();

        [OperationContract]
        [WebGet(UriTemplate = "GetBook/{id}")]  // The value of UriTemplate defines the name that the
                                                // client should use to turn to the function
        Book GetBookById(int id);

        [OperationContract]
        [WebInvoke(UriTemplate = "AddBook/{name}", Method = "PUT")]
        void AddBook(string name);

        [OperationContract]
        [WebInvoke(UriTemplate = "UpdateBook/{id}/{name}", Method = "POST")]
        void UpdateBook(int id, string name);

        [OperationContract]
        [WebInvoke(UriTemplate = "DeleteBook/{id}", Method = "DELETE")]
        void DeleteBook(int id);
    }


    [DataContract]
    public class Book
    {
        int id;
        string name;


        [DataMember]
        public int ID
        {
            get { return id; }
            set { id = value; }
        }

        [DataMember]
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }
}

BookStoreImpl:

using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Activation;

namespace BookStore
{
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class BookStoreImpl : IBookStore
    {
        public void AddBook(string name)
        {
            using (var db = new BookStoreContext())
            {
                Book book = new BookStore.Book { Name = name };
                db.Books.Add(book);
                db.SaveChanges();
            }
        }

        public void DeleteBook(int id)
        {
            try
            {
                using (var db = new BookStoreContext())
                {
                    Book book = db.Books.Find(id);
                    db.Books.Remove(book);
                    db.SaveChanges();
                }
            }
            catch
            {
                throw new FaultException("Something went wrong");
            }
        }

        public Book GetBookById(int id)
        {
            using (var db = new BookStoreContext())
            {
                return db.Books.Find(id);
            }
        }

        public List<Book> GetBooksList()
        {
            List<Book> allBooks = new List<Book>();
            try
            {
                using (var db = new BookStoreContext())
                {
                    IEnumerator<Book> booksEnum = db.Books.GetEnumerator();
                    booksEnum.Reset();
                    while (booksEnum.MoveNext())
                    {
                        allBooks.Add(booksEnum.Current);
                    }
                }
            }
            catch
            {
                throw new FaultException("Something went wrong");
            }
            return allBooks;
        }

        public void UpdateBook(int id, string name)
        {
            try
            {
                using (var db = new BookStoreContext())
                {
                    Book book = db.Books.Find(id);
                    book.Name = name;
                    db.SaveChanges();
                }
            }
            catch
            {
                throw new FaultException("Something went wrong");
            }
        }
    }
}

My WebConfig file is:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5.2" />
    <httpRuntime targetFramework="4.5.2" />
    <httpModules>
      <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />
    </httpModules>
  </system.web>

  <system.serviceModel>     
    <behaviors>
        <serviceBehaviors>
            <behavior name="MyServiceBehavior">
                <serviceMetadata httpGetEnabled="true"    />
                <serviceDebug includeExceptionDetailInFaults="true"/>          
            </behavior>
        </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="WebBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>    
    <services>      
      <service behaviorConfiguration="MyServiceBehavior" name="BookStore.BookStoreImpl">
        <endpoint address="http://localhost:8080/bookservice/" binding="wsHttpBinding" contract="BookStore.IBookStore" />
        <endpoint address="" behaviorConfiguration="WebBehavior"
                  binding="webHttpBinding"
                  contract="BookStore.IBookStore">
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>    
  </system.serviceModel>
  <!--
  <system.serviceModel>
    <services>
      <service name="BookStore.BookStoreImpl">
        <endpoint address="http://localhost:8080/bookservice"
            behaviorConfiguration="restfulBehavior" binding="webHttpBinding"
            bindingConfiguration="" contract="BookStore.IBookStore"
            />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8080/bookservice" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="restfulBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <protocolMapping>
      <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  -->
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="ApplicationInsightsWebTracking" />
      <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" />
    </modules>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true" />
    <validation validateIntegratedModeConfiguration="false" />
  </system.webServer>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="mssqllocaldb" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>

I have also created the database, attached it to the project with the .mdf file, compiled and run the project and I can see the timer running in the right corner of the screen after I run the project. Then I open my browser, type into the address box: http://localhost:8080/bookservice/GetBooksList and press enter and I get an error page instead. Doesn't look like my requests ever get to the server in the first place. Can anyone please help me understand why?

Here's the error: enter image description here

EDIT: I noticed that if I set a breakpoint somewhere and run, I see the following error in the "WCF Test Client" window that pops up: "Error: Cannot obtain Metadata from http://localhost:59250/BookStoreImpl.svc If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address. For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange Error URI: http://localhost:59250/BookStoreImpl.svc Metadata contains a reference that cannot be resolved: 'http://localhost:59250/BookStoreImpl.svc'. The requested service, 'http://localhost:59250/BookStoreImpl.svc' could not be activated. See the server's diagnostic trace logs for more information.HTTP GET Error URI: http://localhost:59250/BookStoreImpl.svc There was an error downloading 'http://localhost:59250/BookStoreImpl.svc'. The request failed with the error message:-- No protocol binding matches the given address 'http://localhost:8080/bookservice/'. Protocol bindings are configured at the Site level in IIS or WAS configuration. body {font-family:"Verdana";font-weight:normal;font-size: .7em;color:black;} p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px} b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px} H1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red } H2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon } pre {font-family:"Consolas","Lucida Console",Monospace;font-size:11pt;margin:0;padding:0.5em;line-height:14pt} .marker {font-weight: bold; color: black;text-decoration: none;} .version {color: gray;} .error {margin-bottom: 10px;} .expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; } @media screen and (max-width: 639px) { pre { width: 440px; overflow: auto; white-space: pre-wrap; word-wrap: break-word; } } @media screen and (max-width: 479px) { pre { width: 280px; } }

Server Error in '/' Application.

No protocol binding matches the given address 'http://localhost:8080/bookservice/'. Protocol bindings are configured at the Site level in IIS or WAS configuration.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: No protocol binding matches the given address 'http://localhost:8080/bookservice/'. Protocol bindings are configured at the Site level in IIS or WAS configuration.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:

[InvalidOperationException: No protocol binding matches the given address 'http://localhost:8080/bookservice/'. Protocol bindings are configured at the Site level in IIS or WAS configuration.] System.ServiceModel.Activation.HostedAspNetEnvironment.GetBaseUri(String transportScheme, Uri listenUri) +109963 System.ServiceModel.Channels.TransportChannelListener.OnOpening() +13058405 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +265 System.ServiceModel.Channels.DatagramChannelDemuxer2.OnOuterListenerOpen(ChannelDemuxerFilter filter, IChannelListener listener, TimeSpan timeout) +445 System.ServiceModel.Channels.SingletonChannelListener3.OnOpen(TimeSpan timeout) +78 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +308 System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout) +61[InvalidOperationException: The ChannelDispatcher at 'http://localhost:8080/bookservice/' with contract(s) '"SecurityNegotiationContract"' is unable to open its IChannelListener.] System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout) +134 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +308 System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) +136 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +308 System.ServiceModel.Security.NegotiationTokenAuthenticator1.OnOpen(TimeSpan timeout) +137 System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout) +21 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +308 System.ServiceModel.Security.CommunicationObjectSecurityTokenAuthenticator.Open(TimeSpan timeout) +23 System.ServiceModel.Security.SymmetricSecurityProtocolFactory.OnOpen(TimeSpan timeout) +513 System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout) +21 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +308 System.ServiceModel.Security.SecurityListenerSettingsLifetimeManager.Open(TimeSpan timeout) +86 System.ServiceModel.Channels.SecurityChannelListener1.OnOpen(TimeSpan timeout) +240 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +308 System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout) +61[InvalidOperationException: The ChannelDispatcher at 'http://localhost:8080/bookservice/' with contract(s) '"IssueAndRenewSession"' is unable to open its IChannelListener.] System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout) +134 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +308 System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) +136 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +308 System.ServiceModel.Security.SecuritySessionSecurityTokenAuthenticator.OnOpen(TimeSpan timeout) +129 System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout) +21 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +308 System.ServiceModel.Security.CommunicationObjectSecurityTokenAuthenticator.Open(TimeSpan timeout) +23 System.ServiceModel.Security.SecuritySessionServerSettings.OnOpen(TimeSpan timeout) +759 System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout) +21 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +308 System.ServiceModel.Security.SecurityListenerSettingsLifetimeManager.Open(TimeSpan timeout) +130 System.ServiceModel.Channels.SecurityChannelListener1.OnOpen(TimeSpan timeout) +240 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +308 System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout) +61[InvalidOperationException: The ChannelDispatcher at 'http://localhost:8080/bookservice/' with contract(s) '"IBookStore"' is unable to open its IChannelListener.] System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout) +134 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +308 System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) +136 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +308 System.ServiceModel.HostingManager.ActivateService(ServiceActivationInfo serviceActivationInfo, EventTraceActivity eventTraceActivity) +110 System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath, EventTraceActivity eventTraceActivity) +641[ServiceActivationException: The service '/BookStoreImpl.svc' cannot be activated due to an exception during compilation. The exception message is: The ChannelDispatcher at 'http://localhost:8080/bookservice/' with contract(s) '"IBookStore"' is unable to open its IChannelListener..] System.Runtime.AsyncResult.End(IAsyncResult result) +481507 System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result) +174 System.ServiceModel.Activation.ServiceHttpModule.EndProcessRequest(IAsyncResult ar) +351314 System.Web.AsyncEventExecutionStep.OnAsyncEventCompletion(IAsyncResult ar) +9791593</pre></code> </td> </tr> </table> <br> <hr width=100% size=1 color=silver> <b>Version Information:</b>ÿMicrosoft .NET Framework Version:4.0.30319; ASP.NET Version:4.6.1586.0 </font> </body></html><!-- [InvalidOperationException]: No protocol binding matches the given address 'http://localhost:8080/bookservice/'. Protocol bindings are configured at the Site level in IIS or WAS configuration. at System.ServiceModel.Activation.HostedAspNetEnvironment.GetBaseUri(String transportScheme, Uri listenUri) at System.ServiceModel.Channels.TransportChannelListener.OnOpening() at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Channels.DatagramChannelDemuxer2.OnOuterListenerOpen(ChannelDemuxerFilter filter, IChannelListener listener, TimeSpan timeout) at System.ServiceModel.Channels.SingletonChannelListener3.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout)[InvalidOperationException]: The ChannelDispatcher at 'http://localhost:8080/bookservice/' with contract(s) '"SecurityNegotiationContract"' is unable to open its IChannelListener. at System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Security.NegotiationTokenAuthenticator1.OnOpen(TimeSpan timeout) at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Security.CommunicationObjectSecurityTokenAuthenticator.Open(TimeSpan timeout) at System.ServiceModel.Security.SymmetricSecurityProtocolFactory.OnOpen(TimeSpan timeout) at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Security.SecurityListenerSettingsLifetimeManager.Open(TimeSpan timeout) at System.ServiceModel.Channels.SecurityChannelListener1.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout)[InvalidOperationException]: The ChannelDispatcher at 'http://localhost:8080/bookservice/' with contract(s) '"IssueAndRenewSession"' is unable to open its IChannelListener. at System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Security.SecuritySessionSecurityTokenAuthenticator.OnOpen(TimeSpan timeout) at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Security.CommunicationObjectSecurityTokenAuthenticator.Open(TimeSpan timeout) at System.ServiceModel.Security.SecuritySessionServerSettings.OnOpen(TimeSpan timeout) at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Security.SecurityListenerSettingsLifetimeManager.Open(TimeSpan timeout) at System.ServiceModel.Channels.SecurityChannelListener1.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout)[InvalidOperationException]: The ChannelDispatcher at 'http://localhost:8080/bookservice/' with contract(s) '"IBookStore"' is unable to open its IChannelListener. at System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.ServiceHostingEnvironment.HostingManager.ActivateService(ServiceActivationInfo serviceActivationInfo, EventTraceActivity eventTraceActivity) at System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath, EventTraceActivity eventTraceActivity)[ServiceActivationException]: The service '/BookStoreImpl.svc' cannot be activated due to an exception during compilation. The exception message is: The ChannelDispatcher at 'http://localhost:8080/bookservice/' with contract(s) '"IBookStore"' is unable to open its IChannelListener.. at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result) at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result) at System.ServiceModel.Activation.ServiceHttpModule.EndProcessRequest(IAsyncResult ar) at System.Web.HttpApplication.AsyncEventExecutionStep.OnAsyncEventCompletion(IAsyncResult ar)-->--."
like image 456
logcat Avatar asked Dec 25 '16 13:12

logcat


2 Answers

Seems like the problem with your WCF hosting.

WCF service should run inside some host. It could be console application, ASP.NET application, windows service, etc.

Before you're trying to access the url http://localhost:8080/bookservice/, have you deployed your service as IIS application with specified address?

Most likely you're just launching your application under debug in Visual Studio. In this case you should check whether Project url is configured correctly. Open Project properties, Web tab. What address is specified in 'Project Url' edit box?

enter image description here

By default VS puts there 'localhost:some random port', e.g.: http://localhost:38577/. And in your case the port is most likely 59250 that is seen from error

Error: Cannot obtain Metadata from http://localhost:59250/BookStoreImpl.svc

If this is the case and you want to stick to your Web.config, then change this value to http://localhost:8080/bookservice/, press 'Create Virtual Directory' and relaunch debug session. Then try to access GetBooksList method again.

like image 182
CodeFuller Avatar answered Nov 01 '22 16:11

CodeFuller


To see if basic binding works can you make this change.

<service behaviorConfiguration="MyServiceBehavior" name="BookStore.BookStoreImpl">
    <endpoint address="" 
              behaviorConfiguration="WebBehavior"
              binding="basicHttpBinding"
              bindingConfiguration="HttpBinding"    
              contract="BookStore.IBookStore">
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
like image 38
Ross Bush Avatar answered Nov 01 '22 15:11

Ross Bush