What operation contract can I put for my WCF service? - wcf

I am currently developing a C# Windows Form Application that I intend to let it interact with a server. The server will receive posting from a mobile application that I have developed and whenever a posting is received, my Windows Form Application should be notified and give me a notification. And for now I am starting to create a WCF service for it.
This is a sample scenario of what I meant,
E.g. My mobile application sends an message over to my server. Once my server receives the message, my windows form application should display a new notification showing the content of the message received.
so for the operationcontract of the service, what type of methods should i put in in order for me to receive the posting?
e.g.
[OperationContract]
bool receivePosting(int n);

I'm not quite clear as to which direction you want to communicate:
your "server" needs to notify the Winforms app of a new posting that's been saved?
or:
your Winforms app asks the "server" about new postings??
I put "server" in quotes because in WCF world, that's a term being used for a specific role.
Assuming the first option, you need to do this:
your Winforms app needs to be the WCF server - e.g. it needs to define a service contract, operation contract and data contract - and implement those
your "posting server" would be the WCF client in this case; whenever a posting is received/stored, then you would call the WCF service in your Winforms app to send a notification (so really, in this setup, your roles are reserved - the Winforms app is the WCF server)
As for the operation contract - what does your Winforms app need to know about the new posting? Just the fact a new posting has been received? The whole contents of the posting, or just parts of it??
In any case, you need to define a method on your WCF service that the "posting server" can call and pass all relevant info to the Winforms WCF Server - you don't want to have to make two or more calls just for one notification.
So you Service Contract might be:
[ServiceContract]
public interface IPostingService
{
[OperationContract]
void NotifyAboutPosting(Posting post);
}
and your Posting class would be the data contract:
[DataContract]
public class Posting
{
[DataMember]
public int ID { get; set; }
[DataMember]
public string Description { get; set; }
[DataMember]
public DateTime PostingTimestamp { get; set; }
}
Whatever you need to send between those two parties - define it in your data contract which is the argument to your service call

Related

Client's method description for WCF service

I have a WCF service (hosted in windows-service) and a client for it.
They interact as follows: client sends a request, service gets it and returns HTTP 200. Also client passes its address for the answer in the WS-Addressing header. For the moment that's all
After a few hours windows-service should send a result for that request. Client has a web-method that will get the result. So the question is: where should be a description (name of the method, its parameters) for the client's method that will get the result? Should the client expose its WSDL, or should I put that description in my WSDL (if it works that way)?
As I understand your scenario, you have two services, let's call them Service A (hosted in a Windows Service) and Service B. Service B sends a request to Service A (in other words, it's acting like a client) to have Service A start a long-running task of some sort.
When the task is complete, Service A needs to send the results to Service B. Since it's a long-running task, using a duplex binding would not be ideal. However, Service A could call a method exposed by Service B to send the results.
Something like this:
[ServiceContract]
public interface IServiceA
{
[OperationContract]
public void StartWork();
}
[ServiceContract]
public interface IServiceB
{
[OperationContract]
public void ReceiveResults(ResultData data);
}
where ResultData is some object containing the results (could be a simple type as well, this is simply for illustration). ServiceA's StartWork can return void (the response will still be sent to the client, since it's not marked as IsOneWay=true). Semi-pseduo code follows:
Start the task:
ServiceAClient client = new ServiceAClient();
client.Open();
client.StartWork();
client.Close();
Service A sends the results to Service B when the task is complete:
ResultData results = new ResultData();
ServiceBClient client = new ServiceBClient();
client.Open();
client.ReceiveResults(results);
client.Close();
In this case, the method to receive the results will be part of Service B's WSDL, as Service A will call that method.

consuming wcf service secured by adfs in windows phone application

I have a wcf service secured by ADFS deployed in azure. I am able to consume that service in my console application. But when I am not sure how to consume that service in windows phone 7 application.
In my console application, I am retrieving a security token and passing that token to channelfactory object using CreateChannelWithIssuedToken method. But there is no such method in windows phone app to pass the token to wcf service. Can anyone guide me in this issue?
Thanks in advance.
CreateChannelWithIssuedToken was an extension method added by the WIF assembly in .NET 3.5/4.0 (I believe .NET 4.5 has most of this stuff now built-in to the System.ServiceModel namespace). Since you won't have this on the phone, you're stuck with the regular WCF methods to create and use channels.
This is still the case when working on WinForms/WPF apps, though in that case you have the option of bringing in the WIF assembly. Still, it isn't required, and consuming an ADFS-secured service is perfectly doable with the regular WCF classes.
Windows Phone seems to support this stuff, though with some caveats. Looking at the implementation of the extension method, it doesn't seem like they are doing anything all that fancy really:
public static T CreateChannelWithIssuedToken<T>(this ChannelFactory<T> factory, SecurityToken issuedToken)
{
return ChannelFactoryOperations.CreateChannelWithParameters<T>(factory, new FederatedClientCredentialsParameters
{
IssuedSecurityToken = issuedToken
});
}
public static T CreateChannelWithParameters<T>(ChannelFactory<T> factory, FederatedClientCredentialsParameters parameters)
{
ChannelFactoryOperations.VerifyChannelFactory<T>(factory);
T t = factory.CreateChannel();
((IChannel)t).GetProperty<ChannelParameterCollection>().Add(parameters);
return t;
}
The verify method simply performs some diagnostics and throws exceptions (such as if the endpoint isn't set). ChannelParameterCollection is defined in System.ServiceModel.Channels and is supported in Silverlight/WP7. And FederatedClientCredentialsParameters is nothing special either:
public class FederatedClientCredentialsParameters
{
public SecurityToken ActAs ( get; set; )
public SecurityToken OnBehalfOf ( get; set; )
public SecurityToken IssuedSecurityToken ( get; set; )
}
It seems like you should be able to create a channel and use your token with it normally, even from WP7, though I'm afraid I don't have the exact steps to do so. Maybe someone else does or maybe this leads you in the right direction.
This article shows how to access a WIF-protected WCF service from Silverlight, which I imagine is nearly identical to how you'd do it on the phone.
There is a training kit (http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=8396) example ACSAndWindowsPhone7 that may help here (I've not looked at it in detail). I know that Wade Wegner has a number of blog posts on ACS and WP7, but not sure if he's tackled ADFS specifically versus OAuth type mechanisms.

WF4 Services and WIF Integration

Are there proven patterns that anyone could share regarding Workflow 4.0 services integrated with Windows Identity Foundation? We are looking for the best way to inspect the STS token and claims in order to derive who the user is outside the workflow service instance context and make the application's user object available to the workflow context.
We want to maintain separation of concerns between the service implementation of WIF and workflow business logic so our workflow services are highly testable. We have seen a few examples provided which point to wrapping the Receive activity with a code activity that instantiates an implementation of IReceiveMessageCallback in order to get a reference to the OperationContext. Link to Maurice's Blog Post. However, this means activities internal to the service are dependent on the existence of the operation context and possibly even the IClaimsIdentity.
The best solution we can come up with so far is to create an implementation of IDispatchMessageInspector for the service that interrogates the token and creates the application user objects needed by the workflow making them available to the workflow runtime via InstanceContext.Extensions. This seems to work but doesn't feel exactly solid. Any help or feedback is greatly appreciated!
Service Behavior
public class SecurityTokenServiceBehavior : IServiceBehavior, IDispatchMessageInspector
{
...
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
var claimsPrincipal = (IClaimsPrincipal)(Thread.CurrentPrincipal is GenericPrincipal ? null : Thread.CurrentPrincipal);
...
instanceContext.Extensions.Add(new SecurityContextExtension(appUser, audit));
return null;
}
...
}
IReceiveMessageCallback
public class SecurityContextCallback : IReceiveMessageCallback
{
[DataMember]
public SecurityContextExtension SecurityContext { get; private set; }
public void OnReceiveMessage(OperationContext operationContext, ExecutionProperties activityExecutionProperties)
{
SecurityContext = operationContext.InstanceContext.Extensions.Find<SecurityContextExtension>();
}
}
Did you see this blog post about using the ClaimsAuthorizationManager as well? Using the ClaimsAuthorizationManager is the usual way to check for authorization when using WIF.
See Dominick post here for some example on how to embed checks in your code using either the ClaimsAuthorize attribute or the static ClaimsAuthorize.CheckAccess() method. You might also want to take a look at the WF Security Pack CTP 1 here.

WCF with .Net and other clients?

What is a good way to create a WCF service layer so that a native .Net client application and other client types can talk to the service?
I know, in the future our applicaiton will need to support mobile devices.
We are passing objects into our WCF methods similar to this:
[DataContract]
public class User: DomainBase
{
[DataMember]
public string Username { get; set; }
[DataMember]
public string Password { get; set; }
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
}
So there may be a method in our servcie like this:
public bool Save(User item){
...do some work
}
public User GetUserByUsernameAndPassword(string username, string password){
...do some work
}
Now, in .Net I can use the same object library as my services, but with other clients I will not be able to. So, if I don't want to write a bunch of differnt methods for each type of client what would be the best way to handle this?
I think interoperability with other clients is more dependent on the binding that the actual contracts. If the other clients and client languages that you will support can do SOAP, then sticking with the BasicHttpBinding provides the best support. For example clients using .NET 2 can still interact with a .NET 3.5 WCF server. There area also SOAP libraries for Java and other languages.
The server can just publish the WSDL, and the clients can then generate all your contract interfaces and types automatically in whatever language from the WSDL. That handles the 'reuse' of your data contract types.
If you want to venture away from SOAP, there are ways to do REST or Plain-old-XML or JSON with WCF, but it gets a lot more complicated from the server side...
What you have now should work perfectly for any other client. What leads you to believe there might be a problem?
It depends on which binding you choose to support. Certain bindings only work with .NET.
BasicHttpBinding: SOAP over HTTP. Any SOAP client can connect
WsHttpBinding: - It is same like
BasicHttpBinding. In short, it uses
SOAP over HTTP. But with it also
supports reliable message transfer,
security and transaction. WS-Reliable
Messaging, security with WS-Security,
and transactions with WS-Atomic
Transaction supports reliable
message.
NetTcpBinding: - This
binding sends binary-encoded SOAP,
including support for reliable
message transfer, security, and
transactions, directly over TCP. The
biggest disadvantage of NetTcpBinding
is that both server and client should
be also made in .NET language.
NetNamedPipesBinding:-Ths binding
Sends binary-encoded SOAP over named
pipes. This binding is only usable
for WCF-to-WCF communication between
processes on the same Windows-based
machine.

Can I use an interface as a type in my WCF client code?

I'm working on a Windows Phone 7 app using WCF for communications with my server.
I've created a service and am able to communicate well, but I'm having trouble accessing an interface in the client code.
For instance, in my server code I have something like this:
[OperationContract]
[ServiceKnownType(typeof(IField))]
[ServiceKnownType(typeof(TextField))]
[ServiceKnownType(typeof(NumberField))]
FieldForm GetForm();
Now my FieldForm contains the following declaration:
[DataContract]
class FieldForm
{
public List<IField> Fields { get; set; }
}
And finally, this IField interface has a few implementations:
interface IField
{
string Name { get; set; }
}
[DataContract]
class TextField : IField
{
}
[DataContract]
class NumberField : IField
{
}
(this isn't my code, but describes what I'm trying to accomplish)
Now on my client, I receive a FieldForm object via WCF and want to iterate through the Fields list to determine what UI elements to create. Problem is, the service did not provide the IField interface on the client, but I do have the implementations available (TextField and NumberField).
This leads to some crappy code in my client code like:
foreach ( object field in Fields )
{
if ( field is TextField )
// do textfieldy stuff
else if (field is NumberField)
// do numberfieldy stuff
}
when I'd really prefer to just use:
foreach ( IField field in Fields )
{
field.Name;
}
Am I missing a simple annotation on the interface in order to make the interface type available on the client, or does WCF simply not provide the ability to serialize interfaces?
Is there a way I can access my interface in my client code?
No you cannot serialize an interface across a WCF connection.
WCF uses serialized (XML) messages to communicate between client and server - all you can express in XML schema (XSD) can be moved across. This basically means any concrete type, composed of atomic types like int, string, etc.. XSD also supports inheritance and enums, but that's about the end of the flagpole.
What you might be able to do if you control both ends of the communications link (e.g. both server and client) is to put those interfaces (service interfaces and your data contracts and interfaces) into a common, shared assembly which both your client project and server project would then reference. Use any class implementing your interface in the concrete service implementation, but with this assembly sharing, you can use the signature you like on the client side and program against an interface. Mind you: this "kills" all interoperability of your WCF service - no Ruby or Java clients will be able to call your service anymore.