The requested address is not valid in this context - c#

I have a WCF rest service define like this:
static void Main(string[] args)
{
try
{
DOMConfigurator.Configure();
string serviceUriStr = "http://127.0.0.1:9001/AFMServer";
Uri serviceUri = new Uri(serviceUriStr);
_webHost = new WebServiceHost(typeof(AftermathFacade), serviceUri);
WebHttpBinding binding = new WebHttpBinding(WebHttpSecurityMode.None);
binding.MaxBufferPoolSize = 2000000000;
binding.MaxReceivedMessageSize = 2000000000;
//binding.ReceiveTimeout = TimeSpan.MaxValue;
//binding.CloseTimeout = TimeSpan.MaxValue;
//binding.SendTimeout = TimeSpan.MaxValue;
////binding.OpenTimeout = TimeSpan.MaxValue;
_webHost.AddServiceEndpoint(typeof(IAftermathFacade), binding, serviceUriStr);
ServiceThrottlingBehavior stb = new ServiceThrottlingBehavior();
stb.MaxConcurrentCalls = 1000;
stb.MaxConcurrentInstances = 1000;
stb.MaxConcurrentSessions = 1000;
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
_webHost.Description.Behaviors.Add(smb);
_webHost.Description.Behaviors.Add(stb);
_webHost.Open();
_log.Info("Listening on Uri: " + serviceUri.AbsoluteUri);
Console.ReadLine();
}
catch (Exception ex)
{
_log.Error(ex.StackTrace);
}
}
Accessing this service from a client randomly throws a
"The requested address is not valid in this context"
exception. Sometimes it does, sometimes it does not and the remote call works.
What I noticed is that it seems to happen when to calls to the service are made too quickly.
for instance:
CallServiceMethod1();
CallSericeMethod2();
throws an exception.
However:
CallServiceMethod1();
sleep(1000);
CallSericeMethod2();
Works!
Any idea where the problem might be coming from?
Note that the service is hosted on a AWS micro instance (very poor performance). When I test locally on my box, the exception is not happening as often.

Related

wsHttpBinding workarounds in .NET Core

I am looking for a dotnet core WCF wsHttpBinding workaround.
I am aware that .net core WCF implementation currently does not support wsHttpBinding (see support matrix here https://github.com/dotnet/wcf/blob/master/release-notes/SupportedFeatures-v2.1.0.md)
I'm integrating with a legacy third party service that appears to only support wsHttpBinding. Our tech stack is .net core, so I cannot revert to the full version of .net framework or mono variant.
The question is whether it's possible to use the service via custom bindings? I am hoping that there is a workaround that maybe isn't fully functional, but at least allows me to consume the service.
var cBinding = new CustomBinding();
var textBindingElement = new TextMessageEncodingBindingElement()
{
MessageVersion = MessageVersion.Soap12WSAddressing10
};
cBinding.Elements.Add(textBindingElement);
var httpBindingElement =
new HttpsTransportBindingElement
{
AllowCookies = true, MaxBufferSize = int.MaxValue, MaxReceivedMessageSize = int.MaxValue,
};
cBinding.Elements.Add(httpBindingElement);
var myEndpoint = new EndpointAddress("https://..../Service.svc/wss");
using (var myChannelFactory = new ChannelFactory<ISearch>(cBinding, myEndpoint))
{
myChannelFactory.Credentials.UserName.UserName = "...";
myChannelFactory.Credentials.UserName.Password = "...";
ISearch client = null;
try
{
client = myChannelFactory.CreateChannel();
var result = client.Find(new Search("Criteria")).Result;
((ICommunicationObject)client).Close();
myChannelFactory.Close();
}
catch (Exception ex)
{
(client as ICommunicationObject)?.Abort();
}
}
Client gets created and a call is made to the service, but it fails because:
Message = "The message could not be processed. This is most likely because the action '' is incorrect or because the message contains an invalid or expired security context token or because there is a mismatch between binding
Forget it, they are not completely compatible with Core. Under some specified case, there may be a basic call to WsHttpBinding. You could refer to the following example.
Server.
Uri uri = new Uri("http://localhost:11011");
WSHttpBinding binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.None;
using (ServiceHost sh=new ServiceHost(typeof(MyService),uri))
{
sh.AddServiceEndpoint(typeof(IService), binding, "");
ServiceMetadataBehavior smb;
smb = sh.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (smb==null)
{
smb = new ServiceMetadataBehavior()
{
};
sh.Description.Behaviors.Add(smb);
}
Binding mexbinding = MetadataExchangeBindings.CreateMexHttpBinding();
sh.AddServiceEndpoint(typeof(IMetadataExchange), mexbinding, "mex");
sh.Opened += delegate
{
Console.WriteLine("Service is ready");
};
sh.Closed += delegate
{
Console.WriteLine("Service is clsoed");
};
sh.Open();
Client(auto-generated)
private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration)
{
if ((endpointConfiguration == EndpointConfiguration.WSHttpBinding_IService))
{
System.ServiceModel.Channels.CustomBinding result = new System.ServiceModel.Channels.CustomBinding();
System.ServiceModel.Channels.TextMessageEncodingBindingElement textBindingElement = new System.ServiceModel.Channels.TextMessageEncodingBindingElement();
result.Elements.Add(textBindingElement);
System.ServiceModel.Channels.HttpTransportBindingElement httpBindingElement = new System.ServiceModel.Channels.HttpTransportBindingElement();
httpBindingElement.AllowCookies = true;
httpBindingElement.MaxBufferSize = int.MaxValue;
httpBindingElement.MaxReceivedMessageSize = int.MaxValue;
result.Elements.Add(httpBindingElement);
return result;
}
Invocation.
ServiceReference1.ServiceClient client2 = new ServiceReference1.ServiceClient();
try
{
var res = client2.SayHelloAsync();
Console.WriteLine(res.Result);
}
catch (Exception)
{
throw;
}
While in most cases it is impossible to call WCF service created by WsHttpBinding.
Officials also have no intention of continuing to support plan for wshttpbinding.
Here are related discussions.
https://github.com/dotnet/wcf/issues/31
https://github.com/dotnet/wcf/issues/1370

How to generate GetSystemDateAndTime xml

I have the following bit of code that i took from this source...
public bool Initialise(string cameraAddress, string userName, string password)
{
bool result = false;
try
{
var messageElement = new TextMessageEncodingBindingElement()
{
MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None)
};
HttpTransportBindingElement httpBinding = new HttpTransportBindingElement()
{
AuthenticationScheme = AuthenticationSchemes.Digest
};
CustomBinding bind = new CustomBinding(messageElement, httpBinding);
mediaClient = new MediaClient(bind, new EndpointAddress($"http://{cameraAddress}/onvif/Media"));
mediaClient.ClientCredentials.HttpDigest.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
mediaClient.ClientCredentials.HttpDigest.ClientCredential.UserName = userName;
mediaClient.ClientCredentials.HttpDigest.ClientCredential.Password = password;
var profs = mediaClient.GetProfiles();
//rest of the code...
When i run wireshark while going through the GetProfiles() part in the debugger, I see that the generated XML looks like:
What code would it take to change the xml to look like:
How am i supposed to call the GetSystemDateAndTime function?
To call the GetProfiles function, I had to create a MediaClient and, then, call that function...
Is there such thing as a MediaClient to get access to the GetSystemDateAndTime??
Edit:
I found that you could use the DeviceClient to get access the the GetSystemDateAndTime function...
You'll need to add the device management wsdl to your connected services before:
https://www.onvif.org/ver10/device/wsdl/devicemgmt.wsdl
I also added System.Net.ServicePointManager.Expect100Continue = false; in there because i saw someone said it helped at this link...
So i added :
CustomBinding bind = new CustomBinding(messageElement, httpBinding);
System.Net.ServicePointManager.Expect100Continue = false;
DeviceClient d = new DeviceClient(bind, new EndpointAddress($"http://{cameraAddress}/onvif/device_service"));
var time = d.GetSystemDateAndTime();
Note:
I'm still getting the error:
ErrorMessage "The header 'To' from the namespace 'http://www.w3.org/2005/08/addressing' was not understood by the recipient of this message, causing the message to not be processed. This error typically indicates that the sender of this message has enabled a communication protocol that the receiver cannot process. Please ensure that the configuration of the client's binding is consistent with the service's binding. " string
This error is saying that there is trouble when trying to read a message, so i tough it was probably due to some sort of encoding ...
AND I WAS RIGHT!!
All I had to do was changing a parameter in the TextMessageEncodingBindingElement's creation.
MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.WSAddressing10)
All you need to do is make sure that you have good encoding and AuthenticationScheme...
Here's my final code to get an onvif camera's (here cohuHD camera) system and date and time settings:
public bool Initialise(string cameraAddress, string userName, string password)
{
bool result = false;
try
{
var messageElement = new TextMessageEncodingBindingElement()
{
MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.WSAddressing10)
};
HttpTransportBindingElement httpBinding = new HttpTransportBindingElement()
{
AuthenticationScheme = AuthenticationSchemes.Digest
};
CustomBinding bind = new CustomBinding(messageElement, httpBinding);
System.Net.ServicePointManager.Expect100Continue = false;
DeviceClient deviceClient = new DeviceClient(bind, new EndpointAddress($"http://{cameraAddress}/onvif/device_service"));
var temps = deviceClient.GetSystemDateAndTime();
}
catch (Exception ex)
{
ErrorMessage = ex.Message;
}
return result;
}
Bonus:
If you want to execute a function that needs credentials, you can add those to your deviceClient like so:
//DIGEST (httpBinding)
deviceClient.ClientCredentials.HttpDigest.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
deviceClient.ClientCredentials.HttpDigest.ClientCredential.UserName = userName;
deviceClient.ClientCredentials.HttpDigest.ClientCredential.Password = password;
Watch out also for the EndpointAddress' URL... I think some cameras use Device_service and other device_service .

SuperWebSocket: After restarting the program the server continues to listen a port

I'm using SuperWebSocket in my application, instance WebSocketServer with next configuration
var rootConfig = new RootConfig();
var serverConfig = new ServerConfig
{
Name = $"WebSocketName_{config.Host}:3202",
Mode = SocketMode.Tcp,
Ip = config.Host,
Port = config.Port,
MaxRequestLength = 80485760, // 80Mb
MaxConnectionNumber = 200,
LogAllSocketException = true,
};
this._webSocketServer = new WebSocketServer();
this._webSocketServer.Setup(rootConfig, serverConfig, logFactory: new Log4Net2NLogFactory());
However, after restarting the program I catch an exception:
Error Exception: 'System.Net.Sockets.SocketException (0x80004005)
How i can close the web socket server correctly during closing my applicaion.
P.S. Finalizer code
this._webSocketServer?.Dispose();

WCF EndpointNotFoundException when running as NetworkService

I have a net.Pipe WCF service that is hosted by IIS (right now, in my VS2010):
(Global.asax):
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
ServiceHost svcHost = new ServiceHost(typeof(DoSomethingService), new Uri("net.pipe://localhost/helloworld"));
var serviceBinding = new NetNamedPipeBinding { MaxReceivedMessageSize = int.MaxValue, MaxConnections = 2048 };
var sect = new NamedPipeTransportSecurity { ProtectionLevel = ProtectionLevel.EncryptAndSign };
var sec = new NetNamedPipeSecurity { Mode = NetNamedPipeSecurityMode.Transport, Transport = sect };
serviceBinding.Security = sec;
svcHost.AddServiceEndpoint(typeof(IDoSomethingContract), serviceBinding, "");
svcHost.Open();
}
I have a console app client:
static void Main(string[] args)
{
var factory = new ChannelFactory<IDoSomethingContract>();
var defaultCredentials = factory.Endpoint.Behaviors.Find<ClientCredentials>();
factory.Endpoint.Behaviors.Remove(defaultCredentials);
factory.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
factory.Credentials.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;
var serviceBinding = new NetNamedPipeBinding { MaxReceivedMessageSize = int.MaxValue, MaxConnections = 2048 };
var sect = new NamedPipeTransportSecurity { ProtectionLevel = ProtectionLevel.EncryptAndSign };
var sec = new NetNamedPipeSecurity { Mode = NetNamedPipeSecurityMode.Transport, Transport = sect };
serviceBinding.Security = sec;
var ep = new EndpointAddress("net.pipe://localhost/helloworld");
factory.Endpoint.Binding = serviceBinding;
var love = factory.CreateChannel(ep);
Console.WriteLine(love.Do());
Console.ReadKey();
}
Now everything works great when I run this as a user principal (and so I can use a PrincipalPermission inside my operation).
However, if I create myself a 'Network Service' command line prompt (using psexec), and try to run the client (with the service running, obviously), I get the EndpointNotFoundException exception.
Is there anything I need to do for Network Service to see my named pipe?
May be following articles useful for you
http://www.aspfree.com/c/a/asp-net/developing-a-wcf-service-library-and-hosting-it-as-wcf-web-service-using-vs2k8/
http://msdn.microsoft.com/en-us/library/dd728288%28v=vs.110%29.aspx
I was considering deleting this, but since somebody actually commented - I found the answer here:
http://social.msdn.microsoft.com/Forums/vstudio/en-US/fcb7254a-15b5-4be4-bf67-34d500bdce2d/wcf-netpipe-endpoint-not-found-exception-whitout-elevated-user-rights-uac-enabled?forum=wcf
Basically, since I was running my dev server as my own account, the service was published in Session namespace. Once I published this on real IIS as Network Service, it was visible in the Global Namespace, so I could see it.

Process not timing out properly

I am working on building a IP scanner for our program. It currently works but runs incredibly slow. The timeout doesn't seem to be working correctly. The code looks like this:
public Tracker Discover(Uri hostUri, string organizationTrackerId)
{
var binding = new NetTcpBinding();
binding.ReceiveTimeout = TimeSpan.FromSeconds(2);
binding.SendTimeout = TimeSpan.FromSeconds(2);
binding.OpenTimeout = TimeSpan.FromSeconds(2);
var endpointAddress = new EndpointAddress(hostUri);
using (var factory = new ChannelFactory<ITrackerService>(binding, endpointAddress))
{
try
{
factory.Open(TimeSpan.FromSeconds(2));
var channel = factory.CreateChannel();
Tracker tracker = channel.Discover(organizationTrackerId);
factory.Close();
return tracker;
}
catch (Exception)
{
factory.Abort();
}
}
return null;
}
This code is called from a for loop that loops through 255 IPs. When this function is called it currently takes ~16 seconds to finish even though I have tried to set the timeout at 2. Any ideas?

Categories