是否有可能和一个明智的解决方案来创建一个“可浏览”的自托管WCF服务?

时间:2011-09-05 13:28:02

标签: c# wcf

是否可以创建一个“可浏览”的自托管WCF服务,即可以在Web浏览器中查看和访问,这对我的场景来说是个好主意(后面会有描述)?

我们有一个Windows服务,我需要偶尔调用它来检索一些诊断数据。我的想法是自我托管服务然后RDC到服务器,启动IE,并在浏览器中访问服务(因此我只启用了localhost绑定)。一个可接受的替代方案,我也不知道该怎么做,可能是打开服务到互联网访问,但将其限制为具有管理员权限的Windows帐户,然后我可以编写一个简单的程序来调用服务并获取数据。这样做的缺点是我们的防火墙是配置的噩梦所以我宁愿不用打开另一个端口。

到目前为止,这是我的代码:

WCF合同和实施:

/// <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();
    }
}

“工厂”功能:

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;
    }
}

实例化:

_selfHostDiagnostics = HttpSelfHostFactory(Settings.Default.WCFHttpDiagnosticsPort, "Diagnostics", typeof(WCFDiagnosticsService), FTArmada.Logging);

更新:现在就开始工作了,谢谢,并接受了答案。我已经转换为REST并注释了我的服务合同界面,现在可以在http://localhost:85/Diagnostics/EnumerateConnectedModems上获得结果。

这些链接帮助我实施了它:1 2

新界面:

[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<ConnectedModemDiagnosticsClass> EnumerateConnectedModems();
}

在工厂方法中创建REST端点(?):

if (rest)
            {
                selfHost = new WebServiceHost(serviceType, baseAddress);
                selfHost.AddServiceEndpoint(implementedContract, new WebHttpBinding(), "");
                ServiceDebugBehavior stp = selfHost.Description.Behaviors.Find<ServiceDebugBehavior>();
                stp.HttpHelpPageEnabled = httpHelpPageEnabled;
            }
            else
            {
                selfHost = new ServiceHost(serviceType, baseAddress);
            }

2 个答案:

答案 0 :(得分:2)

如果您基于webHttpBinding创建WCF REST服务 - 这本身就是“可浏览的”。

查看MSDN Developer Center for WCF REST了解详情。

通过实例化WebServiceHost而不是更通用的ServiceHost,您基本上可以将WCF服务作为REST服务托管。

完成后,您可以通过从浏览器发出HTTP请求来“导航”您的服务。所以去

http://yourURL/diagnostics/modems

可能会显示所有已安装调制解调器的列表,您可以通过以下URL来“导航”到单个调制解调器:

http://yourURL/diagnostics/modems/4711

如果你的调制解调器有一些唯一的ID - 那么这个URL可能会显示一个状态页面。

答案 1 :(得分:0)

为什么不通过使用this一个

等嵌入式Web服务器来托管网站并在Windows服务中提供asp.net页面