Task based asynchronous operation disabled in PCL Service Reference setting - wcf

I'm currently building a Xamarin based mobile application. For that project, I have created a PCL project with framework 4.5. I'm using VS 2013 as the development IDE. Now I want add a WCF service reference to this PCL. While adding service reference to this PCL project, I noticed that generation of asynchronous operation is disabled. Please check the image for more detail.
I added the BCL.Async package via Nuget to the project. But still I can't access the Task based operation from the radiobutton list (its disabled).
So is there any way to generate task based asynchronous operation in service client?

Hate to break it to you but you cannot generate Task based WCF client in Xamarin. The reason is Xamarin or Mono implements the Silverlight set which is a limited WCF implementation. As such you need to use SLSVCUTIL.exe instead(Adding a service reference in Xamarin would use this tool). The silverlight WCF client generated by SLSVCUTIL will be async based only.
All is not lost! You can easily wrap the silverlight async client into a task based client using the Task.FromAsync method.
A sample taken from the Xamarin website:
public async Task<List<TodoItem>> RefreshDataAsync ()
{
...
var todoItems = await Task.Factory.FromAsync <ObservableCollection<TodoWCFService.TodoItem>> (
todoService.BeginGetTodoItems,
todoService.EndGetTodoItems,
null,
TaskCreationOptions.None);
foreach (var item in todoItems) {
Items.Add (FromWCFServiceTodoItem (item));
}
...
}
https://developer.xamarin.com/guides/xamarin-forms/web-services/consuming/wcf/
Now if someone can figure out how to catch an Fault Exception when wrapping in Tasks that would be awesome!

I've not used Xamarin before, but I'll assume APM and maybe Tasks are actually supported in it and this is just a Visual Studio limitation. Try using wsdl.exe manually to generate code. This is the tool Visual Studio calls when you add a service reference.
You'll need to pass either newAsync (Tasks) or oldAsync (APM) through the /parameters switch.

Related

.NET Core Azure servicebusqueue number of messages

I am currently working on a .NET Core project where I use the Microsoft.Azure.Servicebus version 1.0 NuGet package found here: https://github.com/Azure/azure-service-bus
The problem I have is that I haven't found any method to get a queue's number of active messages. This used to be pretty easy with .NET framework using the ServicebusNamespace.NamespaceManager, referring to a queue and use the .ActiveMessageCount.
Is this possible in some other way in this library with .NET Core 1.1?
It is now possible using the latest version of the Service Bus library (3.1.1):
using Microsoft.Azure.ServiceBus;
using Microsoft.Azure.ServiceBus.Management;
var client = new ManagementClient(connectionString);
var queue = await client.GetQueueRuntimeInfoAsync(queuePath);
var counts = queue.MessageCountDetails;
var subs = await client.GetSubscriptionRuntimeInfoAsync(topic, subscription);
var countForThisSubscription = subs.MessageCount; //// (Comes back as a Long.)
The .NET Standard client (Microsoft.Azure.ServiceBus) is deliberately not providing management operations. It states that management operations should not be performed at run time. Management operations are extremely slow.
Is this possible in some other way in this library with .NET Core 1.1?
Yes, it is possible.
Instead of the NamespaceManager that was available with the old client (WindowsAzure.ServiceBus), there's a ServiceBus management library (Microsoft.Azure.Management.ServiceBus.Fluent)
You will need to do the following:
Authenticate using ServiceBusManager
Access the namespace you're interested in via ServiceBusManager.Namespaces
Filter out the entity you're interested in by locating it under ServiceBusManager.Namespaces.Queues/ServiceBusManager.Namespaces.Topics. For subscription you'll need to locate one via ITopic object.
Once you've got your entity (IQueue, ITopic, or ISubscription), you'll be able to access the message counts.
I'm not a big fan of this approach. Rather than each developer reinventing this wheel, Azure Service Bus team should have provided a helper library to replace NamespaceManger. You can always raise an issue or vote for an issue that was closed.
Management operations were introduced back in version 3.1.1 with pull request #481.

Message headers sent on webservice calls on portable libraries (PCL)

I'm trying to move all the calls I make to webservices to an Portable Class Library (PCL) that I've just created to organize and reuse my code. The frameworks I'm targeting to are .NET for Windows Store apps; .NET Framework 4.5; Silverlight 4 and higher and WP7 and higher.
On my Win RT project I've been setting up the message headers by implementing the IClientMessageInspector interface available in the namespace System.ServiceModel.Dispatcher. But on my PCL project that interface as well as System.ServiceModel.Description.IEndpointBehavior are not available.
So I need to find out how to attach a message header / service header to my service calls from a PCL project with those targeted frameworks. Anyone has experience and/or suggestions that I should try?
Update
Just for adding more info, I've tried to create a WP8 project now and noticed that those interfaces are not available for it either. So IClientMessageInspector and IEndpointBehavior are probably not available for my PCL project because it is targeting WP8 which misses them itself.
You should be able to scope the OperationContext to the current client channel you want to work with:
using(var scope = new OperationContextScope(_client.InnerChannel)){
//More to come
}
Now that you have the operation context created for your client channel, you can add outgoing message headers:
using(var scope = new OperationContextScope(_client.InnerChannel)){
var header = MessageHeader.CreateHeader("x-client-type", "http://www.myapp.com", "WP8");
OperationContext.Current.OutgoingMessageHeaders.Add(header);
//Send message to server
}
After that, you should be able to get the header using the IncomingMessageHeaders property of the OperationContext.Current.
These are all core pieces of WCF services, so it should be available (hopefully).
Mono does have support for WCF services, but you would have to check on what they have implemented. EG: Perhaps they don't have MessageHeader.Create and you would have to use var header = new MessageHeader<string>("x-client-type"); and var untypedHeader = header.GetUntypedHeader("x-client-type", "http://www.myapp.com"); instead to create your header to add.

Does Microsoft.Data.Services.Client caches data?

We were using the System.Data.Services.Client (version 4 I guess) of Microsoft WCF Data Services. When we updated to the version 5.2 (Microsoft.Data.Services.Client dll), it seems that some caching mechanism has been inserted into the new version of WCF Data Services.
Because when we query the data services (OData) through browser, fresh data would be returned, but when we add a service reference to our UI project and use that reference (proxy) to retrieve data, only after 10 minutes or so the fresh data would be shown.
By resetting IIS (iisreset.exe) fresh data would be available, which probably means that somewhere in UI project a caching should be in place.
We don't do something extraordinary in our code, but using OData service reference in its most simple state:
public List<Customer> GetCustomers()
{
CustomersODataModel customersData = new CustomersODataModel("Url");
return customersData.ToList();
}
Consider disabling client side caching in the DataService object and see if that helps. I had the same problem and setting dataService.MergeOption to MergeOption = MergeOption.OverwriteChanges helped keep the data service refreshing the obejct on each change and get.

Can I create a WCF workflow using the standard Workflow activity templates?

Is it possible to create a WCF workflow using the standard (Activity template) Workflow activity templates? And, if so, where can I find some samples that DO NOT use the standard WCF service template (WCF Workflow Service template)?
Explanation: I'm trying to discover, load and run workflows at runtime, including workflows with WCF activities. Standard workflows get compiled into types (which makes them easy to discover), however the "WCF Workflow Service" template is an xamlx file, which is added as content and loaded as a manifest stream at runtime. This makes discovery at runtime difficult.
I don't think it is a requirement to use this template to create a service, as the WorkflowServiceHost can take an Activity in its constructor.
I'm trying to keep the task of developing a new WCF service to be discovered, loaded and "executed" (i.e., loaded and listening) at runtime as streamlined as possible.
I have been trying to figure out the same since yesterday and now I stumbled upon a workaround. There is no template for simple workflow (xaml) in VS 2010 when adding new item. If you create a WCF WF Application, you get xamlx. I created a Workflow Console application instead, that gave me a xaml file which I copied to my working project. Once this was done, hosting was simple using WorkflowServiceHost.
string uri = "http://localhost:8008/MyService";
WorkflowServiceHost wsh = new WorkflowServiceHost(new Workflow1(), new Uri(uri));
ServiceMetadataBehavior metadataBehavior = new ServiceMetadataBehavior();
metadataBehavior.HttpGetEnabled = true;
wsh.Description.Behaviors.Add(metadataBehavior);
wsh.AddServiceEndpoint("IService", new BasicHttpBinding(), uri);
wsh.Open();
Yes it is.
This blog post describes how to use an SVC extension instead of a XAMLX and uses a compiles workflow to do so. The comments add some details how to get rid of the SVC file as well. You need to use the WorkflowServiceHostFactory as the Factory to wire things up. You can also do something similar when self hosting.
Actually I just figured out that "Activity" template in add new item is xaml so no need to create that "Workflow console application" to get a xaml file.

Silverlight and WCF: Handle 'WCF down' exception / WCF connection check

Inside my Silverlight app, I'm calling a web service asynchronously, using the client generated for me by Visual Studio (Add Service Reference...).
My code looks like this:
ServiceClient serviceClient = new ServiceClient();
serviceClient.GetServerTimeCompleted += new EventHandler<GetServerTimeCompletedEventArgs>(serviceClient_GetServerTimeCompleted);
serviceClient.GetServerTimeAsync();
void serviceClient_GetServerTimeCompleted(object sender, GetServerTimeCompletedEventArgs e)
{
// do nothing atm
}
Everything works fine as long as the service is up and running, but when the service isn't running, i get:
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
"An exception occurred during the
operation, making the result invalid.
Check InnerException for exception
details."
InnerException
"An error occurred while trying to
make a request to URI
'http://'. 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."
It makes sense that I get an exception under these circumstances, but what I can't figure out is how to catch the exception in my client code. Is there a standard way to do this? If I understand how this is working, when my code calls the generated code, it spawns another thread that actually calls the web service and waits for the response. The exception is in that thread and in the generated code. Neither my calling code (see above) or my callback method have the opportunity to see the exception.
Thanks
Christian
There are a number of reasons not to use the "Add Service Reference" functionality in Visual Studio. Here's a good (and long) article on the issues, and how to use WCF creating your clients. I'm working through these issues myself, right now.
Among the concerns about "Add Service Reference" include code bloat in the downloadable client .XAP file, difficulty in maintaining generated code, difficulty in staging or shipping code when the server addresses and ports are hard-coded in the client config file (also embedded in the .XAP), and lots more. Building your own clients will also give you better capability to manage exceptions in client code.
There are some tradeoffs; you'll need to make your data contract classes portable to the Silverlight environment. (You can't just add a reference to a server-side .NET assembly; it doesn't work.) There same site linked above has a good article on re-using assemblies in Silverlight, but probably the easiest way to deal with this is to add links to your server-side classes from your Silverlight project. (In the Silverlight project, right-click and Add -> Add existing item... and find the item you want to include, but instead of clicking on the Add button, click the down-arrow beside it and click on "Add as Link".) Watch out for other references and using statements that refer to server-side classes; you may need to do conditional compiles so that your data contract classes compile cleanly in the client-side project.
Overall, it really looks like a cleaner way to go, especially for large projects that may use lots of service contracts and data contracts, or where you need to ship your Silverlight projects as part of a commercial application that runs on other people's servers. It should also be a lot cleaner for testability, especially for integration and staging testing.
I have encountered this problem before - you need to add exception handling code around your ServiceClient setup code. I typically check for the following CommunicationException, TimeoutException, and EndpointNotFoundException and provide the user with an appropriate dialog telling them something is broken:
ServiceClient serviceClient;
try
{
serviceClient = new ServiceClient();
serviceClient.GetServerTimeCompleted += new EventHandler<GetServerTimeCompletedEventArgs>(serviceClient_GetServerTimeCompleted);
serviceClient.GetServerTimeAsync();
}
catch (EndpointNotFoundException ex)
{
// log exception
// show error dialog
}
Note: this will not handle errors encountered during the asnchronous method callback - it will need it's own (similar) exception handling.
Actually you have to put crossdomainaccesspolicy.xml in IIS default website root folder.
you copy the given below xml content and save in the name of ClinetAccespolicy.xml and then put on the IIS default website root folder.