I have a WCF SOAP Service with wsHttpBinding, i have 2 methods, the first one executes fine, but for some reason the call to the second method times out. I debuged the method and the everything is fine i my code, it executes and returns, but the in the client, on the same machine, the requests times out. I created a new WCF Service Application project, copied the entire code + config to the new project, ran it, and the method didn't time out for a few times, then suddenly it started doing it again.
here is the config:
<system.serviceModel>
<services>
<service behaviorConfiguration="PolicyServiceBehavior" name="IST.Broker.Services.PolicyServiceV2.PolicyService">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="PolicyServiceBindingConfiguration"
contract="IST.Broker.Services.PolicyServiceV2.IPolicyService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:63915/" />
</baseAddresses>
<timeouts closeTimeout="00:01:00" openTimeout="00:01:00" />
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="PolicyServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceThrottling maxConcurrentCalls="2147483647" maxConcurrentSessions="2147483647" maxConcurrentInstances="2147483647" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="PolicyServiceBindingConfiguration"
bypassProxyOnLocal="false"
transactionFlow="false"
hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="2000000"
maxReceivedMessageSize="2000000"
messageEncoding="Text"
textEncoding="utf-8"
useDefaultWebProxy="true"
allowCookies="true">
<readerQuotas
maxDepth="2000000"
maxStringContentLength="2000000"
maxArrayLength="2000000"
maxBytesPerRead="2000000"
maxNameTableCharCount="2000000" />
<reliableSession
enabled="true"
inactivityTimeout="00:01:00" />
<security mode="None"/>
</binding>
</wsHttpBinding>
</bindings>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
The service cotnract:
[ServiceContract(SessionMode = SessionMode.Required)]
public interface IPolicyService
{
[OperationContract(IsInitiating = true)]
void Initialize(int employeeId);
[OperationContract(IsInitiating = false, IsTerminating = false)]
GetPolicyResponse GetPolicy(GetPolicyRequest request);
[OperationContract(IsInitiating = false, IsTerminating = false)]
CreateMtplApplicationResponse CreateMtplApplication(CreateMtplApplicationRequest request);
[OperationContract(IsInitiating = false, IsTerminating = true)]
void SignOut();
}
And implementation:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.PerSession)]
public class PolicyService : IPolicyService
{
private Employee _currentEmployee;
public GetPolicyResponse GetPolicy(GetPolicyRequest request)
{
return new GetPolicyResponse(PolicyManager.GetPolicy(request.Id, request.PolicyNumber));
}
public void Initialize(int employeeId)
{
if (!InsuranceCompaniesServiceManager.IsInitialized)
{
var appPhysicalPath = HostingEnvironment.ApplicationPhysicalPath;
_currentEmployee = EmployeeManager.GetEmployee(employeeId);
InsuranceCompaniesServiceManager.Initialize(_currentEmployee, appPhysicalPath);
}
}
public CreateMtplApplicationResponse CreateMtplApplication(CreateMtplApplicationRequest request)
{
return new CreateMtplApplicationResponse(PolicyManager.CreateMtplApplication(request.CompanyId, request.Policy.ToBusinessObject(), request.Vehicle.ToBusinessObject(),
request.Clients.Select(x => x.ToBusinessObject()).ToList(), request.GreenCard.ToBusinessObject(), request.Sticker.ToBusinessObject()));
}
public void SignOut()
{
}
}
EDIT:
The method is calling a DLL that inside is calling another service.
Comment out below line because it'll be added automatically while configuring the proxy.
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
If you want to check, Right click on service proxy where you added service proxy, and select "Configure Service Reference" and you'll notice /mex is added in URL of the service at last
Related
I am frustrated. Okay, here is the error.
There was no endpoint listening at net.pipe://localhost/MyIpcAppToService that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
I finally got the App.Config file working, at least no complaints.
Current App.Config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
</startup>
<system.serviceModel>
<services>
<service behaviorConfiguration="MyServiceBehavior" name="MyService.Communication.IpcAppToService">
<endpoint address="net.pipe://localhost/MyIpcAppToService" binding="wsDualHttpBinding" bindingConfiguration="MyAppToServiceEndpointBinding" contract="MyIpc.IIpcAppToService"/>
<endpoint address="mex" binding="mexHttpBinding" name="mex" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/MyService/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add scheme="http" binding="wsHttpBinding" bindingConfiguration="MyAppToServiceEndpointBinding" />
</protocolMapping>
<bindings>
<wsDualHttpBinding>
<!-- https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/wcf/wshttpbinding -->
<binding name="MyAppToServiceEndpointBinding"
transactionFlow="true"
sendTimeout="00:01:00"
maxReceivedMessageSize="2147483647"
messageEncoding="Mtom">
</binding>
</wsDualHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
<baseAddressPrefixFilters>
<add prefix="http://localhost:8733"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
</system.serviceModel>
<appSettings>
<add key="countoffiles" value="7"/>
<add key="logfilelocation" value="abc.txt"/>
</appSettings>
</configuration>
I used to have:
<endpoint address="http://localhost:8733/MyIpcAppToService" ...
and in the Windows Service OnStart() event:
(this following code is now commented out, as of this question post, as the App.config file is supposed to start the named.pipe.)
public Boolean CreatePipeServer()
{
string eventText = $"My Service: CommAppToService::CreatePipeServer(IPC App to Service){Environment.NewLine}";
try
{
if (null != this.ServiceParent.HostIpcAppToService)
this.ServiceParent.HostIpcAppToService = null;
string pipeBaseAddress = #"net.pipe://localhost/MyIpcAppToService";
this.ServiceParent.HostIpcAppToService = new ServiceHost(typeof(IpcAppToService), new Uri(pipeBaseAddress));
NetNamedPipeBinding pipeBinding = new NetNamedPipeBinding()
{
//ReceiveTimeout = new TimeSpan(0, 0, 0, 0, Constants.My_TimeoutMsSendReceive),
//SendTimeout = new TimeSpan(0, 0, 0, 0, Constants.My_TimeoutMsSendReceive),
};
this.ServiceParent.HostIpcAppToService.AddServiceEndpoint(typeof(IIpcAppToService), pipeBinding, "MyIpcAppToService");
this.ServiceParent.HostIpcAppToService.UnknownMessageReceived += HostIpcAppServer_UnknownMessageReceived;
this.ServiceParent.HostIpcAppToService.Faulted += HostIpcAppServer_Faulted;
this.ServiceParent.HostIpcAppToService.Closing += HostIpcAppServer_Closing;
this.ServiceParent.HostIpcAppToService.Closed += HostIpcAppServer_Closed;
this.IpcAppToService = new IpcAppToService();
this.IpcAppToService.ApplyDispatchBehavior(this.ServiceParent.HostIpcAppToService);
this.IpcAppToService.Validate(this.ServiceParent.HostIpcAppToService);
this.ServiceParent.HostIpcAppToService.Open();
return true;
}
I read that the service will AUTOMATICALLY start services placed in the App.Config file, really the MyExeName.exe.config file. I kept looking at the code and saw that it was nearly identical, so I replaced the http:// with net.pipe://.
Sadly, old code, new code, in between code, all nothing. I keep receiving the same error.
I use the following to connect to the service from my desktop application.
public static Boolean ConnectToService()
{
try
{
var callback = new IpcCallbackAppToService();
var context = new InstanceContext(callback);
var pipeFactory = new DuplexChannelFactory<IIpcAppToService>(context, new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/MyIpcAppToService"));
Program.HostIpcAppToService = pipeFactory.CreateChannel();
Program.HostIpcAppToService.Connect();
CommAppToService.IsPipeAppToService = true;
return true;
}
catch (Exception ex)
{
// Log the exception.
Errors.LogException(ex);
}
return false;
}
For whatever it is worth, here is:
Interface
[ServiceContract(SessionMode = SessionMode.Allowed, CallbackContract = typeof(IIpcCallbackAppToService))]
public interface IIpcAppToService
{
[OperationContract(IsOneWay = false)]
[FaultContractAttribute(typeof(IpcAppToServiceFault))]
UInt16 GetServiceId();
...
}
Service:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class IpcAppToService : IIpcAppToService, IErrorHandler
{
public static IIpcCallbackAppToService Callback { get; set; } = null;
public void OpenCallback()
{
IpcAppToService.Callback = OperationContext.Current.GetCallbackChannel<IIpcCallbackAppToService>();
}
public void CloseCallback()
{
IpcAppToService.Callback = null;
}
public void SendMessage(string message)
{
//MessageBox.Show(message);
}
public UInt16 GetServiceId()
{
return Constants.My_Id_AppToService;
}
...
}
Inner Exception from my desktop WinForms Application
(Note, there were no further inner exceptions than this one.):
"The pipe endpoint 'net.pipe://localhost/MyIpcAppToService' could not be found on your local machine."
Why do I keep seeing this error?
UPDATE AFTER 1ST ANSWER
The direction that I would like to take is opposite of the answer, yet the same, namely that the service starts with the App.config and the client uses C# code.
Sadly, I still get the same error.
Revised Server Side App.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
</startup>
<system.serviceModel>
<services>
<service behaviorConfiguration="BehaviorMyService" name="MyService.Communication.IpcAppToService">
<endpoint address="net.pipe://localhost/MyIpcAppToService"
binding="netNamedPipeBinding"
bindingConfiguration="EndpointBindingMyAppToService"
contract="MyIpc.IIpcAppToService"
/>
<endpoint address="mex" binding="mexHttpBinding" name="mex" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/MyService/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="BehaviorMyService">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true"
httpsGetEnabled="true"
/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netNamedPipeBinding>
<!-- https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/wcf/wshttpbinding -->
<binding name="EndpointBindingMyAppToService"
closeTimeout="00:01:00"
openTimeout="00:01:00"
receiveTimeout="00:10:00"
sendTimeout="00:01:00"
transactionFlow="false"
transferMode="Buffered"
transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288"
maxBufferSize="65536"
maxConnections="10"
maxReceivedMessageSize="2147483647"
>
<security mode="None">
<transport protectionLevel="None" />
</security>
</binding>
</netNamedPipeBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
<baseAddressPrefixFilters>
<add prefix="http://localhost:8733"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
</system.serviceModel>
<appSettings>
<add key="countoffiles" value="7"/>
<add key="logfilelocation" value="abc.txt"/>
</appSettings>
</configuration>
Revised Client Side C# Code:
var callback = new IpcCallbackAppToService();
InstanceContext context = new InstanceContext(callback);
NetNamedPipeBinding binding = new NetNamedPipeBinding();
binding.Security.Mode = NetNamedPipeSecurityMode.None;
EndpointAddress endpointAddress = new EndpointAddress("net.pipe://localhost/MyIpcAppToService");
var pipeFactory = new DuplexChannelFactory<IIpcAppToService>(context, binding, endpointAddress);
Program.HostIpcAppToService = pipeFactory.CreateChannel();
Program.HostIpcAppToService.Connect();
CommAppToService.IsPipeAppToService = true;
The service throws no exceptions that I can detect, as the EventViewer is clean, just the OnStart() successfully completed message. I know that the system processes the App.config file, as previously when I had errors, the Windows Event Viewer would keep complaining, but not anymore.
Here were some of the Microsoft docs that I used:
netNamedPipeBinding
netNamedPipeBinding2
I did try IO Ninja, but specifying \\.\pipe\MyIpcToService for File Stream, Pipe Listener, and Pipe Monitor, but nothing shows there, even when I try to connect using my WinForms desktop application, which then throws the no pipe listener found exception.
What can be the problem?
<endpoint address="net.pipe://localhost/MyIpcAppToService" binding="wsDualHttpBinding" bindingConfiguration="MyAppToServiceEndpointBinding" contract="MyIpc.IIpcAppToService"/>
Make sure that the service address is in the same form (transport protocol) as the binding type.
TCP(net.tcp://localhost:8000/myservice) NetTcpBinding
IPC(net.pipe://localhost/mypipe) NetNamedPipeBinding
Http/Https(http://localhost:8000/myservice)
Wshttpbinding,Wsdualhttpbinding,basichttpbinding
WebSocket(ws://localhost:3434) Nethttpbinding
MSMQ(net.msmq://localhost/private/myservice) NetMsmqBinding
we are supposed to use NetnamedPipeBinding for the service address. Please refer to my example.
Updated
I have a wcf service using NetNamedPipeBinding hosted in IIS, wish it is useful to you.
Server(wcf service application)
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
}
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
}
Web.config(Server side)
<system.serviceModel>
<services>
<service behaviorConfiguration="BehaviorMyService" name="WcfService1.Service1">
<endpoint address="MyIpcAppToService"
binding="netNamedPipeBinding"
bindingConfiguration="EndpointBindingMyAppToService"
contract="WcfService1.IService1"
/>
<endpoint address="mex" binding="mexHttpBinding" name="mex" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="BehaviorMyService">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netNamedPipeBinding>
<binding name="EndpointBindingMyAppToService"
closeTimeout="00:01:00"
openTimeout="00:01:00"
receiveTimeout="00:10:00"
sendTimeout="00:01:00"
transactionFlow="false"
transferMode="Buffered"
transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288"
maxConnections="10"
maxReceivedMessageSize="2147483647"
>
<security mode="None">
<transport protectionLevel="None" />
</security>
</binding>
</netNamedPipeBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
</serviceHostingEnvironment>
</system.serviceModel>
Enable WCF new feature.
IIS site(enable net.pipe)
Client(console application)
ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
var result = client.GetData(34);
Console.WriteLine(result);
Client app.config(auto-generated)
I use the http address(service metadata GET address http://localhost:8733/Service1.svc?wsdl) to generated the configuration.
<system.serviceModel>
<bindings>
<netNamedPipeBinding>
<binding name="NetNamedPipeBinding_IService1">
<security mode="None" />
</binding>
</netNamedPipeBinding>
</bindings>
<client>
<endpoint address="net.pipe://mynetpipe/Service1.svc/MyIpcAppToService"
binding="netNamedPipeBinding" bindingConfiguration="NetNamedPipeBinding_IService1"
contract="ServiceReference1.IService1" name="NetNamedPipeBinding_IService1" />
</client>
</system.serviceModel>
Feel free to let me know if there is anything I can help with.
My web.config for WCF service looks like below
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfService1.Service1">
<endpoint address="" binding="basicHttpBinding"
bindingConfiguration="" name="service1Endpoint"
contract="WcfService1.IService1" />
<endpoint address=""
behaviorConfiguration="WcfService1.AjaxAspNetAjaxBehavior"
binding="" contract="WcfService1.IService1" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="service1Endpoint" />
</basicHttpBinding>
<webHttpBinding>
<binding name="webHttpBinding" />
</webHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:2393/Service1.svc"
binding="basicHttpBinding"
bindingConfiguration="service1Endpoint"
contract="ServiceReference1.IService1"
name="service1Endpoint" />
<endpoint address="http://localhost:2393/Service1.svc"
behaviorConfiguration="WcfService1.AjaxAspNetAjaxBehavior"
binding="webHttpBinding" contract="ServiceReference1.IService1"
/>
</client>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to
false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment to avoid
disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="WcfService1.AjaxAspNetAjaxBehavior">
<enableWebScript />
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
I have another simple aspx page created to test whether service is accessible or not. But when I am trying to run this service error displayed is Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata. Can anyone tell me how to resolve this error.
Thanks in advance.
My web service and contract is as below
namespace WcfService1
{
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
}
}
Contract looks like below
namespace WcfService1
{
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped,
ResponseFormat = WebMessageFormat.Json)]
string GetData(int value);
}
}
You need a mex service endpoint to allow metadata to be exposed. Add a new endpoint under service node like:
<endpoint address="mex" binding="mexHttpBinding" name="MetadataEndpoint"
contract="IMetadataExchange" />
Read more about Metadata Exchange Endpoint here:
http://www.wcftutorial.net/Metadata-Exchange-Endpoint.aspx
I have the followings:
In Competitions.svc:
<%# ServiceHost Language="C#" Debug="true" Service="MySite_WebSite.Pages.Client.CompetitionsSVC" CodeBehind="Competitions.svc.cs" %>
In ICompetitions.cs :
namespace MySite_WebSite.Pages.Client
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "ICompetitions" in both code and config file together.
[ServiceContract(Name="CompetitionsSVC")]
public interface ICompetitions
{
[OperationContract]
[WebInvoke(
Method = "GET"
, RequestFormat = WebMessageFormat.Json
, ResponseFormat = WebMessageFormat.Json
, UriTemplate = "DoWork"
, BodyStyle=WebMessageBodyStyle.Wrapped
)]
Dictionary<DateTime, List<Competitions.Entry>> DoWork();
}
}
In Competitions.svc.cs :
namespace MySite_WebSite.Pages.Client
{
[DataContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class CompetitionsSVC : ICompetitions
{
#region ICompetitions Members
public Dictionary<DateTime, List<Competitions.Entry>> DoWork()
{
var c = new Competitions();
return c.GetMonthlyEntries(new Competitions.ParamGetMonthlyEntries()
{
Start = DateTime.Now.Date.AddMonths(-1)
, End = DateTime.Now.Date.AddMonths(2)
, UserLang = "fr-BE"
, ActiveLang = "fr-BE"
, IsExternal = false
});
}
#endregion
}
}
In Web.config:
<system.serviceModel>
<services>
<service name="MySite_WebSite.WS.WCF.SubsetMID">
<endpoint address=""
binding="wsHttpBinding"
contract="MySite_WebSite.WS.WCF.ISubsetMID" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
<service name="MySite_WebSite.Pages.Client.CompetitionsSVC">
<endpoint address=""
binding="webHttpBinding"
behaviorConfiguration="WebBehavior"
contract="MySite_WebSite.Pages.Client.ICompetitions" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<bindings>
<wsHttpBinding>
<binding>
<security mode="None"/>
</binding>
</wsHttpBinding>
<netTcpBinding>
<binding name="NetTcpBinding_IServiceWCallBack" sendTimeout="00:10:00"
maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxStringContentLength="2147483647" />
<security mode="None" />
</binding>
<binding name="NetTcpBinding_IHandleSubset">
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="WebBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment
multipleSiteBindingsEnabled="true"
aspNetCompatibilityEnabled="true"
/>
</system.serviceModel>
When I enter the url
localhost2/MySite_WebSite/Pages/Client/Competitions.svc/DoWork
, it doesn't work.
I have a breakpoint at the begining of the method, and I can see the method gets called twice, yet it doesn't return anything (I don't even think it send any HTTP code backs).
What did I do wrong?
Additional notes:
Entry is actually a "base class".
public class EntryCompetition : Entry
public class EntryEvent : Entry
In my code the dictionary actually contains EntryCompetition and EntryEvent instances.
Thanks for posting your code that definitely helps. But i think you're going to need to show a little more work, and some more concrete results on how your project is failing. But so as not to leave you helpless. I recommend looking at Fiddler
http://www.telerik.com/fiddler
It allows you to create Http requests and to see the responses inside of it's console. it is useful for seeing specifically what http response code your endpoint is returning, and allows you to modify your request through the composer window.
another helpful tip, would be to step all the way through your code, so you can point us to exactly what line is failing or what values are being set before your method completes.
Without more information, my best guess is you're code is throwing and most likely swallowing an exception. Or your methods or calls are setting null values that don't return the values you expect. Please reply once you've setup some further tests and updated your question if you are still having issues.
Ok, I solved the problem. I use a custom piece o code to serialize the dictionnary into a JSON string and I don't use DateTime objects as keys anymore.
I am attempting to secure a new .Net 4.5 WCF service using HTTPS / SSL, Basic client credentials and the WebHttpBinding. From reading up online I found a good series of Blog Posts from Allen Conway which I have used as a template.
WCF configuration
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webInteropSecureBinding" allowCookies="false" maxBufferPoolSize="2097152" maxBufferSize="2097152" maxReceivedMessageSize="2097152">
<security mode="Transport">
<transport clientCredentialType="Basic"></transport>
</security>
</binding>
</webHttpBinding>
</bindings>
<services>
<service name="PsmDataProvider.PsmProvider" behaviorConfiguration="SecureRest">
<clear />
<endpoint address="" binding="webHttpBinding" bindingConfiguration="webInteropSecureBinding" name="PsmProvider" contract="PsmDataProvider.IPsmProvider" behaviorConfiguration="webHttpBehavior" />
<endpoint address="mex" binding="mexHttpsBinding" name="mex" contract="IMetadataExchange" listenUriMode="Explicit" />
<host>
<baseAddresses>
<add baseAddress="https://localhost:44300/PsmProvider/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="SecureRest">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="PsmDataProvider.Security.CustomerUserNamePasswordValidator, PsmDataProvider"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webHttpBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
CustomerUserNamePasswordValidator
I have stubbed out the CustomerUserNamePasswordValidator implementation and have confirmed that the constructor is called before the exception is raised.
using System;
using System.IdentityModel.Selectors;
namespace PsmDataProvider.Security
{
internal class CustomerUserNamePasswordValidator : UserNamePasswordValidator, ICustomerUserNamePasswordValidator
{
public CustomerUserNamePasswordValidator()
{
}
public override void Validate(string userName, string password)
{
if (userName == null) throw new ArgumentNullException("userName","The username must be provided in the request to access this service");
if (password == null) throw new ArgumentNullException("password", "The password must be provided in the request to access this service");
}
}
}
When I try to run the code in VS2012 through IIS Express the service fails to start with the below error.
If I remove the clientCredentialType from the configuration then it works but I require the additional security of using the username / password validation on the service and possibly at a method level in the future.
Is this something I have configured incorrectly in the WCF config or a problem with the configuration in IISExpress?
Please help...
The issue appears to be when using Basic Authentication when hosting the service in IIS as IIS wants to handle the authentication.
This is discussed in this MSDN blog post
In the version of WCF that shipped with .Net Framework 3.0 we didn't
support custom validators with transport level HTTP security. We
received much feedback from the community that this was a highly
desired feature, so I'm happy to say we added support for this
scenario in the 3.5 release of the .Net Framework. Note that this is
only supported under self hosted services.
There is a resolution as discussed in Allen Conway's Blog Post by implementing a custom authorisation manager derived from ServiceAuthorizationManager
CustomAuthorizationManager
public class CustomAuthorizationManager : ServiceAuthorizationManager
{
private const string UserName = "username";
private const string Password = "password";
protected override bool CheckAccessCore(OperationContext operationContext)
{
string authHeader = WebOperationContext.Current.IncomingRequest.Headers["Authorization"];
if ((authHeader != null) && (authHeader != string.Empty))
{
string[] svcCredentials = System.Text.ASCIIEncoding.ASCII
.GetString(Convert.FromBase64String(authHeader.Substring(6)))
.Split(':');
var user = new { Name = svcCredentials[0], Password = svcCredentials[1] };
if ((user.Name.Equals(UserName) && user.Password.Equals(Password)))
return true;
else
return false;
}
else
{
WebOperationContext.Current.OutgoingResponse.Headers.Add("WWW-Authenticate: Basic realm=\"PsmProvider\"");
throw new WebFaultException(HttpStatusCode.Unauthorized);
}
}
}
Config
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webInteropSecureBinding" allowCookies="false" maxBufferPoolSize="51200" maxBufferSize="51200" maxReceivedMessageSize="51200">
<security mode="Transport"/>
</binding>
</webHttpBinding>
</bindings>
<services>
<service name="PsmDataProvider.PsmProvider" behaviorConfiguration="SecureRest">
<clear />
<endpoint binding="webHttpBinding" bindingConfiguration="webInteropSecureBinding"
name="PsmProvider" contract="PsmDataProvider.IPsmProvider" behaviorConfiguration="webHttpBehavior" />
<endpoint address="mex" binding="mexHttpsBinding" name="mex" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="https://localhost:44300/PsmProvider/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="SecureRest">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceAuthorization serviceAuthorizationManagerType="PsmDataProvider.Security.CustomAuthorizationManager, PsmDataProvider"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webHttpBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Note
Also note a comment from Travich regarding the IIS / IIS Express configuration
Travich said... One thing to help other users. It was briefly stated,
but something I overlooked... Turn off Basic Auth in IIS and remove
tag from your webHttpBinding!
Works for me.
Setup is mono latest stable on raspberry pi, polling data from service on server with .NET 4.5.
My configuration for server side:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="vlcBehaviour">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="ser.Serwys">
<endpoint address="net.tcp://192.168.56.1:9070/WindowService" binding="netTcpBinding" bindingConfiguration="AnonymousTcpBinding"
contract="Window.Service.IWindowServiceHost" />
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="AnonymousTcpBinding" receiveTimeout="00:00:01"
sendTimeout="00:00:01"
maxBufferSize="1000"
maxConnections="100"
maxBufferPoolSize="100"
listenBacklog="200"
maxReceivedMessageSize="1000">
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
On client side:
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="maxItems">
<dataContractSerializer maxItemsInObjectGraph="2147483646" />
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="AnonymousTcpBinding" openTimeout="00:00:01" receiveTimeout="00:00:01" sendTimeout="00:00:01" maxBufferSize="1000" maxConnections="200" listenBacklog="200" maxReceivedMessageSize="1000">
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint name="WindowService" address="net.tcp://192.168.56.1:9070/WindowService" binding="netTcpBinding" bindingConfiguration="AnonymousTcpBinding" contract="Window.Service.IWindowServiceHost" />
</client>
</system.serviceModel>
Service contract:
namespace Window.Service
{
[ServiceContract(
Namespace = "http://window",
Name = "WindowHost")]
public interface IWindowServiceHost
{
[OperationContract]
void Connect(int windowId);
[OperationContract]
void Disconnect();
[OperationContract]
DisplayData GetData();
}
}
Implementation of service:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
public class Serwys:IWindowServiceHost
Method that is called:
public DisplayData GetData()
{
Console.WriteLine("Called get data {0}:{1}:{2}",DateTime.Now.Minute,DateTime.Now.Second,DateTime.Now.Millisecond);
return new DisplayData
{
BoxesInProgress = 1,
};
}
Call to GetData from client takes more and more time, don't know why.
I have tested it on Ubuntu also, Mono is latest version here how I log it:
Stopwatch stp = new Stopwatch();
stp.Start();
var data = remote.GetData();
stp.Stop();
log.WarnFormat("Polling service took: {0} ms", stp.ElapsedMilliseconds);
Any explanations?? I think it is Mono bug, because setup is really basic no concurrency method called is dead simple, and polling times are going up.
I call it on timer elapse, and for test I call it every 10ms but it is growing even if I call it every second, but slower, and this only gives me more time before all crashes.