Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 公开自托管服务时从配置文件programmticlally读取WCF行为元素_C#_.net_Wcf_Configuration_Self Hosting - Fatal编程技术网

C# 公开自托管服务时从配置文件programmticlally读取WCF行为元素

C# 公开自托管服务时从配置文件programmticlally读取WCF行为元素,c#,.net,wcf,configuration,self-hosting,C#,.net,Wcf,Configuration,Self Hosting,我的app.config中有此配置: </binding> </basicHttpBinding> </bindings> <behaviors> <serviceBehaviors> <behavior name="myBehavior"> <serviceMetadata httpGetEnabled="true"/> <serviceDebug i

我的app.config中有此配置:

    </binding>
  </basicHttpBinding>
</bindings>



<behaviors>
  <serviceBehaviors>
    <behavior name="myBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

    </binding>
  </basicHttpBinding>
</bindings>



<behaviors>
  <serviceBehaviors>
    <behavior name="myBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
然后添加端点及其绑定:

    </binding>
  </basicHttpBinding>
</bindings>



<behaviors>
  <serviceBehaviors>
    <behavior name="myBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
var binding = new BasicHttpBinding("myBinding");
host.AddServiceEndpoint(typeof(IMyInterface), binding, "MyName");
现在,我想用从配置文件中读取名为myBehavior的行为的代码替换下面的代码,而不是硬编码行为选项。

    </binding>
  </basicHttpBinding>
</bindings>



<behaviors>
  <serviceBehaviors>
    <behavior name="myBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
ServiceMetadataBehavior smb = new ServiceMetadataBehavior() { HttpGetEnabled = true };    
host.Description.Behaviors.Add(smb);   
// Enable exeption details
ServiceDebugBehavior sdb = host.Description.Behaviors.Find<ServiceDebugBehavior>();
sdb.IncludeExceptionDetailInFaults = true;
*编辑*

    </binding>
  </basicHttpBinding>
</bindings>



<behaviors>
  <serviceBehaviors>
    <behavior name="myBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

使用配置文件配置服务

    </binding>
  </basicHttpBinding>
</bindings>



<behaviors>
  <serviceBehaviors>
    <behavior name="myBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
您不应该需要这种方式,您应该让主机从配置文件自动获取其配置,而不是手动提供,读取,这将帮助您,我在C#中的一行中托管了我的服务,在配置中很少托管

    </binding>
  </basicHttpBinding>
</bindings>



<behaviors>
  <serviceBehaviors>
    <behavior name="myBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
,, 我的错是我试图把这两种方法混为一谈

    </binding>
  </basicHttpBinding>
</bindings>



<behaviors>
  <serviceBehaviors>
    <behavior name="myBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

我将添加此作为答案。

首先,您需要使用

    </binding>
  </basicHttpBinding>
</bindings>



<behaviors>
  <serviceBehaviors>
    <behavior name="myBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

    </binding>
  </basicHttpBinding>
</bindings>



<behaviors>
  <serviceBehaviors>
    <behavior name="myBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
然后您阅读以下行为:

    </binding>
  </basicHttpBinding>
</bindings>



<behaviors>
  <serviceBehaviors>
    <behavior name="myBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
var bindings = BindingsSection.GetSection(config);
var group = ServiceModelSectionGroup.GetSectionGroup(config);
foreach (var behavior in group.Behaviors.ServiceBehaviors)
{
    Console.WriteLine ("BEHAVIOR: {0}", behavior);
}
请注意,它们属于
System.ServiceModel.Configuration.ServiceBehaviorElement类型,因此还不是您想要的类型

    </binding>
  </basicHttpBinding>
</bindings>



<behaviors>
  <serviceBehaviors>
    <behavior name="myBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
如果您不介意使用私有API,可以通过反射调用受保护的方法
BehaviorExtensionElement.CreateBehavior()

    </binding>
  </basicHttpBinding>
</bindings>



<behaviors>
  <serviceBehaviors>
    <behavior name="myBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
foreach (BehaviorExtensionElement bxe in behavior)
{
    var createBeh = typeof(BehaviorExtensionElement).GetMethod(
        "CreateBehavior", BindingFlags.Instance | BindingFlags.NonPublic);
    IServiceBehavior b = (IServiceBehavior)createBeh.Invoke(bxe, new object[0]);
    Console.WriteLine("BEHAVIOR: {0}", b);
    host.Description.Behaviors.Add (b);
}

使用配置文件配置服务

    </binding>
  </basicHttpBinding>
</bindings>



<behaviors>
  <serviceBehaviors>
    <behavior name="myBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
您不应该需要这种方式,您应该让主机从配置文件自动获取其配置,而不是手动提供,读取,这将帮助您,我在C#中的一行中托管了我的服务,在配置中很少托管

    </binding>
  </basicHttpBinding>
</bindings>



<behaviors>
  <serviceBehaviors>
    <behavior name="myBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
,,
我的错是我试图把这两种方法混为一谈

虽然这是一个老问题,但我在其他地方找不到我需要的东西,所以这里是我的解决方案,供将来参考

    </binding>
  </basicHttpBinding>
</bindings>



<behaviors>
  <serviceBehaviors>
    <behavior name="myBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
var behaviorSection = ConfigurationManager.GetSection("system.serviceModel/behaviors") as BehaviorsSection;
if (behaviorSection != null)
{
                // for each behavior, check for client and server certificates
    foreach (EndpointBehaviorElement behavior in behaviorSection.EndpointBehaviors)
    {
        foreach (PropertyInformation pi in behavior.ElementInformation.Properties)
        {
            if (pi.Type == typeof(ClientCredentialsElement))
            {
                var clientCredentials = pi.Value as ClientCredentialsElement;
                var clientCert = clientCredentials.ClientCertificate;
                            // TODO: Add code...
            }
        }
    }
}
ConfigurationManager.Open…Configuration()
不能很好地处理web项目,因此手动获取节并强制转换它更简单

    </binding>
  </basicHttpBinding>
</bindings>



<behaviors>
  <serviceBehaviors>
    <behavior name="myBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
如果您确实坚持让
System.ServiceModel
为您进行配置读取,则可以执行以下操作:

    </binding>
  </basicHttpBinding>
</bindings>



<behaviors>
  <serviceBehaviors>
    <behavior name="myBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
ExeConfigurationFileMap map = new ExeConfigurationFileMap();
map.ExeConfigFilename = System.IO.Path.Combine(HttpContext.Current.Server.MapPath("~"), "web.config"); // the root web.config  
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
var group = ServiceModelSectionGroup.GetSectionGroup(config);

foreach (EndpointBehaviorElement item in group.Behaviors.EndpointBehaviors)
{
    // TODO: add code...
}

第二种方法使用
HttpContext.Current
,我们都知道
HttpContext.Current
在进行单元测试时非常糟糕。

有合理的理由不使用配置文件,即从外部源检索地址等。除非您不想使用默认配置文件
    </binding>
  </basicHttpBinding>
</bindings>



<behaviors>
  <serviceBehaviors>
    <behavior name="myBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>