This is useful as a basis:
How to programmatically connect a client to a WCF service?
However, I'd like my client to do the same thing REST-style without knowledge of any service contract.
Seeing how this is done easily in Javascript / jQuery, it seems odd that C# presents no options.
In C# all you need is a standard HttpWebRequest or WebClient like this:
var request = HttpWebRequest.Create("http://localhost:28330/books");
var response = request.GetResponse();
var reader = new StreamReader(response.GetResponseStream());
Console.WriteLine(reader.ReadToEnd());
or
var client = new WebClient();
Console.WriteLine(client.DownloadString("http://localhost:28330/books"));
Of course you still need to do something with the XML or JSON (or whatever data format is returned) but that is no different in JavaScript with jQuery.
Seeing how this is done easily in Javascript / jQuery, it seems odd
that C# presents no options.
That is only partially true. It does - you can use HttpWebRequest to do a call. Old REST StarterKit (only technology preview) and a new Web-API (only CTP) offers better support in HttpClient class.
Related
We are converting some code from .NET Framework to .NET Core. Some services are using SOAP messages with a signed header. Using SoapCore we've been abled to create a service which supports signed XML (and the necessary validations). However, we are now creating a client which should be able to consume such a service (in .NET Core).
Basic code (performing the request, no signing):
var binding = new BasicHttpBinding();
var endpoint = new EndpointAddress(new Uri("https://myserver/mysoapendpoint/"));
var channelFactory = new ChannelFactory<ISampleService>(binding, endpoint);
var serviceClient = channelFactory.CreateChannel();
var result = serviceClient.Ping("hey");
I can't find any way to make the service send an XML. In .NET Framework we could do it the following way:
using (ChannelFactory<ISampleService> factory = new ChannelFactory<ISampleServiceChannel>(tokenBinding, endpointAddress))
{
factory.Credentials.UseIdentityConfiguration = true;
using (ISampleServiceChannel proxy = factory.CreateChannelWithIssuedToken(myToken))
{
var result = proxy.Ping("hey");
}
}
Stuff like CreateChannelWithIssuedToken no longer seems to be implemented in .NET Core. If I could inject something which would sign the XML than I could do the writing myself. However, I'm unable to find the correct way to achieve this goal.
We cannot change to another implementation of security as we are not controlling the clients/services... (Clients from different organizations will interact this way...)
Many thanks for your replies.
I am stuck on this simple question. In my console application, I want to consume a wcf service. So I add the web reference to the project and call it. That is it.
But why I saw some examples especially using RESTSHARP, they never add web reference. They just use so called "DTO" to return object by the service and consume it.
I hope somebody can clarify the concepts for me. Is DTO used inside WCF?
sample:
private static List<ApplicationDTO> features;
RestClient client = new RestClient("http://" + baseUrl + "/FacilityData.svc");
var request = new RestRequest(Method.GET);
request.Resource = "/GetFeatures";
request.Parameters.Clear();
request.AddParameter("Id", 888);
var response = client.Execute(request);
features = JsonConvert.DeserializeObject<List<ApplicationDTO>>(response.Content);
from this post:
For REST service, it provides a generic way for WCF service consuming
which doesn't rely on the SOAP. That's why we no longer need "Add
ServiceReference..." for consuming it. REST service operations can be
accessed through standard HTTP GET/POST request, so any webrequest
enabled client can consume it. For example, you can use HttpWebRequest
to invoke a REST operation and use LINQ to XML to load and extract
values from the response XML data. It's very flexible.
DTO, usually used for Data Transfer Object - is nothing more then entity you want to pass as parameter / receive as a result.
In your example, ApplicationDTO - is probably some entity to hold Data about Application Feature object (Name, Type, ...)
While I have already learned how I can easily write to the response stream, I was wondering whether in the context of a ServiceStack client (e.g. ServiceClientBase) I can gain access to the server's response stream.
Before I start accessing the HttpWebResponse object I wanted to double-check that I do not reinvent the wheel.
See this earlier answer for examples of how to access the underlying raw response types.
Also the C# ServiceClient wiki is the authoritative documentation on ServiceStack's built in C#/.NET service clients. It includes a section on different ways of accessing the underlying raw response, including via the Response stream:
using (Stream responseStream = client.Get<Stream>("/poco/World")) {
var dto = responseStream.ReadFully().FromUtf8Bytes().FromJson<PocoResponse>();
dto.Result //Hello, World
}
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