Is it possible to create a self-hosted WCF service which is "browsable"?
Is it possible to create a self-hosted WCF service which is "browsable", i.e. can be viewed and accessed in a web browser?
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.
Here's my code so far:
WCF contract and implementation:
/// <summary>
/// Windows Communications Foundation Diagnostics Service contract
/// </summary>
//[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<ConnectedModemDiagnosticsClass> EnumerateConnectedModems();
}
/// <summary>
/// Windows Communications Foundation Diagnostics Service class
/// </summary>
public class WCFDiagnosticsService : IDiagnosticsService
{
public List<ConnectedModemDiagnosticsClass> EnumerateConnectedModems()
{
return TcpServerSingleton.Instance.EnumerateConnectedModems();
}
}
"Factory" function:
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);
//开发者_C百科 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;
}
}
Instantiation:
_selfHostDiagnostics = HttpSelfHostFactory(Settings.Default.WCFHttpDiagnosticsPort, "Diagnostics", typeof(WCFDiagnosticsService), FTArmada.Logging);
If you create a WCF REST service based on the webHttpBinding
-- that would be inherently "browseable".
Check out the MSDN Developer Center for WCF REST for more details.
You could basically host your WCF service as a REST service by instantiating a WebServiceHost
instead of a more generic ServiceHost
.
Once done, you can "navigate" your service by issuing HTTP requests from a browser. So going to
http://yourURL/diagnostics/modems
might display a list of all installed modems, and you could "navigate" to a single modem by means of an URL something like:
http://yourURL/diagnostics/modems/4711
if your modems have some unique ID - and this URL would then maybe show a status page or something.
Why not just host a website and serve up asp.net pages in the windows service by using an embedded web server such as this one
精彩评论