我在app.config中有这个配置:
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="myBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
我想以编程方式从我的桌面应用程序公开此服务:
我定义了主机实例:
ServiceHost host = new ServiceHost(typeof(MyType), new Uri("http://" + hostName + ":" + port + "/MyName"));
然后我用它的绑定添加端点:
var binding = new BasicHttpBinding("myBinding");
host.AddServiceEndpoint(typeof(IMyInterface), binding, "MyName");
现在,我想用一些从配置文件中读取名为 myBehavior 的行为的代码替换下面的代码,而不是硬编码行为选项。 < / p>
ServiceMetadataBehavior smb = new ServiceMetadataBehavior() { HttpGetEnabled = true };
host.Description.Behaviors.Add(smb);
// Enable exeption details
ServiceDebugBehavior sdb = host.Description.Behaviors.Find<ServiceDebugBehavior>();
sdb.IncludeExceptionDetailInFaults = true;
然后,我可以打开主持人。
host.Open();
*编辑*
使用配置文件配置服务
你不应该这样,你应该让主机从配置文件中自动获取配置,而不是手动给它们,阅读this article (Configuring Services Using Configuration Files),它会帮助你,我已经托管了我的服务C#中的单行和config中的少行。
This is a second article about (Configuring WCF Services in Code), 我的错是我试图混合两种方式!
我会将此作为答案添加。
答案 0 :(得分:7)
首先,您需要使用
打开配置文件var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
或
var map = new ExeConfigurationFileMap();
map.ExeConfigFilename = "app.config";
var config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
然后你读了行为:
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
,所以还不是您想要的。
如果您不介意使用私有API,可以通过反射调用受保护的方法BehaviorExtensionElement.CreateBehavior()
:
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);
}
答案 1 :(得分:6)
使用配置文件配置服务
你不应该这样,你应该让主机从配置文件中自动获取配置,而不是手动给它们,阅读this article (Configuring Services Using Configuration Files),它会帮助你,我已经托管了我的服务C#中的单行和config中的少行。
This is a second article about (Configuring WCF Services in Code), 我的错是我试图混合两种方式!
答案 2 :(得分:1)
虽然这是一个老问题,但我在其他地方找到我需要的东西时遇到了问题,所以今后我的解决方案就是我的解决方案。
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()
不适用于网络项目,因此手动获取部分并将其投射更简单。
如果您真的坚持让System.ServiceModel
为您做配置阅读,可以这样做:
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
在进行单元测试时非常糟糕。