How to get an object on ASP.NET web API?

This is my web API and it works great, I mean, when I enter this URL into my browser:

http://localhost:18207/api/values/GetMyClass 

I get this result:

 <MyClass> <A>a</A> <b>b</b> </MyClass> 

My codes are:

 public class MyClass { public MyClass() { this.A = "a"; this.b = "b"; } public string A { get; set; } public string b { get; set; } } public class ValuesController : ApiController { public MyClass GetMyClass() { return new MyClass(); } } 

I have another console application to use my web API and you want to know how can I create a complex or object type MyClass?

The codes on my console are below, but it returns a string type

  static void Main(string[] args) { var cts = new CancellationTokenSource(); MainAsync(args, cts.Token).Wait(); } static async Task MainAsync(string[] args, CancellationToken token) { string baseAddress = "http://localhost:18207/api/values/GetMyClass"; using (var httpClient = new HttpClient()) { string response = await httpClient.GetStringAsync(baseAddress); } } 
+5
source share
4 answers

Your answer probably fits your console application as JSON (the reason your browser gets it as XML, due to the different Accept headers, you can find out about this if you look at Content Consolidation ). So what you need to do is parse the JSON and deserialize it into your object. There are so many libraries that can do this for you.

First, make sure your MyClass defined in the class library project, which references your web API project and your console project. This allows us to reuse the class definition without having to have a separate copy in both projects.

Next, you need a JSON parsing library. There is one built in to .NET, but there is a third-party one called Json.NET , which is the gold standard. My answer will use it, since I am more familiar with it. Install the Newtonsoft.Json package in the console application.

Then modify the console application as follows:

 using Newtonsoft.Json; // at the top of your file static void Main(string[] args) { var cts = new CancellationTokenSource(); MainAsync(args, cts.Token).Wait(); } static async Task MainAsync(string[] args, CancellationToken token) { string baseAddress = "http://localhost:18207/api/values/GetMyClass"; using (var httpClient = new HttpClient()) { string json = await httpClient.GetStringAsync(baseAddress); MyClass instance = JsonConvert.DeserializeObject<MyClass>(json); } } 

The JsonConvert class handles JSON serialization and deserialization. When deserializing, we just say which class we are deserializing to, and it will try to convert the JSON into an instance of that class and return it.

+8
source

Here is a complete solution from end to end. We host a web api that returns MyClass , and then we call the API and get the XML data through a console application.

First, we have MyClass annotated as a DataContract :

 [DataContract] public class MyClass { public MyClass() { this.A = "a"; this.b = "b"; } [DataMember] public string A { get; set; } [DataMember] public string b { get; set; } } 

MyClass web interface:

 [AllowAnonymous] public class MyClassController : ApiController { public MyClass Get() { return new MyClass(); } } 

and a console application that uses HttpWebRequest to invoke Web Api.

Here is this code (bottom half from my original post):

 static void Main(string[] args) { // this is my Web API Endpoint var req = (HttpWebRequest)WebRequest.Create("http://localhost:17512/api/MyClass"); // default is JSON, but you can request XML req.Accept = "application/xml"; req.ContentType = "application/xml"; var resp = req.GetResponse(); var sr = new StreamReader(resp.GetResponseStream()); // read the response stream as Text. var xml = sr.ReadToEnd(); var ms = new MemoryStream(Encoding.UTF8.GetBytes(xml)); // Deserialize var ser = new XmlSerializer(typeof(MyClass)); var instance = (MyClass)ser.Deserialize(ms); Console.WriteLine(instance.A); Console.WriteLine(instance.b); var final = Console.ReadLine(); } 

NOTE. You need to find out if you want to share the MyClass link between the two assemblies or just want to have a copy of the code file in each project.

0
source

You can use the GetAsync method, which will return an object of class "HttpResponseMessage", and then you can call "ReadAsAsync" in the Content property. See below code:

 public class MyClass { public MyClass() { this.A = "a"; this.b = "b"; } public string A { get; set; } public string b { get; set; } } static void Main(string[] args) { var cts = new CancellationTokenSource(); MainAsync(args, cts.Token).Wait(); } static async Task MainAsync(string[] args, CancellationToken token) { string baseAddress = "http://localhost:18207/api/values/GetMyClass"; using (var httpClient = new HttpClient()) { HttpResponseMessage response = await httpClient.GetAsync(baseAddress); response.EnsureSuccessStatusCode(); MyClass result = await response.Content.ReadAsAsync< MyClass>(); } } 
0
source

You can simply remove the XML Formatter inside your WebApiConfig.cs

 public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Removing XML config.Formatters.Remove(config.Formatters.XmlFormatter); // Allows us to map routes using [Route()] and [RoutePrefix()] config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } } 

Then in your controller you will return exactly the same as in your example:

 public class ValuesController : ApiController { public MyClass GetMyClass() { return new MyClass(); } } 

UPDATE 1: I made my answer more consistent with the question

When creating a request from a console application, you can use RestSharp .

 var client = new RestClient("http://localhost:18207/"); var request = new RestRequest("api/values/GetMyClass", Method.GET); var response = client.Execute<MyClass>(request); if(response.StatusCode == HttpStatusCode.OK) var responseData = response.Data; 

When you execute client.Execute<MyClass>(request) , it will deserialize the response into an object of this class. If the field names match, they should work.

-1
source

Source: https://habr.com/ru/post/1238397/


All Articles