Search code examples
c#winformswcfwcf-bindingwcf-hosting

Hosting WCF service via ServiceHost in Console/WinForms


I'm hosting WCF service in console application (.NET 4.0). Service code (from msdn example):

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

namespace WCFServiceHost
{
    [ServiceContract(Namespace = "WCFServiceHost")]
    public interface ICalculator
    {
        [WebInvoke(ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
        MathResult DoMathJson(double n1, double n2);

        [WebInvoke(ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Wrapped)]
        MathResult DoMathXml(double n1, double n2);

    }

    public class CalculatorService : ICalculator
    {

        public MathResult DoMathJson(double n1, double n2)
        {
            return DoMath(n1, n2);
        }

        public MathResult DoMathXml(double n1, double n2)
        {
            return DoMath(n1, n2);
        }

        private MathResult DoMath(double n1, double n2)
        {
            MathResult mr = new MathResult();
            mr.sum = n1 + n2;
            mr.difference = n1 - n2;
            mr.product = n1 * n2;
            mr.quotient = n1 / n2;
            return mr;
        }
    }

    [DataContract]
    public class MathResult
    {
        [DataMember]
        public double sum;

        [DataMember]
        public double difference;

        [DataMember]
        public double product;

        [DataMember]
        public double quotient;
    }
}

Next the console app code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace WCFServiceHost
{
    class Program
    {
        public static void Main()
        {
            var adrs = new Uri[1];
            adrs[0] = new Uri("http://localhost:3980");
            using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), adrs))
            {
                try
                {
                    // Open the ServiceHost to start listening for messages.
                    serviceHost.Open();

                    // The service can now be accessed.
                    Console.WriteLine("The service is ready.");
                    Console.WriteLine("Press <ENTER> to terminate service.");
                    Console.ReadLine();

                    // Close the ServiceHost.
                    serviceHost.Close();
                }
                catch (TimeoutException timeProblem)
                {
                    Console.WriteLine(timeProblem.Message);
                    Console.ReadLine();
                }
                catch (CommunicationException commProblem)
                {
                    Console.WriteLine(commProblem.Message);
                    Console.ReadLine();
                }
            }
        }
    }
}

And my 2 questions:

1. When I'm open _http://localhost:3980 I've get: enter image description here How to enable metadata publishing? See Dai Bok answer.

  1. Now how to get data from this service - (to get data from service like in msdn example)? Embed any web framework (like Nancy) or use HttpListener?

Solution

  • You need to make sure you WCF web config is set up correctly

    You will need to enable metat data for http gets, check you web config in the system.serviceModel -> behaviors -> serviceBehaviors -> behavior -> serviceMetadata

    and make sure you have:

    <serviceMetadata httpGetEnabled="true"/>
    

    For Part 2, you can get the data, you can do something like

       public MathResult GetResult(int a, int b) {
            var status = new MathResult();
            try {
                        var myBinding = new WSHttpBinding();
                        var myEndpoint =
                            new EndpointAddress(
                                new Uri("http://localhost:3980/"));
                        var myChannelFactory = new ChannelFactory<ICalculator>(myBinding, myEndpoint);
                        ICalculator client = myChannelFactory.CreateChannel();
                status = client.DoMathJson(a,b);
            } catch (Exception e) {
                //do something proper here 
            }
            return status;
        }