A registration already exists for URI in windows service hosted WCF - c#

I have a WCF service library hosted by a windows service. I am using Castle Windson to do constructor injection. When I try to start up the service I get an exception with the following inner exception:
{"A registration already exists for URI 'net.tcp://localhost:8056/LoggingServiceWCF/tcp'."}
App.config:
<system.serviceModel>
<services>
<service name="LoggingServiceWCF.LoggingService">
<endpoint address="tcp" binding="netTcpBinding" bindingConfiguration="" name="netTcp" contract="LoggingServiceWCF.ILoggingService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="tcpMex" binding="mexTcpBinding" bindingConfiguration="" name="mexTcp" contract="IMetadataExchange" />
<endpoint address="pipe" binding="netNamedPipeBinding" bindingConfiguration="" name="namedPipe" contract="LoggingServiceWCF.ILoggingService" />
<endpoint address="pipeMex" binding="mexNamedPipeBinding" contract="IMetadataExchange" bindingConfiguration="" name="mexPipe" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8056/LoggingServiceWCF" />
<add baseAddress="net.pipe://localhost/LoggingServiceWCF"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Castle windsor installer:
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.AddFacility<WcfFacility>();
container.Register(Component
.For<LoggerServiceCore.Interfaces.ILogger>()
.ImplementedBy<LogManager>(),
Component
.For<ILoggingService>()
.ImplementedBy<LoggingService>()
.LifeStyle.Transient
.AsWcfService());
container.Register(Component
.For<ServiceBase>()
.ImplementedBy<LoggingHostService>());
}
Program.cs:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
#if DEBUG
Debugger.Launch();
#endif
ServiceBase.Run(CreateContainer().Resolve<ServiceBase>());
}
private static IWindsorContainer CreateContainer()
{
var container = new WindsorContainer();
container.Install(FromAssembly.This());
return container;
}
}
Windows service class:
public partial class LoggingHostService : ServiceBase
{
internal static ServiceHost service = null;
public LoggingHostService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
if(service != null)
{
service.Close();
}
service = new ServiceHost(typeof(LoggingServiceWCF.LoggingService));
service.Open();
}
protected override void OnStop()
{
if(service != null)
{
service.Close();
service = null;
}
}
}
I have Googled around and found all kinds of solutions to similar issues, but I can't seem to find something that works in my case.

Related

WCF protobuf endpoint 400 bad request

I have WCF service with DataContract json serialization. I would like to add service endpoints to consume Protobuf data messages.
I tried to use nugget package ProtoBuf.Services.WCF.
Added endpoint via web.config configuration. However, every request on protobuf endpoint with address "proto" returns 400 Bad request. Web.config sample is written bellow. Endpoint with default address "" works properly.
Get method:
HTTP 200 OK http://localhost:65460/BeaconService.svc/GetData
HTTP 400 BAD REQUEST: http://localhost:65460/BeaconService.svc/proto/GetData
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding transferMode="Streamed">
<security mode="None" />
</binding>
</webHttpBinding>
<basicHttpBinding>
<binding messageEncoding="Mtom">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<extensions>
<behaviorExtensions>
<add name="protobuf" type="ProtoBuf.ServiceModel.ProtoBehaviorExtension, protobuf-net" />
</behaviorExtensions>
</extensions>
<services>
<service behaviorConfiguration="DefaultServiceBehavior" name="Services.BeaconService">
<endpoint address="" behaviorConfiguration="httpBehavior" binding="webHttpBinding" contract="Services.IBeaconService" />
<endpoint address="proto" behaviorConfiguration="protoBehavior" binding="basicHttpBinding" contract="Services.IBeaconService" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="protoBehavior">
<protobuf />
</behavior>
<behavior name="httpBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</system.serviceModel>
Please, which part of configuration is defective. Eventualy, what is proper way to call Get method on "proto" WCF endpoint to avoid HTTP 400 Bad request message?
Unfortunately, I have failed to implement ProtoBuf.Services.WCF and decided to use another approach. In general, WCF by default uses DataContractSerializer.
After reading this article, I realized It is possible to replace this serializer with another one, f.e. protobuf serializer in this library. So I created behavior extension, which replaces DataContractSerializer with my custom ProtobufSerializer. In configuration added another endpoint, which has set behavior extension to use my custom ProtobufSerializer.
WebHttpBehavior:
public class ProtobufBehavior : WebHttpBehavior
{
protected override IDispatchMessageFormatter GetRequestDispatchFormatter(OperationDescription operationDescription, ServiceEndpoint endpoint)
{
return new ProtobufDispatchFormatter(operationDescription);
}
protected override IDispatchMessageFormatter GetReplyDispatchFormatter(OperationDescription operationDescription, ServiceEndpoint endpoint)
{
return new ProtobufDispatchFormatter(operationDescription);
}
}
Dispatch formatter:
namespace Services.Extension.ProtobufSerializationExtension
{
public class ProtobufDispatchFormatter : IDispatchMessageFormatter
{
OperationDescription operation;
bool isVoidInput;
bool isVoidOutput;
public ProtobufDispatchFormatter(OperationDescription operation)
{
this.operation = operation;
this.isVoidInput = operation.Messages[0].Body.Parts.Count == 0;
this.isVoidOutput = operation.Messages.Count == 1 || operation.Messages[1].Body.ReturnValue.Type == typeof(void);
}
public void DeserializeRequest(Message message, object[] parameters)
{
if (!message.IsEmpty)
{
XmlDictionaryReader bodyReader = message.GetReaderAtBodyContents();
bodyReader.ReadStartElement("Binary");
byte[] rawBody = bodyReader.ReadContentAsBase64();
MemoryStream ms = new MemoryStream(rawBody);
using (StreamReader sr = new StreamReader(ms))
for (int i = 0; i < parameters.Length; i++)
parameters[i] = Serializer.Deserialize(operation.Messages[i].Body.Parts[i].Type, sr.BaseStream);
}
}
public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
{
byte[] body;
using (MemoryStream ms = new MemoryStream())
using (StreamWriter sw = new StreamWriter(ms))
{
Serializer.Serialize(sw.BaseStream, result);
sw.Flush();
body = ms.ToArray();
}
Message replyMessage = Message.CreateMessage(messageVersion, operation.Messages[1].Action, new RawBodyWriter(body));
replyMessage.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Raw));
return replyMessage;
}
class RawBodyWriter : BodyWriter
{
internal static readonly byte[] EmptyByteArray = new byte[0];
byte[] content;
public RawBodyWriter(byte[] content)
: base(true)
{
this.content = content;
}
protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
{
writer.WriteStartElement("Binary");
writer.WriteBase64(content, 0, content.Length);
writer.WriteEndElement();
}
}
}
}
Extension element:
namespace Services.Extension.ProtobufSerializationExtension
{
public class ProtobufSerializationServiceElement : BehaviorExtensionElement
{
public override Type BehaviorType
{
get { return typeof(ProtobufBehavior); }
}
protected override object CreateBehavior()
{
return new ProtobufBehavior();
}
}
}
Web config:
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding transferMode="Streamed">
<security mode="None" />
</binding>
</webHttpBinding>
</bindings>
<extensions>
<behaviorExtensions>
<add name="protobufExtension" type="Services.Extension.ProtobufSerializationExtension.ProtobufSerializationServiceElement, Services" />
</behaviorExtensions>
</extensions>
<services>
<service behaviorConfiguration="DefaultServiceBehavior" name="Services.BeaconService">
<endpoint address="" behaviorConfiguration="httpBehavior" binding="webHttpBinding" contract="Services.IBeaconService" />
<endpoint address="proto" behaviorConfiguration="protoBehavior" binding="webHttpBinding" contract="Services.IBeaconService" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="protoBehavior">
<webHttp/>
<protobufExtension/>
</behavior>
<behavior name="httpBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</system.serviceModel>
Services.Extension.ProtobufSerializationExtension is name of my custom namespace inside application structure. Hope this helps someone.

HttpModule in WCF project just works once

Please consider this code:
<system.web>
<compilation debug="true" targetFramework="4.6"/>
<httpRuntime targetFramework="4.5.2"/>
<authentication mode="None" />
</system.web>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<services>
<service name="MyNameSpace.Services.Service1" behaviorConfiguration="ServiceBehavior">
<endpoint binding="basicHttpBinding" contract="MyNameSpace.Services.ISrv"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpBinding" scheme="http"/>
</protocolMapping>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="AuthSecurity" type="MyNameSpace.CustomAuthorization" />
</modules>
<directoryBrowse enabled="true"/>
</system.webServer>
and the HttpModule code is:
namespace MyNameSpace
{
public class CustomAuthorization : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
CheckAccess();
}
private bool CheckAccess()
{
HttpContext c = HttpContext.Current;
if (HttpContext.Current.Handler != null) // <--Break Point
{
string authHeader = HttpContext.Current.Request.Headers["Authorization"];
...
}
return false;
}
}
}
and in the client I wrote this code:
Service1client client = new Service1client();
client.ClientCredentials.UserName.UserName = "mmmm"
client.ClientCredentials.UserName.Password = "nnnn";
var tmp = client.DoWork(1);
the problem is after running the project, Service returns the correct result but HttpModule code didn't execute.
When I use a breakpoint in HttpModule it hits during Application_Start event. But after that it doesn't hit any more and its code doesn't execute.
Where is the problem?
Thanks
As I understand it, you defined just what to do at application start; if you want to check incoming requests, try to add these methods to your HttpModule and set breakpoints to check whether those methods are hit:
private void Application_BeginRequest(Object source,
EventArgs e)
{
CheckAccess();
}
private void Application_EndRequest(Object source, EventArgs e)
{
CheckAccess();
}
Of course you need to register those methods at application start:
application.BeginRequest +=
(new EventHandler(this.Application_BeginRequest));
application.EndRequest +=
(new EventHandler(this.Application_EndRequest));

WCF Error: The operation cannot be completed because the pipe was closed

I am getting an error when the client reference is used a second time for calling the underlying method. On first call, It works perfectly. I have googled it and did so many tries like setting timeouts but nothing worked. Any suggestions will be highly appreciated. Also, if more details are required please let me know, I will post the required code.
A MDI Child form will call this method.
Debugger shows CommunicationException.
Trace Viewer shows message: The operation cannot be completed because the pipe was closed. This may have been caused by the application on the other end of the pipe exiting.
Contract
[ServiceContract(Namespace = "http://Company/ManagementInformationSystemServices/", SessionMode = SessionMode.Required)]
public interface IPrincipalService
{
#region Service contracts for Reports
[OperationContract]
[FaultContract(typeof(ProcessExecutionFault))]
Parcel InsertParcel(Parcel singleParcel, out bool Exists);
[OperationContract]
[FaultContract(typeof(ProcessExecutionFault))]
Parcel GetByParcelId(int id);
#endregion
}
Contract Implementation
[ServiceBehavior(UseSynchronizationContext = false, ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
public class PrincipalService : IPrincipalService
{
#region Constructor
public PrincipalService()
{
}
#endregion
#region Public Methods
#region Parcel Methods
public Parcel InsertParcel(Parcel singleParcel, out bool Exists)
{
bool ExistsInner = false;
try
{
ParcelComponent parcelComponent = new ParcelComponent();
singleParcel = parcelComponent.Insert(singleParcel, out ExistsInner);
Exists = ExistsInner;
return singleParcel;
}
catch (Exception ex)
{
throw new FaultException<ProcessExecutionFault>
(new ProcessExecutionFault(LogResource.InsertParcelExistsError, ex), ex.Message);
}
}
public Parcel GetByParcelId(int id)
{
try
{
ParcelComponent parcelComponent = new ParcelComponent();
return parcelComponent.GetById(id);
}
catch (Exception ex)
{
throw new FaultException<ProcessExecutionFault>
(new ProcessExecutionFault(LogResource.ReadParcelError, ex), ex.Message);
}
}
#endregion
#endregion
}
Server Configuration
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<services>
<service behaviorConfiguration="serviceBehavior" name="ManagementInformationSystem.Services.PrincipalService">
<host>
<baseAddresses>
<add baseAddress="net.pipe://localhost/ManagementInformationSystemServices" />
</baseAddresses>
</host>
<endpoint address="PrincipalService"
binding="netNamedPipeBinding"
contract="ManagementInformationSystem.Services.Contracts.IPrincipalService" />
<endpoint address="PrincipalService/mex"
binding="mexNamedPipeBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<diagnostics wmiProviderEnabled="true">
</diagnostics>
Client Configuration
<system.serviceModel>
<bindings>
<netNamedPipeBinding>
<binding name="NetNamedPipeBinding_IPrincipalService" />
</netNamedPipeBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="endpointBehavior">
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="net.pipe://localhost/ManagementInformationSystemServices/PrincipalService"
binding="netNamedPipeBinding" bindingConfiguration="NetNamedPipeBinding_IPrincipalService"
contract="PrincipalServiceReference.IPrincipalService" name="NetNamedPipeBinding_IPrincipalService">
<identity>
<userPrincipalName value="company-238\company" />
</identity>
</endpoint>
</client>
<diagnostics wmiProviderEnabled="true">
</diagnostics>
Service Helper Class and I am getting Communication Exception here
public static class ServiceHelper<T>
{
public static ChannelFactory<T> _channelFactory = new ChannelFactory<T>(GlobalResource.PrincipalServiceEndPointName);
public static void Use(UseServiceDelegate<T> codeBlock)
{
IClientChannel proxy = (IClientChannel)_channelFactory.CreateChannel();
bool success = false;
try
{
codeBlock((T)proxy);
proxy.Close();
success = true;
}
catch (CommunicationException ex)
{
throw ex;
}
catch (TimeoutException ex)
{
throw ex;
}
finally
{
if (!success)
{
proxy.Abort();
}
}
}
}

Missing contract in WCF self hosted console application

Trying to make simple selfhosted WCF service in console application:
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
namespace SupportSrvWCF
{
[ServiceContract]
public interface IA
{
[OperationContract]
int LogIt(int id, string data, ref int level);
}
public class SupportServicee : IA
{
public int LogIt(int id, string data, ref int level)
{
return 0;
}
}
class Program
{
static void Main(string[] args)
{
try
{
ServiceHost selfHost = new ServiceHost(typeof(SupportServicee));
selfHost.Open();
Console.WriteLine("The service is running. Press any key to stop.");
Console.ReadKey();
}
catch (Exception e)
{
Console.WriteLine("An error occurred: '{0}'", e);
}
}
}
}
App.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<services>
<service name="SupportSrvWCF.SupportServicee">
<endpoint address="" binding="basicHttpBinding" contract="SupportSrvWCF.IA ">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8002/WCFService1" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<!--<behavior name="CalculatorServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>-->
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
</system.serviceModel>
</configuration>
Have exception:
An error occurred: 'System.InvalidOperationException: The contract name 'Support
SrvWCF.IA ' could not be found in the list of contracts implemented by the servi
ce 'SupportServicee'.
Where is problem
hello try the following code instead and delete the service configuration from app.config
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
namespace SupportSrvWCF
{
[ServiceContract]
public interface IA
{
[OperationContract]
int LogIt(int id, string data, ref int level);
}
public class SupportServicee : IA
{
public int LogIt(int id, string data, ref int level)
{
return 0;
}
}
class Program
{
static void Main(string[] args)
{
using (ServiceHost selfHost = new ServiceHost(typeof(SupportServicee),new Uri("http://localhost:8080/Myservice")))
{
try
{
selfHost.AddServiceEndpoint(typeof(IA),new BasicHttpBinding(),"basic");
selfHost.Open();
Console.WriteLine("The service is running. Press any key to stop.");
Console.ReadKey();
}
catch (Exception e)
{
Console.WriteLine("An error occurred: '{0}'", e);
}
}
}
}
}

WCF Authentication using basicHttpBinding and custom UserNamePasswordValidator?

Here i am implementing custom usernamepasswordvalidator in WCF RESTfull service.What i need is while invoking this one http://localhost:12229/RestServiceImpl.svc/GetStudentObj through Chrome REST Client it is not validating the username password..it directly invoke this method and fetching the result.What am i doing wrong here??
My interface
[ServiceContract]
public interface IRestServiceImpl
{
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "/GetStudentObj", RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]
Student GetStudent();
}
SVC
public class RestServiceImpl : IRestServiceImpl
{
public Student GetStudent()
{
Student stdObj = new Student
{
StudentName = "Foo",
Age = 29,
Mark = 95
};
return stdObj;
}
public class CustomUserNameValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
if (null == userName || null == password)
{
throw new ArgumentNullException("You must provide both the username and password to access this service");
}
if (!(userName == "user1" && password == "test") && !(userName == "user2" && password == "test"))
{
throw new SecurityTokenException("Unknown Username or Incorrect Password");
}
}
}
}
and Web.Config
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webHttpTransportSecurity">
<security mode="Transport">
<transport clientCredentialType="Basic"></transport>
</security>
</binding>
</webHttpBinding>
</bindings>
<protocolMapping>
<add scheme="http" binding="webHttpBinding"/>
</protocolMapping>
<services>
<service name="RestService.RestServiceImpl" >
<endpoint address="" binding="webHttpBinding" contract="RestService.IRestServiceImpl"></endpoint>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior>
<webHttp />
</behavior >
</endpointBehaviors>
<serviceBehaviors>
<behavior name="SecureRESTSvcTestBehavior">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="RESTfulSecuritySH.CustomUserNameValidator, RESTfulSecuritySH" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Any suggestion??
It seems that you didn't set the custom behavior for your service.
You need to tell the service about your SecureRESTSvcTestBehavior behavior by using the behaviorConfiguration attribute:
<service name="RestService.RestServiceImpl" behaviorConfiguration="SecureRESTSvcTestBehavior">
<endpoint address="" binding="webHttpBinding" contract="RestService.IRestServiceImpl"></endpoint>
</service>

Categories

Resources