如何在 ASP.NET Web API 上获取对象?
How to get object on ASP.NET Web API?
这是我的网站 API 并且运行良好,我的意思是当我在浏览器中输入此 URL 时:
http://localhost:18207/api/values/GetMyClass
我检索到这个结果:
<MyClass>
<A>a</A>
<b>b</b>
</MyClass>
我的代码:
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();
}
}
我有另一个控制台应用程序可以使用我的 Web API,我想知道,
我怎样才能拥有 MyClass 的复杂类型或对象类型?
我控制台上的代码如下,但它是 returns 字符串类型
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);
}
}
您的响应可能会以 JSON (the reason your browser receives it as XML is because of different Accept headers, you can learn about that if you look at Content Negotiation) 的形式出现在您的控制台应用程序中。所以你需要做的是解析 JSON 并将其反序列化到你的对象中。有很多图书馆可以为您做到这一点。
首先确保您的 MyClass
是在您的 Web API 项目和控制台项目都引用的 Class 库项目中定义的。这使我们能够重用 class 定义,而无需在两个项目中都有单独的副本。
接下来,你需要一个JSON解析库。 .NET 中内置了一个,但有一个名为 Json.NET that is the gold standard. My answer will use that one since I'm more familiar with it. Install the Newtonsoft.Json 的第 3 方程序包到您的控制台应用程序中。
然后,按如下方式更改您的控制台应用程序:
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);
}
}
JsonConvert
class 处理 JSON 的序列化和反序列化。反序列化时,我们只是告诉要反序列化到哪个 class,它会尝试将 JSON 转换为 class 和 return 的实例。
这是端到端的完整解决方案。我们正在托管一个 Api returns MyClass
的网站,然后我们调用 API 并通过控制台应用程序获取格式化为 XML 的数据。
首先,我们将 MyClass
注释为 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
网站API:
[AllowAnonymous]
public class MyClassController : ApiController
{
public MyClass Get()
{
return new MyClass();
}
}
和一个使用 HttpWebRequest
调用 Web Api 的控制台应用程序。
这是代码(下半部分来自我原来的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();
}
注意:您需要弄清楚是否要在两个程序集之间共享对 MyClass
的引用,或者您是否只想在每个项目中拥有一份代码文件的副本。
您可以使用方法 "GetAsync",它将 return class "HttpResponseMessage" 的对象,然后您可以在内容 属性 上调用 "ReadAsAsync" .
请看下面的代码:
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>();
}
}
您只需删除 WebApiConfig.cs
中的 XML 格式化程序
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 }
);
}
}
然后在您的控制器中,您将 return 就像在您的示例中一样:
public class ValuesController : ApiController
{
public MyClass GetMyClass()
{
return new MyClass();
}
}
更新 1:我的回答与问题更加一致了
从控制台应用程序发出请求时,您可以使用 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;
当您执行 client.Execute<MyClass>(request)
时,它会将响应反序列化为 class 的对象。如果字段名称匹配,它应该可以工作。
这是我的网站 API 并且运行良好,我的意思是当我在浏览器中输入此 URL 时:
http://localhost:18207/api/values/GetMyClass
我检索到这个结果:
<MyClass>
<A>a</A>
<b>b</b>
</MyClass>
我的代码:
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();
}
}
我有另一个控制台应用程序可以使用我的 Web API,我想知道, 我怎样才能拥有 MyClass 的复杂类型或对象类型?
我控制台上的代码如下,但它是 returns 字符串类型
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);
}
}
您的响应可能会以 JSON (the reason your browser receives it as XML is because of different Accept headers, you can learn about that if you look at Content Negotiation) 的形式出现在您的控制台应用程序中。所以你需要做的是解析 JSON 并将其反序列化到你的对象中。有很多图书馆可以为您做到这一点。
首先确保您的 MyClass
是在您的 Web API 项目和控制台项目都引用的 Class 库项目中定义的。这使我们能够重用 class 定义,而无需在两个项目中都有单独的副本。
接下来,你需要一个JSON解析库。 .NET 中内置了一个,但有一个名为 Json.NET that is the gold standard. My answer will use that one since I'm more familiar with it. Install the Newtonsoft.Json 的第 3 方程序包到您的控制台应用程序中。
然后,按如下方式更改您的控制台应用程序:
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);
}
}
JsonConvert
class 处理 JSON 的序列化和反序列化。反序列化时,我们只是告诉要反序列化到哪个 class,它会尝试将 JSON 转换为 class 和 return 的实例。
这是端到端的完整解决方案。我们正在托管一个 Api returns MyClass
的网站,然后我们调用 API 并通过控制台应用程序获取格式化为 XML 的数据。
首先,我们将 MyClass
注释为 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
网站API:
[AllowAnonymous]
public class MyClassController : ApiController
{
public MyClass Get()
{
return new MyClass();
}
}
和一个使用 HttpWebRequest
调用 Web Api 的控制台应用程序。
这是代码(下半部分来自我原来的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();
}
注意:您需要弄清楚是否要在两个程序集之间共享对 MyClass
的引用,或者您是否只想在每个项目中拥有一份代码文件的副本。
您可以使用方法 "GetAsync",它将 return class "HttpResponseMessage" 的对象,然后您可以在内容 属性 上调用 "ReadAsAsync" . 请看下面的代码:
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>();
}
}
您只需删除 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 }
);
}
}
然后在您的控制器中,您将 return 就像在您的示例中一样:
public class ValuesController : ApiController
{
public MyClass GetMyClass()
{
return new MyClass();
}
}
更新 1:我的回答与问题更加一致了
从控制台应用程序发出请求时,您可以使用 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;
当您执行 client.Execute<MyClass>(request)
时,它会将响应反序列化为 class 的对象。如果字段名称匹配,它应该可以工作。