none
VS2017 WCF Service Library installed as a Windows Service RRS feed

  • Question

  • We are going to be using a WCF Service library which will be installed as a Windows Service. What I am trying to figure out is how are we going to control the service address once deployed. We have 1000's of customers that will be hosting the service with clients within their business connected to the service. I see while developing, the client can just add a service reference and everything works fine but this will not be the case once deployed. The clients connecting to the server will have to be told the service address I assume and then actually have to put the address in to connect to the service?

    What I am trying to get at is I want to install the WCF Service as a windows service on a machine and then install my client on another machine and connect to the service. How to I explicitly define the Service address such that my clients can connect to the service? I do not see any overrides in the service library that would allow me to explicitly define the service address at run-time.

    <host>
              <baseAddresses>
                <add baseAddress="http://*:8733/Design_Time_Addresses/SIS.Apps.Service/Service1/" />
              </baseAddresses>
    </host>

    That needs to be set dynamically at runtime which will be read from an INI file

    Any help would be appreciated. I think I am just missing something or not understanding something.



    Friday, June 1, 2018 3:02 PM

Answers

  • Hi brown,

    >>When I run The Android project the service will start since I set up a proxy project and then when it gets to the line in the MainActivity.cs below, I get a NoEndpointException

    It seems the Android fail to find the endpoint address, I suggest you try to use ip address instead of "sisdev-ws1:5000".

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, June 7, 2018 5:34 AM

All replies

  • Hi brown,

    For changing endpoint address at runtime, you will need to configure the service by code instead of configuring in web.config.

    #Configuring WCF Services in Code

    https://docs.microsoft.com/en-us/dotnet/framework/wcf/configuring-wcf-services-in-code

    You could configure above code in Windows Service.

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, June 4, 2018 3:24 AM
  • This is our issue. The Service will be hosted by 1000's of company's. Each company will host it with their own address. So the service endpoint will need to be defined upon install for each company. There will be one universal app (Android, iOS, Windows) that will need to connect to a specific company's service. I have written the service and able to get it installed as a Windows service with the default endpoint (http://localhost:8733/Design_Time_Addresses/SIS.Apps.Service/Service1/) but what I am not understanding is how to code the apps in order to connect to the service. Remind you that the apps upon install or first run will need to define the company's service endpoint they are connecting to .



    • Edited by brown71576 Tuesday, June 5, 2018 4:30 PM
    Tuesday, June 5, 2018 3:33 PM
  • Hi brown,

    >>but what I am not understanding is how to code the apps in order to connect to the service. 

    You will need to set the endpoint address at universal app which you defined while installing.

    What is your issue for this process?

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, June 6, 2018 1:52 AM
  • The company will notify all their customers the service address and then they will be able to add the service address in to their app and a customer password in order to retrieve data from the service.

    Our project is set up like the following

    For our service code, which is generic at this point looks like the following:

    Screenshot of project:

    AppsService.cs

    using System;
    
    
    namespace SIS.Apps.Service
    {
        // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in both code and config file together.
        public class AppsService : IAppsService
        {
            public string GetData(int value)
            {
                return string.Format("You entered: {0}", value);
            }
    
            public CompositeType GetDataUsingDataContract(CompositeType composite)
            {
                if (composite == null)
                {
                    throw new ArgumentNullException("composite");
                }
                if (composite.BoolValue)
                {
                    composite.StringValue += "Suffix";
                }
                return composite;
            }
        }
    }


    IAppsService.cs

    using System.Runtime.Serialization;
    using System.ServiceModel;
    
    namespace SIS.Apps.Service
    {
        // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IAppsService" in both code and config file together.
        [ServiceContract]
        public interface IAppsService
        {
            [OperationContract]
            string GetData(int value);
    
            [OperationContract]
            CompositeType GetDataUsingDataContract(CompositeType composite);
    
            // TODO: Add your service operations here
        }
    
        // Use a data contract as illustrated in the sample below to add composite types to service operations.
        // You can add XSD files into the project. After building the project, you can directly use the data types defined there, with the namespace "SIS.Apps.Service.ContractType".
        [DataContract]
        public class CompositeType
        {
            bool boolValue = true;
            string stringValue = "Hello ";
    
            [DataMember]
            public bool BoolValue
            {
                get { return boolValue; }
                set { boolValue = value; }
            }
    
            [DataMember]
            public string StringValue
            {
                get { return stringValue; }
                set { stringValue = value; }
            }
        }
    }


    SISAppsServiceInstaller.cs

    using System.ComponentModel;
    using System.Configuration.Install;
    using System.ServiceProcess;
    
    namespace SIS.Apps.Service
    {
        [RunInstaller(true)]
        public class SISAppsServiceInstaller : Installer
        {
            private ServiceProcessInstaller process;
            private ServiceInstaller service;
    
            public SISAppsServiceInstaller()
            {
                process = new ServiceProcessInstaller();
                process.Account = ServiceAccount.LocalSystem;
                service = new ServiceInstaller();
                service.ServiceName = "SIS.Apps.Service";
                Installers.Add(process);
                Installers.Add(service);
            }
        }
    }


    SISAppsWindowsService.cs

    using System.ServiceProcess;
    using System.ServiceModel;
    
    namespace SIS.Apps.Service
    {
        public class SISAppsWindowsService : ServiceBase
        {
            public ServiceHost serviceHost = null;
    
            public SISAppsWindowsService()
            {
            }
    
            public static void Main()
            {
                ServiceBase.Run(new SISAppsWindowsService());
            }
    
            protected override void OnStart(string[] args)
            {
                if (serviceHost != null)
                {
                    serviceHost.Close();
                }
    
                // Create a ServiceHost for the AppService type and 
                // provide the base address.
                serviceHost = new ServiceHost(typeof(AppsService));
    
                // Open the ServiceHostBase to create listeners and start 
                // listening for messages.
                serviceHost.Open();
            }
    
            protected override void OnStop()
            {
                if (serviceHost != null)
                {
                    serviceHost.Close();
                    serviceHost = null;
                }
            }
    
    
        }
    }

    App.config

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <appSettings>
        <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
      </appSettings>
      <system.web>
        <compilation debug="true" />
      </system.web>
      <!-- When deploying the service library project, the content of the config file must be added to the host's 
      app.config file. System.Configuration does not support config files for libraries. -->
      <system.serviceModel>
        <bindings />
        <client />
        <services>
          <service name="SIS.Apps.Service.AppsService">
            <endpoint address="" binding="basicHttpBinding" contract="SIS.Apps.Service.IAppsService">
              <identity>
                <dns value="localhost" />
              </identity>
            </endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
            <host>
              <baseAddresses>
                <add baseAddress="http://*:5000/SIS.Apps.Service/" />
                <!--<add baseAddress="http://*:8733/Design_Time_Addresses/SIS.Apps.Service/Service1/" />-->
              </baseAddresses>
            </host>
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <!-- To avoid disclosing metadata information, 
              set the values below to false before deployment -->
              <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
              <!-- To receive exception details in faults for debugging purposes, 
              set the value below to true.  Set to false before deployment 
              to avoid disclosing exception information -->
              <serviceDebug includeExceptionDetailInFaults="False" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    
    </configuration>


    Our proxy project that should allow the apps to connect to the service.

    Our Android project

    Code in the android project

    MainActivity.cs

    using System;
    
    using Android.App;
    using Android.Content.PM;
    using Android.Runtime;
    using Android.Views;
    using Android.Widget;
    using Android.OS;
    using System.ServiceModel;
    using SIS.Apps.Service.Proxy.SISAppsServiceProxy;
    namespace SIS.Apps.Droid
    {
        [Activity(Label = "SIS.Apps", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
        public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
        {
            protected override void OnCreate(Bundle bundle)
            {
                TabLayoutResource = Resource.Layout.Tabbar;
                ToolbarResource = Resource.Layout.Toolbar;
    
                base.OnCreate(bundle);
    
                global::Xamarin.Forms.Forms.Init(this, bundle);
                LoadApplication(new App());
    
                BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
    
                // THis would be gotten file a file that is saved once the customer has the address to the service, Hard coded for testing
                EndpointAddress endpointAddress = new EndpointAddress("http://sisdev-ws1:5000/SIS.Apps.Service/");
    
                ChannelFactory<IAppsService> myChannelFactory = new ChannelFactory<IAppsService>(basicHttpBinding, endpointAddress);
                IAppsService client = null;
                try
                {
                    client = myChannelFactory.CreateChannel();
                    client.GetData(1);
                    ((ICommunicationObject)client).Close();
                }
                catch (Exception Ex)
                {
                    if (client != null)
                    {
                        ((ICommunicationObject)client).Abort();
                    }
                }
            }
        }
    }
    


    When I run The Android project the service will start since I set up a proxy project and then when it gets to the line in the MainActivity.cs below, I get a NoEndpointException

    client.GetData(1);

    Yet when I go to the web browser and put in the address the client in using, everything looks fine.


    • Edited by brown71576 Wednesday, June 6, 2018 4:44 PM
    Wednesday, June 6, 2018 3:14 PM
  • Hi brown,

    >>When I run The Android project the service will start since I set up a proxy project and then when it gets to the line in the MainActivity.cs below, I get a NoEndpointException

    It seems the Android fail to find the endpoint address, I suggest you try to use ip address instead of "sisdev-ws1:5000".

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, June 7, 2018 5:34 AM
  • Yes I actually figured that out yesterday. I would like to pick your brain a little more if you do not mind. 


    I will need to have the server send notification to devices as well as devices request data from the service. How can I setup my WCF Service to do this?

    Thursday, June 7, 2018 4:22 PM
  • Hi brown,

    Does the ip address resolve your issue? If it did, I would suggest you mark the helpful reply as answer to close this thread.

    If not, it would be helpful if you could share us your solution and then mark it as answer.

    >>I will need to have the server send notification to devices as well as devices request data from the service. How can I setup my WCF Service to do this?

    For this new issue, I would suggest you post a new thread, share us more information, then we could focus on this new issue.

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, June 8, 2018 5:41 AM