Note that there are some explanatory texts on larger screens.

plurals
  1. POIs it possible and a sensible solution to create a self-hosted WCF service which is "browsable"?
    text
    copied!<p>Is it possible to create a self-hosted WCF service which is "browsable", i.e. can be viewed and accessed in a web browser, and is that a good idea for my scenario (description follows)?</p> <p>We have a Windows service which I need to call into occasionally to retrieve some diagnostics data. My idea was to self-host a service and then RDC into the server, fire up IE, and access the service in the browser (therefore I've enabled localhost binding only). An acceptable alternative, which I'm also not sure how to do, might be to open the service up to internet access but restrict it to Windows accounts with Administrator privileges, then I can write a simple program to call the service and get the data. The downside to this is that our firewall is a nightmare to configure so I'd rather not have to open up another port.</p> <p>Here's my code so far:</p> <p>WCF contract and implementation:</p> <pre><code>/// &lt;summary&gt; /// Windows Communications Foundation Diagnostics Service contract /// &lt;/summary&gt; //[Service Contract] // commented out and space added as current code doesn't work with these attributes in place; they're needed if using WebServiceHost (which didn't help) public interface IDiagnosticsService { //[Operation Contract] List&lt;ConnectedModemDiagnosticsClass&gt; EnumerateConnectedModems(); } /// &lt;summary&gt; /// Windows Communications Foundation Diagnostics Service class /// &lt;/summary&gt; public class WCFDiagnosticsService : IDiagnosticsService { public List&lt;ConnectedModemDiagnosticsClass&gt; EnumerateConnectedModems() { return TcpServerSingleton.Instance.EnumerateConnectedModems(); } } </code></pre> <p>"Factory" function:</p> <pre><code>public static ServiceHost HttpSelfHostFactory(int port, string serviceNameForUri, Type serviceType, Logging logObject, string hostName = "localhost", bool publishMetadata = true, bool startListening = true) { // Argument checking: if (string.IsNullOrWhiteSpace(serviceNameForUri)) throw new ArgumentException("serviceNameForUri"); serviceNameForUri = serviceNameForUri.Trim(); if (hostName != null) hostName = hostName.Trim().ToLower(); switch (hostName) { case "localhost": case "127.0.0.1": break; case null: case "": throw new ArgumentException("hostName"); default: throw new NotImplementedException("Non localhost bindings not yet implemented. Need to ensure security."); } ServiceHost selfHost = null; try { // Create Uri: Uri baseAddress = new Uri(string.Format("http://{0}:{1}/{2}", hostName, port, serviceNameForUri)); logObject.WriteLogFile("", "Starting WCF server on " + baseAddress); // Create the ServiceHost: selfHost = new ServiceHost(serviceType, baseAddress); // Enable metadata publishing: if (publishMetadata) { ServiceMetadataBehavior smb = new ServiceMetadataBehavior {HttpGetEnabled = true, MetadataExporter = {PolicyVersion = PolicyVersion.Policy15}}; selfHost.Description.Behaviors.Add(smb); } // Start listening: if (startListening) selfHost.Open(); } catch (Exception ex) { logObject.WriteLogFile("WCF startup exception " + ex.Message); if (selfHost != null) { try { selfHost.Close(); } catch { } selfHost = null; } } return selfHost; } } </code></pre> <p>Instantiation:</p> <pre><code>_selfHostDiagnostics = HttpSelfHostFactory(Settings.Default.WCFHttpDiagnosticsPort, "Diagnostics", typeof(WCFDiagnosticsService), FTArmada.Logging); </code></pre> <p><strong>UPDATE</strong>: Have this working now, thanks, and answer accepted. I've converted to REST and annotated my service contract interface and can now get the results on <a href="http://localhost:85/Diagnostics/EnumerateConnectedModems" rel="nofollow noreferrer">http://localhost:85/Diagnostics/EnumerateConnectedModems</a>.</p> <p>These links helped me implement it: <a href="http://debugmode.net/2010/06/01/restselfhosted/" rel="nofollow noreferrer">1</a> <a href="https://stackoverflow.com/questions/41155/wcf-service-returning-method-not-allowed">2</a></p> <p>New interface:</p> <pre><code>[ServiceContract] // commented out and space added as current code doesn't work with these attributes in place; they're needed if using WebServiceHost (which didn't help) public interface IDiagnosticsService { [OperationContract] [WebGet] List&lt;ConnectedModemDiagnosticsClass&gt; EnumerateConnectedModems(); } </code></pre> <p>Creating the REST endpoint (?) in the factory method:</p> <pre><code>if (rest) { selfHost = new WebServiceHost(serviceType, baseAddress); selfHost.AddServiceEndpoint(implementedContract, new WebHttpBinding(), ""); ServiceDebugBehavior stp = selfHost.Description.Behaviors.Find&lt;ServiceDebugBehavior&gt;(); stp.HttpHelpPageEnabled = httpHelpPageEnabled; } else { selfHost = new ServiceHost(serviceType, baseAddress); } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload