如何在WCF中使用net.Pipe绑定

时间:2011-12-29 11:29:33

标签: c# asp.net wcf web-services

我有一个使用Wcf服务的项目。在我的web.config中绑定是:

<netNamedPipeBinding>
   <binding name="RCISPNetNamedPipeBinding" />
</netNamedPipeBinding>

<service behaviorConfiguration="Fara.WcfServiceBehaviour" name="Fara.WcfService.CommonWcfService">
   <endpoint address="CommonServices" binding="netNamedPipeBinding" bindingConfiguration="FaraNetNamedPipeBinding" contract="Fara.Common.ServiceContract.ICommonService" />
</service>

当我想创建服务主机

时,我遇到了运行时错误
public class ServiceFactory : ServiceHostFactory
{
   protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
   {
      if (!IsInitialised) InitialiseService();
         return base.CreateServiceHost(serviceType, baseAddresses);
   }

}

异常消息是:

Could not find a base address that matches scheme net.pipe for the endpoint with binding NetNamedPipeBinding. Registered base address schemes are [http].

我的项目属性是: enter image description here

我该如何更正此错误?

我更新了Web.config:                                                                      但我的问题没有解决!

enter image description here enter image description here enter image description here

2 个答案:

答案 0 :(得分:3)

由于错误消息非常清楚:您没有为net.pipe绑定定义任何基址。所以定义一个!

<service name="Fara.WcfService.CommonWcfService"
          behaviorConfiguration="Fara.WcfServiceBehaviour"  >
   <host>
      <baseAddresses>
          <add baseAddress="net.pipe://localhost/Services" />
      </baseAddresses>
   </host>
   <endpoint 
       address="CommonServices" 
       binding="netNamedPipeBinding" bindingConfiguration="FaraNetNamedPipeBinding" 
       contract="Fara.Common.ServiceContract.ICommonService" />
</service>

然后您的服务端点将是net.pipe://localhost/Services/CommonServices

答案 1 :(得分:1)

为未来的读者。

您需要确保网站SITE添加了绑定“net.pipe”。

Edit Bindings

以上可以详细说明:

Binding net.pipe to Default Web Site via IIS

您需要启用网络应用程序的协议

Enabled Protocols

协议也可以通过命令行设置。沿着下面的线条。找一些其他的例子,我把它作为评论,而不是实际的代码。但它会“让你到那里”。 请注意,“net.tcp”不是必需的。

appcmd.exe set config  -section:system.applicationHost/sites "/[name='Default Web Site'].[path='/SunService'].enabledProtocols":"http,net.pipe,net.tcp"  /commit:apphost

我还没想出第一个(通过命令行)。如果我搞清楚的话,我会在这里更新。它是“一次性”“在蓝色月亮”设置,所以我手动做了很多次。

请注意,我没有设置baseAddress。以下是我的工作.config

<services>

  <service name="My.Concrete.MyService"
           behaviorConfiguration="MyBehaviorOne"
           >

    <host>
      <baseAddresses>
      </baseAddresses>
    </host>


    <!-- IIS Address net.pipe://localhost/MyIISApplication/MyServiceFile.svc/SomeServiceNetNamedPipeAddressAbc -->
    <endpoint
              address  = "SomeServiceNetNamedPipeAddressAbc"
              binding  = "netNamedPipeBinding" bindingConfiguration="NamedPipeBindingName1"
              contract = "My.Interface.IMyService"  >
    </endpoint>


    <endpoint address="mex"
                          binding="mexHttpBinding"
                          contract="IMetadataExchange" />


  </service>


</services>


<bindings>

  <netNamedPipeBinding>
    <binding name="NamedPipeBindingName1"
                 hostNameComparisonMode="StrongWildcard"
                 maxBufferSize="9000000"
                 maxConnections="500"
                 maxReceivedMessageSize="9000000"
                 receiveTimeout="00:20:00"
                 transactionFlow="false">
      <security mode="Transport">
      </security>
    </binding>
  </netNamedPipeBinding>


</bindings>


<behaviors>


    <behavior name="MyBehaviorOne">
      <!-- httpGetUrl is 'relative' in IIS -->
      <serviceMetadata httpGetEnabled="true" httpGetUrl="Metadata"
        httpsGetEnabled="false" /> <!-- httpGetUrl is 'relative' in IIS -->
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>



</behaviors>

APPEND:

appcmd set site /site.name:" IIS网站名称“/+bindings.[protocol='net.pipe',bindingInformation ='*']

来自

https://www.digicert.com/ssl-support/ssl-host-headers-iis-7.htm

这应该让你在正确的方向上进行命令行添加绑定。

以下是一些Wix自定义动作代码(主要是我在互联网上发现的调整版本)

using System;
using System.Globalization;
using System.Linq;
using System.Security.Principal;

using Microsoft.Deployment.WindowsInstaller;
using Microsoft.Web.Administration;

namespace MyCustomActionLibrary
{
    public static class CustomActions
    {
        /// <summary>
        /// Updates the binding for a Site.  IIS.  Right click a Site.  Select "Edit Bindings" to see GUI of this.
        /// </summary>
        /// <param name="session">The session.</param>
        /// <returns>An ActionResult</returns>
        [CustomAction]
        public static ActionResult UpdateBinding(Session session)
        {
            session.Log("Begin UpdateBinding");

            string siteName = session["SITE"];
            if (string.IsNullOrEmpty(siteName))
            {
                session.Log("Property 'SITE' missing");
                return ActionResult.NotExecuted;
            }

            string bindingInformation = session["BINDINGINFORMATION"];
            if (string.IsNullOrEmpty(bindingInformation))
            {
                session.Log("Property 'BINDINGINFORMATION' missing");
                return ActionResult.NotExecuted;
            }

            string bindingProtocol = session["BINDINGPROTOCOL"];
            if (string.IsNullOrEmpty(bindingProtocol))
            {
                session.Log("Property 'BINDINGPROTOCOL' missing");
                return ActionResult.NotExecuted;
            }

            ActionResult result = ActionResult.Failure;

            if (CheckRunAsAdministrator())
            {
                session.Log("Start UpsertBinding.");
                bool outcome = UpsertBinding(session, siteName, bindingInformation, bindingProtocol);
                if (outcome)
                {
                    result = ActionResult.Success;
                }

                session.Log("End UpsertBinding.");
                return result;
            }
            else
            {
                session.Log("Not running with elevated permissions.STOP");
                session.DoAction("NotElevated");
                return ActionResult.Failure;
            }
        }

        /// <summary>
        /// Enables the protocols.  Go to IIS.  Pick a Site.  Right Click an Application.  Select "Manage Application" / "Advanced Settings".  Find "Enabled Protocols" to see the GUI of this setting.
        /// </summary>
        /// <param name="session">The session.</param>
        /// <returns>An ActionResult</returns>
        [CustomAction]
        public static ActionResult EnableProtocols(Session session)
        {
            session.Log("Begin EnableProtocols");

            string siteName = session["SITE"];
            if (string.IsNullOrEmpty(siteName))
            {
                session.Log("Property 'SITE' missing");
                return ActionResult.NotExecuted;
            }

            string alias = session["VIRTUALDIRECTORYALIAS"];
            if (string.IsNullOrEmpty(alias))
            {
                session.Log("Property 'VIRTUALDIRECTORYALIAS' missing");
                return ActionResult.NotExecuted;
            }

            string protocols = session["ENABLEDPROTOCOLS"];
            if (string.IsNullOrEmpty(protocols))
            {
                session.Log("Property 'ENABLEDPROTOCOLS' missing");
                return ActionResult.NotExecuted;
            }

            try
            {
                if (CheckRunAsAdministrator())
                {
                    ServerManager manager = new ServerManager();

                    var site = manager.Sites.FirstOrDefault(x => x.Name.ToUpper(CultureInfo.CurrentCulture) == siteName.ToUpper(CultureInfo.CurrentCulture));
                    if (site == null)
                    {
                        session.Log("Site with name {0} not found", siteName);
                        return ActionResult.NotExecuted;
                    }

                    var application = site.Applications.FirstOrDefault(x => x.Path.ToUpper(CultureInfo.CurrentCulture).Contains(alias.ToUpper(CultureInfo.CurrentCulture)));
                    if (application == null)
                    {
                        session.Log("Application with path containing {0} not found", alias);
                        return ActionResult.NotExecuted;
                    }

                    session.Log("About to set EnabledProtocols.  SITE='{0}', VIRTUALDIRECTORYALIAS='{1}',  ENABLEDPROTOCOLS='{2}'.", siteName, alias, protocols);
                    application.EnabledProtocols = protocols;
                    manager.CommitChanges();
                    session.Log("ServerManager.CommitChanges successful for setting EnabledProtocols. SITE='{0}', VIRTUALDIRECTORYALIAS='{1}',  ENABLEDPROTOCOLS='{2}'.", siteName, alias, protocols);

                    return ActionResult.Success;
                }
                else
                {
                    session.Log("Not running with elevated permissions.STOP");
                    session.DoAction("NotElevated");
                    return ActionResult.Failure;
                }
            }
            catch (Exception exception)
            {
                session.Log("Error setting enabled protocols: {0}", exception.ToString());
                return ActionResult.Failure;
            }
        }

        private static bool UpsertBinding(Session session, string sitename, string bindingInformation, string bindingProtocol)
        {
            bool result;

            session.Log(string.Format("(SiteName)='{0}'", sitename));
            session.Log(string.Format("(BindingInformation)='{0}'", bindingInformation));
            session.Log(string.Format("(BindingProtocol)='{0}'", bindingProtocol));

            using (ServerManager serverManager = new ServerManager())
            {
                Site site = serverManager.Sites.FirstOrDefault(x => x.Name.Equals(sitename, StringComparison.OrdinalIgnoreCase));

                if (null != site)
                {
                    Binding foundBinding = site.Bindings.FirstOrDefault(b => b.Protocol.Equals(bindingProtocol, StringComparison.OrdinalIgnoreCase) && b.BindingInformation.Equals(bindingInformation, StringComparison.OrdinalIgnoreCase));

                    if (null == foundBinding)
                    {
                        //// add bindings
                        session.Log("About add to Site.Bindings.  SITE='{0}', BINDINGINFORMATION='{1}',  BINDINGPROTOCOL='{2}'.", sitename, bindingInformation, bindingProtocol);
                        site.Bindings.Add(bindingInformation, bindingProtocol);
                        serverManager.CommitChanges();
                        session.Log("ServerManager.CommitChanges successsful for adding to Site.Bindings.  SITE='{0}', BINDINGINFORMATION='{1}',  BINDINGPROTOCOL='{2}'.", sitename, bindingInformation, bindingProtocol);
                        result = true;
                    }
                    else
                    {
                        session.Log(string.Format("Binding already exists.  (SiteName='{0}', bindingInformation='{1}', bindingProtocol='{2}')", sitename, bindingInformation, bindingProtocol));
                        result = true; /* do not fail if the binding already exists, the point is to have the binding */
                    }
                }
                else
                {
                    session.Log(string.Format("Site does not exist.  (SiteName) {0}.", sitename));
                    result = false;
                }
            }

            return result;
        }

        /// <summary>
        /// Check that process is being run as an administrator
        /// </summary>
        /// <returns>if the process is being run as administrator</returns>
        private static bool CheckRunAsAdministrator()
        {
            var identity = WindowsIdentity.GetCurrent();
            var principal = new WindowsPrincipal(identity);
            return principal.IsInRole(WindowsBuiltInRole.Administrator);
        }
    }
}

packages.config

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Microsoft.Web.Administration" version="7.0.0.0" targetFramework="net45" />
</packages>

和wix“属性”。

MyProperties.wxi

<?xml version="1.0" encoding="utf-8"?>
<Include>
  <Property Id="SITE" Value="Default Web Site" />
  <Property Id="BINDINGINFORMATION" Value="*" />
  <Property Id="BINDINGPROTOCOL" Value="net.pipe" />

  <Property Id="VIRTUALDIRECTORYALIAS" Value="MyWebApplicationName" />
  <Property Id="ENABLEDPROTOCOLS" Value="http,net.pipe" />
</Include>

然后我在标签内嵌套了下面的内容。

<?include MyProperties.wxi ?>