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.
Related
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.
Need help on an issue I am having. I inherited this WCF RIA project and am trying to understand a couple of things.
When I publish the project, how does the WSDL get generated and put on the URL that I published to?
And I want to incorporate FaultException handling so as to transmit the exceptions to the client side. I read some stuff regarding the FaultException on the web and was able to get a small sample working with the regular WCF service.
I thought it would be similar within my actual project. But unfortunately I am running into some issues(probably due to my lack of WCF + RIA services knowledge).
So in my actual project my Context class derives off of LinqToEntitiesDomainService.
I created a new ContextFaultException class which had some methods to capture some custom error messaging.
Then I applied the [FaultContract(typeof(ContextFaultException))] to some of the methods in my Context class. Everything compiles and all is fine. But when I published to a website and then when I added this service reference to the client, I don't see my new ContextFaultException in the Reference.cs file that's generated.
I thought may be moving it within the Context class will solve the issue. So I made my ContextFaultException class as an inner class of this Context class but I am running into some other issues. Before I try to figure out these issues, I just want to know if this the right approach?
Any suggestions/pointers??
TIA
The URL must be formatted to get to the namespace wdsl
for example:
namespace My.Namespace.Services
{
[EnableClientAccess()]
public partial class MyClassName : LinqToEntitiesDomainService<XXX>
{
....
}
}
Then use the following pattern for the url
http://YOURHOST/APP/Services/My-Namespace-Services-MyClassName.svc?wsdl
Use "-" for the "."
I am new to Web Api world and I see a lot of potential for in the new MVC 4 Web Api. I have generated a WCF Web Service but was planning to get to know Web-APIs and their web service capabilities. Now, is MVC 4 Web-Api Service more as front end? I wrote a sample Service by following some examples online in MVC 4 Web Api but how do I consume the Service in just a basic console app? I have figured out the only way to consume it is by using HttpClient are there other ways? I am used to ASP.NET Web Service and WCF Web Service as where you reference it as a service in your references and then you are able to see all of its objects, properties to make appropriate calls.
What happens if web-api is requesting a object "Task" for post method as an example how am I able to fill an object "Task" and post it back to the web-api? As in WCF I am able to see that "Task" object and its properties because of WSDL so I am able to fill them and send it back to the service how is that done in web-api service?
The webservice would be used internally is it worth it to have an web-api service?
Thank you so much for helping clearing some question of what I have about web-api services.
---Edit as per Comment---
This screenshot shows a possible structure which you can approach. Of course, you can take a design that best suit your application.
So ControllerLib is a separate Class Library project which is brought into the main project as a Service Reference (which is not shown in the screenshot but should be inside the References folder of the SecondMVCApplication project). The two controller file (HomeController.cs and LocationController.cs is a controller file that implemented the Controller class, which is the same thing as a Controller file when you create a new MVC4 application using the template)
So for your question regarding if there is a SVC file. NO. In MVC 4, there is no such thing as a SVC file whether the application is one project or a combination of multiple project (unless I am mistaken). Inside the SecondMVCApplication, there is a file called RouteConfig.cs which holds the routing URL and as long as you add the Service Reference and there controller function exists. The code will run. Also the sample screenshot I showed also includes a WebApiConfig.cs file. You can use that file to do API stuff for mobile if you need. So, the regular RouteConfig.cs handles website request and the WebApiConfig.cs handles API request.
Good to Note: If you are using a Model project as a separate project (which I know you will as it is a M-V-C project...DUH!!). Make sure you put your connection string inside the web.config main project (in this case, the SecondMVCApplication). I remember I was stuck in this problem for 3 days (8 hours each) trying to fix this problem. Hope you don't run into it.
---End Edit---
The following answer to your question is mostly based on my knowledge and may or may not be true to all users.
Is MVC 4 Web-Api Service more as front end?
This depends on how you look at it. Typically, a Web-API service is more suited for creating back-end service to provide a data payload to different platforms, like mobile, desktop apps and so on. However, a MVC4 Internet Application will have front-end aspects in them, namely the Views, which end-users sees.
How do I consume the Service in just a basic console app?
AFAIK, there is two way to do this. One if to consume the APIs as a Service Reference. Another is to use HTTP operation (which I will mention in your question regarding the HTTP client and reserve this answer using the Service Reference method).
This depends on how your application is done. Like I said, if it is a website, your MVC pattern will not need to do anything, but the Models, Views and Controllers all are designed to work together without using any service.
Although, as I mentioned in the comments to the questions, if it is a big application then you will need to break them into different projects that will make the app modular and nimble. So you will end up creating different Service Library. If you go down the Service Library road, then you just make use of the Add Reference option to bring in your API/Projects/Whatever-you-call-it into the project. (For this, I normally put all project inside a single solution and let Visual Studio manage the build order as I am lazy to write up a build script).
Similarly, the same logic could be applied when consuming your web service in a console app.
I have figured out the only way to consume it is by using HttpClient are there other ways?
One way to consume web APIs is using HTTP. Are you aware of how to write http request headers and handle http response. If so, this is the second way I mentioned. You call the web service through it's URL and then get the data and do whatever work. If your answer to use http in console app is NO, then look at this post: Create HTTP post request and receive response using C# console application
What happens if web-api is requesting a object "Task" for post method as an example how am I able to fill an object "Task" and post it back to the web-api?
I think I indirectly answered this in your previous answer (assuming you are going to take the HTTP road). If not, then comment and I'll see if I can find some resource for you.
The webservice would be used internally is it worth it to have an web-api service?
I sort of answered this in the comment to the question. Ask if you need clarification.
Hope all this helps.
you can create your own Client Service class that will serve for every request.
public class ClientService
{
#region async helper methods
private static string m_mediaTypeHeaderValue= "application/json";
static HttpClient client = new HttpClient();
static HttpClient createHttpClientInstance()
{
return client ?? new HttpClient();
}
// SELECT
internal static async Task<T> Get<T>(string endpoint)
{
client= createHttpClientInstance();
var response = await client.GetAsync(endpoint);
string content = await response.Content.ReadAsStringAsync();
return await Task.Run(() => JsonConvert.DeserializeObject<T>(content));
}
// INSERT
static async Task<T> Post<T>(string endpoint, object data)
{
client = createHttpClientInstance();
var httpContent = new StringContent(JsonConvert.SerializeObject(data));
httpContent.Headers.ContentType = new MediaTypeHeaderValue(m_mediaTypeHeaderValue);
var response = await client.PostAsync(endpoint, httpContent);
string content = await response.Content.ReadAsStringAsync();
return await Task.Run(() => JsonConvert.DeserializeObject<T>(content));
}
// UPDATE
static async Task<T> Put<T>(string endpoint, object data)
{
client = createHttpClientInstance();
var httpContent = new StringContent(JsonConvert.SerializeObject(data));
httpContent.Headers.ContentType = new MediaTypeHeaderValue(m_mediaTypeHeaderValue);
var response = await client.PutAsync(endpoint, httpContent);
string content = await response.Content.ReadAsStringAsync();
return await Task.Run(() => JsonConvert.DeserializeObject<T>(content));
}
// DELETE
static async Task<T> Delete<T>(string endpoint)
{
client = createHttpClientInstance();
var response = await client.DeleteAsync(endpoint);
string content = await response.Content.ReadAsStringAsync();
return await Task.Run(() => JsonConvert.DeserializeObject<T>(content));
}
#endregion
}
I have a WCF Restful Service that returns JSON objects that my iPhone and Android apps consume nicely. This is my first attempt at building something like this and I left WP7 till last as my background lies with C# and VS2010. But it seems it’s not going to be a simple as I had guessed.
So I guess I have three questions:
1, Can I consume JSON objects in WP7? If so does anyone know of a tutorial?
2, if not, can I use the existing service and build some new contracts for consumption in WP7? Or,
3, do I need to build a whole new service?
Option one is most desirable but either way, I need to develop for all three operating systems so does anyone know the best type of model to bring this all together???
Cheers,
Mike.
Yes, but not with the channel factory / proxy programming model which you may be used to with WCF. REST services are usually consumed by using some simpler classes such as WebClient. You can use the JSON libraries (DataContractJsonSerializer is in the WP7 profile) then to deserialize the data you receive. Even the untyped JSON (the System.Json classes from the System.Json.dll on Silverlight), while not officially in the profile, they kind of work on WP7 as well (I've seen a few people simply referencing the SL library on a WP7 project).
If you want proxy support, you can add a new endpoint to the service using BasicHttpBinding, which is supported in WP7; if you don't need it, see 1).
No. See 1) and 2).
Try this to deserialize a JSON object:
public static T Deserialize<T>(string strData) where T : class
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
byte[] byteArray = Encoding.UTF8.GetBytes(strData);
MemoryStream memoryStream = new MemoryStream(byteArray);
T tRet = serializer.ReadObject(memoryStream) as T;
memoryStream.Dispose();
return tRet;
}
I find a totally wcf-based approach more interesting.
This is a good post that addresses this issue
http://blogs.msdn.com/b/carlosfigueira/archive/2010/04/29/consuming-rest-json-services-in-silverlight-4.aspx
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.