I have, without any luck, been googling for some time now trying to find out how a WCF service reacts to null values - both directly as in the actual parameter of the service method is set to null; as well indirectly: any property of the parameter (DataContract-annotated object) is null.
Should my service perform null checks on any property value it accesses or is this somehow implicit? In case my service method performs a call on a null-property, will this simply result in a FaultException (without any information on what went wrong) being passed to the client?
Regards
I turned on error reporting in my service configuration to return useful error information to the client:
<behaviors>
<serviceBehaviors>
<behavior name="errorEnabledBehavior">
<serviceDebug includeExceptionDetailInFaults="true"/> <!-- THIS IS IT! -->
</behavior>
</serviceBehaviors>
</behaviors>
Make sure to use this behavior in your service definition
<service behaviorConfiguration="errorEnabledBehavior" ...>
EDIT
I'm using this in a local environment where I log errors on the server side anyway including a full stack trace. As the OP mentioned in his comment, passing this information to the client may be dangerous and should not be used in a production environment. Another solution would be to use a custom fault contract as described here.
Related
I have an ASP.NET application calling a WCF service.
In ASP.NET application, I make a call to ADFS to perform authentication and I can see all the claims of the user in CurrentPrincipal. Then I perform the call of the WCF service (wsHttpBinding), but the list of claims is empty.
What could be the reason?
If I'am not mistake there different ways to get Claims in WCF.
Thread.CurrentPrincipal - Simple and easy to used but need some setting in your configuration, which is most neglected.
<behaviors>
<serviceBehaviors>
<behavior name="Test.Services.WifBehavior">
<serviceCredentials useIdentityConfiguration="true" />
<!---Set principalPermissionMode to always to pass the ClaimsIdentity info to the Thread.CurrentPrincipal-->
<serviceAuthorization principalPermissionMode="Always"/>
</behavior>
<serviceBehaviors>
</behaviors>
OperationContext.Current.ClaimsPrincipal - I can't remember if this needs some configuration but I guess you can get it directly from method invoked.
OperationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets - Create a Custom Authorization Manager for a Service and need to add in config.
Note that I used Windows Identity Foundation (WIF).
I have OpenRIA WCF Service hosted within an asp.net website. I have a WPF client that connects to the Authentiction and DomainService. I am having trouble calling the Login method. It basically does not like that the message parameters are not "Wrapped". See the error message below
An unhandled exception of type 'System.InvalidOperationException' occurred in OpenRiaServices.DomainServices.Client.dll Additional information: Operation 'Login' of contract 'IPatientAuthenticationDomainServiceContract' specifies multiple request body parameters to be serialized without any wrapper elements. At most one body parameter can be serialized without wrapper elements. Either remove the extra body parameters or set the BodyStyle property on the WebGetAttribute/WebInvokeAttribute to Wrapped. On the client side, The WebHttpBehavior in domainClient.ChannelFactory.Endpoint.EndpointBehaviors has DefaultBodyStyle = Wrapped
The asp.net project that's hosting the OpenRIA services has web behavior set to Wrapped.
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp defaultBodyStyle="Wrapped"/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
What could I be missing? Has anyone encountered this issue?
A possible workaround is to change the method parameters to accept a complex type but I do not have control over the Login method of the AuthenticationService. It is part of a base class that RIA framework provides.
Thanks,
Ankur
Issue resolved. Just wanted to share the fix. I am using SharedCookieContainer that Kyle McClellan wrote for sharing cookie between Auth service and Domain service when not using an in-browser client. See http://blogs.msdn.com/b/kylemc/archive/2010/05/14/ria-services-authentication-out-of-browser.aspx
The SharedCookieBehavior in this code is an extension of WebHttpBehavior. This class needs to have the DefaultBodyStyle set to Wrapped when its newed up. Simple fix but took me a while to figure out.
Thanks,
Ankur
I have a fairly standard WCF service (hosted on IIS7) which generates a fairly standard WSDL when queried with ?wsdl:
<wsdl:definitions>
<!-- ... -->
<wsdl:service>
<wsdl:port>
<soap:address location="https://machine/virtual_dir/servicename.svc"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
(boring bits omitted)
I'm after a quick 'n dirty way to change the address given in this generated WSDL to something completely different, for example:
https://othermachine/other_dir/other_service.svc
What is the easiest way of doing this?
There are several approaches you could look at:
WCF supports a lot of extensibility points, and the generation of the WSDL is one of those. You could write your own custom WSDL generator and plug it into WCF
the probably easier way would be to generate the WSDL you have, then tweak it manually, and put that WSDL file somewhere and configure it to be served up (instead of WCF generating the WSDL at runtime, when requested to do so)
You can configure option #2 with the <serviceMetadata> behavior:
<behaviors>
<serviceBehaviors>
<behavior name="StaticMetadata">
<serviceMetadata httpGetEnabled="true"
externalMetadataLocation="(url path to your static WSDL file)" />
</behavior>
</serviceBehaviors>
</behaviors>
If you do this, and your service uses this service behavior, any requests for the WSDL or for MEX data will be routed to that static WSDL you've provided, instead of using the auto-generated WSDL that WCF would normally supply.
I have created a WCF service, now this WCF service has to call a Web Service. What I am doing is adding the service reference of web service in WCF and calling the method of the web service which I want to use.
Just an example shown below :
CalcWebReference.CalculatorSoapClient fct =
new CalcWebReference.CalculatorSoapClient();
int rq = fct.Add(q, r);
return rq;
Now this method when I tried to call from the client it is giving following error
The server was unable to process the
request due to an internal error. For
more information about the error,
either turn on
IncludeExceptionDetailInFaults (either
from ServiceBehaviorAttribute or from
the configuration
behavior) on the server in order to
send the exception information back to
the client, or turn on tracing as per
the Microsoft .NET Framework 3.0 SDK
documentation and inspect the server
trace logs.
Thanks i did what u told but now i am getting following error "Could not find default endpoint element that references contract 'CalcWebReference.CalculatorSoap' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element."
Now do i need to give some end points in the WCF service or in the web service to get the function from web service and if so then how do i give it.
Please help.
Hi,
CalcWebReference.CalculatorSoapClient is reffering to the web service not WCF.
Given below is the code written in WCF(sample code) which is calling the web service :-
CalcWebReference.CalculatorSoapClient fct = new CalcWebReference.CalculatorSoapClient();
int rq = fct.Add(12, 10);
return rq;
Am i not putting the syntax right or is there any additional thing that i need to do in this?
This is the generic WCF "something bad happened" error message. That won't really be much help.
Approaches:
make sure the web service you're calling works on its own - otherwise fix it!
enable the detailed error information, as described in the error message, by including the error details in your WCF service (do this in DEV environments only! Never in production...)
try to launch your WCF service inside Visual Studio and debug what's happening
In order to enable detailed error reporting, you need to add this section to your WCF service's configuration:
<behaviors>
<serviceBehaviors>
<behavior name="DebugBehavior">
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
You might already have a service behavior configured - in that case, just add the <serviceDebug> tag to your service behavior.
If you don't have a service config yet - you'll also need to make sure your service actually uses that service config:
<service name="YourServiceNameHere"
behaviorConfiguration="DebugBehavior">
Make sure to have a behaviorConfiguration= attribute on your <service> tag, and make sure to reference that defined service behavior (by specifying its <behavior name="..." > property).
Once you've done that, your error should hopefully give you more information - you should definitely get an .InnerException on your exception that should point you in the right direction.
What is the best approach to make sure you only need to authenticate once when using an API built on WCF?
My current bindings and behaviors are listed below
<bindings>
<wsHttpBinding>
<binding name="wsHttp">
<security mode="TransportWithMessageCredential">
<transport/>
<message clientCredentialType="UserName" negotiateServiceCredential="false" establishSecurityContext="true"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="NorthwindBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceAuthorization principalPermissionMode="UseAspNetRoles"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="MembershipProvider"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
Next is what I am using in my client app to authenticate (currently I must do this everytime I want to make a call into WCF)
Dim client As ProductServiceClient = New ProductServiceClient("wsHttpProductService")
client.ClientCredentials.UserName.UserName = "foo"
client.ClientCredentials.UserName.Password = "bar"
Dim ProductList As List(Of Product) = client.GetProducts()
What I would like to do is auth w/ the API once using these credentials, then get some type of token for the period of time my client application is using the web service project. I thought establishsecuritycontext=true did this for me?
If you're on an intranet, Windows authentication can be handled for "free" by configuration alone.
If this isn't appropriate, token services work just fine, but for some situations they may be just too much.
The application I'm working on needed bare-bones authentication. Our server and client run inside a (very secure) intranet, so we didn't care too much for the requirement to use an X.509 certificate to encrypt the communication, which is required if you're using username authentication.
So we added a custom behavior to the client that adds the username and (encrypted) password to the message headers, and another custom behavior on the server that verifies them.
All very simple, required no changes to the client side service access layer or the service contract implementation. And as it's all done by configuration, if and when we need to move to something a little stronger it'll be easy to migrate.
While I hate to give an answer I'm not 100% certain of, the lack of responses so far makes me think a potentially correct answer might be okay in this case.
As far as I'm aware there isn't the kind of session token mechanism you're looking for out-of-the-box with WCF which means you're going to have to do some heavy lifting to get things working in the way you want. I should make it clear there is a session mechanism in WCF but it's focused on guaranteeing message orders and is not the ideal tool for creating an authentication session.
I just finished working on a project where we implemented our own session mechanism to handle all manner of legacy SOAP stacks, but I believe the recommended way to implement authenticated sessions is to use a Secure Token Service (STS) like Pablo Cibraro's.
If you want more details please shout, but I suspect Pablo's blog will have more than enough info for you to steam ahead.