Intermittent WCF Error but unable to reproduce locally
In our application we are getting Operation was aborted while establishing a connection to net.tcp://XXXX. We are using WPF application to connect WCF service.
Tried to reproduce the error by recycle IIS pool, stopped WCF service but did not worked
Operation was aborted while establishing a connection to net.tcp://XXXX.
<binding name="MTOMCustomBinding" closeTimeout="00:10:00" openTimeout="00:10:00"
receiveTimeout="00:50:00" sendTimeout="00:10:00">
<mtomMessageEncoding maxBufferSize="2147483647" >
<readerQuotas maxDepth="32" maxStringContentLength="22524288" maxArrayLength="22524288"
maxBytesPerRead="22524288" maxNameTableCharCount="22524288" />
</mtomMessageEncoding>
</binding>
<endpoint address="net.tcp://XXXX.svc" binding="customBinding" bindingConfiguration="MTOMCustomBinding" behaviorConfiguration="ServiceViewEventBehavior" contract="XXXXXXX">
<identity>
<userPrincipalName value="XXXXXX" />
</identity>
</endpoint>
<behaviors>
<endpointBehaviors>
<behavior name="ServiceViewEventBehavior">
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</endpointBehaviors>
</behaviors>
If the error is intermittent, not accidental. When will such an error happen?
Under a normal circumstance, if the connection works properly, it seems to have something to do with the performance of the machine because of the large file transfer involved.
At last, the custom binding use http base address instead of Nettcp protocol address, so I don’t think the service endpoint address could be connected by using nettcp base address. It should throw an error when hosting the service, like below.
Unable to find a base address with an endpoint bound to CustomBinding
that matches the schema http. The registered base address scheme is
[net.tcp]
Feel free to let me know if the problem still exists.
Related
I'm a noob to calling WCF web services, so am hoping this is an easy question. When calling a web service with .NET 4 winform client, how do I change the authorization scheme from Anonymous to NTLM?
Right now I'm getting the exception: The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'NTLM'.
My goal is to build a little tool to help me monitor TFS 2010's data warehouse and cube. TFS provides a WarehouseControlWebService web service. I can call the service via Test mode in a browser when logged on to the server. However I'm trying to call the same web service remotely, from my desktop. My user account is in the local Administrators group on the server.
I've created a .NET 4 WinForm with the canonical Button1 and TextArea1. I then added a service reference to the web service and creatively called it ServiceReference1:
Add Service Reference...
http://tfssvr:8080/tfs/TeamFoundation/Administration/v3.0/WarehouseControlService.asmx
And here's my code behind:
private void button1_Click(object sender, EventArgs e)
{
// Creating a proxy takes about 3-4 seconds
var dwSvc = new ServiceReference1.WarehouseControlWebServiceSoapClient();
// Invoking the method throws an MessageSecurityException
var dwStatus = dwSvc.GetProcessingStatus(null, null, null);
}
I'm getting System.ServiceModel.Security.MessageSecurityException:
The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'NTLM'.
I've tried passing my credentials via:
dwSvc.ClientCredentials.Windows.ClientCredential =
new System.Net.NetworkCredential("user", "pass", "domain");
and also ...
dwSvc.ClientCredentials.Windows.ClientCredential =
CredentialCache.DefaultNetworkCredentials;
I'm wading through the WCF documentation but ... oh boy ... there's a lot there. I'm hoping this is something easy??
Thanks in advance.
Set your config bindings
to security mode="TransportCredentialOnly" and transport clientCredentialType="Ntlm"
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="WarehouseControlWebServiceSoap" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://tfsServer:8080/tfs/TeamFoundation/Administration/v3.0/WarehouseControlService.asmx"
binding="basicHttpBinding" bindingConfiguration="WarehouseControlWebServiceSoap"
contract="TfsWarehouse.WarehouseControlWebServiceSoap" name="WarehouseControlWebServiceSoap" />
</client>
</system.serviceModel>
You are looking in the right direction. This is a good page with some example level information on available authentication methods you need: http://man.ddvip.com/web/bsaspnetapp/LiB0087.html. At least that page should give you some more clues to continue your efforts on.
I am working on a Silverlight 4 application which connects to a claim ware WCF Service. I am using the following code to retrive the claim token in my WCF to perform authorization.
IClaimsPrincipal principal = ( IClaimsPrincipal )Thread.CurrentPrincipal;
IClaimsIdentity identity = ( IClaimsIdentity )principal.Identity;
return string.Format( "You entered: {0} and you are {1}", value, identity.Name );
When I use wsHttpBinding in WCF and try it out with a console app, it works fine. But since Silverlight only supports basicHttp and customeBinding, i cannot use wsHttp, ws2007Http or anyother binding. Becase of which I am not getting the IClaimIdentity token in my WCF from Silverlight.
Is there any way I can use any of the Silverlight suppported binding and still get the ClaimIdentity in my WCF. Is there any tutorial/help text where I can read more abouth this.
My WCF settings are:
<system.serviceModel>
<services>
<service name="ClainAwareWCF.Service" behaviorConfiguration="ClainAwareWCF.ServiceBehavior">
<endpoint address="" binding="basicHttpBinding" contract="ClainAwareWCF.IService" bindingConfiguration="basicbind">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="basicbind">
<security mode="TransportCredentialOnly"></security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ClainAwareWCF.ServiceBehavior" >
<federatedServiceHostConfiguration/>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="federatedServiceHostConfiguration" type="Microsoft.IdentityModel.Configuration.ConfigureServiceHostBehaviorExtensionElement, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</behaviorExtensions>
</extensions>
</system.serviceModel>
Trying to call this directly from the client will never happen because of the binding issues and also because the client auth awareness security of SL (Windows/Forms/WIF/etc.), but one approach is to use RIA Services Domain Authentication Services to authenticate and call the services from the server-side through a WCF RIA Invoke endpoint. The user's security context is proxied to the client and you can tunnel data over the wire in a straight-forward manner.
This may get you in the right direction:
http://archive.msdn.microsoft.com/RiaServices/Release/ProjectReleases.aspx?ReleaseId=5617
Silverlight doesn´t support Claims Based Authorization and WS-Trust out of the box. Microsoft was going to put this into Silverlight 5 but forgot to do so unfortunately.
There is however a very elegant and usable "Silverlight" version of the WIF IdentityModel stuff available in the Identity Training Kit.
The solution consists of a base AuthenticationService that translates WIF authentication tokens to claims server side, and a Silverlight client library "SL.IdentityModel" containing the building blocks such as a Silverlight version of a ClaimsPrincipal.
Get the Identity Training Kit here. Look for the sample Silverlight implementation.
I have a Silverlight 4 application that uses a WCF SOAP service. The authentication/authorization happens per call (quasi RESTful). This is done by using authenticationMode=UserNameOverTransport - this basically means that that username/password is in each WCF call, but is protected by the SSL encryption of each message. The great thing about this scheme is that I can configure a membership provider in my web.config to do the authentication, making it flexible for different installations.
I have a client that would like to set this website up on their network where the scheme is: Internet <= SSL Traffic => External facing SSL enabled forwarding server <= unsecure HTTP in their internal network => server that hosts my application. They assure me this is a common architecture and I believe them, I am not that experienced an internet application developer.
I am not sure what to do about this as my application is set up to be on the SSL enabled server (UserNameWithTransport is over SSL). in plain HTTP I am not sure how I would get the username which I need to provide the user specific application data. WCF does not provide a "UserNameWithNoTransport" authenticationMode as that would mean sending the username/password in plain text, which is silly. Right now my server side code gets the user from the ServiceSecurityContext.Current.PrimaryIdentity.Name, knowing that the web server has already taken care of the SSL encryption and user authentication. How can I have this work in a way that makes sense in an HTTP solution?
I would like a solution that allows me to configure my solution to work in both the HTTP and HTTPS situation from the web.config, if this is not possible than any other advice is appreciated. thanks
I will place a bounty on this question in a few days, if you give a good answer before then you'll get it.
EDIT: here is the web config as requested:
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<system.web>
<pages controlRenderingCompatibilityVersion="4.0" clientIDMode="AutoID"/>
<membership defaultProvider="SampleProvider">
<providers>
<add name="SampleProvider" type="MyNamespace.NullMembershipProvider, MyDLL"/>
</providers>
</membership>
</system.web>
<appSettings>
...
</appSettings>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<bindings>
<customBinding>
<binding name="BinaryCustomBinding" sendTimeout="00:10:00">
<security authenticationMode="UserNameOverTransport"/>
<binaryMessageEncoding />
<httpsTransport maxBufferSize="100000" maxReceivedMessageSize="100000" />
</binding>
</customBinding>
</bindings>
<services>
<service name="MyNamespace.MyService">
<endpoint
binding="customBinding" bindingConfiguration="BinaryCustomBinding"
name="MyService" contract="MyNamespace.IServiceContract" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata
httpsGetEnabled="true"
httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<userNameAuthentication
userNamePasswordValidationMode="MembershipProvider"
membershipProviderName="SampleProvider"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<log4net>
...
</log4net>
</configuration>
Allowing UserNameOverTransport over HTTP is possible in .NET 4 but I think it is not possible in Silverlight. You need to set allowInsecureTransport attribute of security element:
<customBinding>
<binding name="BinaryCustomBinding" sendTimeout="00:10:00">
<security authenticationMode="UserNameOverTransport" allowInsecureTranposrt="true"/>
<binaryMessageEncoding />
<httpTransport maxBufferSize="100000" maxReceivedMessageSize="100000" />
</binding>
</customBinding>
The problem is that allowInsecureTranposrt is not available in Silverlight. Without this you can't use UserName token over unsecured channel.
I have a silverlight application which has a WCF in it. when the wcf is called it fails with this exception:
An error occurred while trying to make a request to URI 'http://localhost:4693/MapService.svc'. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. This error may also be caused by using internal types in the web service proxy without using the InternalsVisibleToAttribute attribute. Please see the inner exception for more details.
Both silverlight and WCF are running from local.
My silverlight is running from:
...\SilverlightApplication1\SilverlightApplication1\Bin\Release\SilverlightApplication1TestPage.html
this is the WCF web.config services tag:
<services>
<service behaviorConfiguration="FileUpAndDownload.Web.MapServiceBehavior" name="FileUpAndDownload.Web.MapService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="MapBinding" contract="FileUpAndDownload.Web.IMapService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
and this is the ServiceReference.ClientConfig:
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IMapService" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:4693/MapService.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IMapService" contract="MapService.IMapService"
name="BasicHttpBinding_IMapService" />
</client>
</system.serviceModel>
I've placed the clientaccesspolicy.xml in bin\release but doesn't help.
HELP PLEASE!
You need some extra configuration to do a cross domain call see:http://www.dotnetcurry.com/ShowArticle.aspx?ID=208&AspxAutoDetectCookieSupport=1
You probably have the clientaccesspolicy.xml in the wrong place, check your IIS log for file not found errors.
The client access policy file must be in your wwwroot folder
There are issues with running Silverlight locally as opposed to from a web server.
The access permissions are different and Silverlight won't be able to access ANY webservice.
I ran into that issue somne time ago with SL2 I think, it might have changed.
You should create a new WebApplication project in Visual Studio and host Silverlight in it.
Then you SL client will have no problem connecting to the service.
I have an existing ASP.NET web application. This ASP.NET web application uses JQuery to provide a rich experience to the users. This user interface interacts with the server through some WCF services. A sample service looks like the following:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior(IncludeExceptionDetailInFaults = false)]
public class myService : ImyService
{
public bool SomeMethod(string parameter1, string parameter2)
{
try
{
return true;
}
catch (Exception ex)
{
return false;
}
}
}
I now want to expose this service to an iPhone and a Windows Phone 7 application. In an attempt to do this, I have configured the service like the following:
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="myServiceBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<services>
<service name="myService">
<endpoint address="" behaviorConfiguration="myServiceBehavior"
binding="webHttpBinding" contract="ImyService" />
</service>
</services>
</system.serviceModel>
The service works with the JQuery calls in my ASP.NET web application. I have not begun working on the iPhone client. But, when I try to expose this service to my WP7 client, I run into problems. As it stands now, when I launch my WP7 application, I receive an error that says:
KeyNotFoundException
If I change the binding in the config file to "basicHttpBinding", I cannot reference the service in Visual Studio. I receive an error that says:
The endpoint at 'http://machine:80/services/myService.svc' does not have a Binding with the None MessageVersion. 'System.ServiceModel.Description.WebScriptEnablingBehavior' is only intended for use with WebHttpBinding or similar bindings.
Ugh. How do I move forward? I thought WCF was designed to make this stuff easier. But I feel like I'm getting stuck doing something relatively basic.
Thank you for your help!
As far as I know (but I have no experience at all with iPhone or WinPhone development) you should be able to expose your WCF service using the regular webHttpBinding and no web script functionality, to get a normal REST style WCF service:
<system.serviceModel>
<services>
<service name="myService">
<endpoint
address=""
binding="webHttpBinding"
contract="ImyService" />
</service>
</services>
</system.serviceModel>
That alone should be sufficient - just browse to the virtual directory where your *.svc file is located and you should see your top-level resources in your browser.
The mobile devices typically don't support the SOAP-style bindings (like basicHttpBinding and so on) - so you need to use webHttpBinding instead (since that really only requires an HTTP client stack on the device - and every device these days definitely has this!)