简体   繁体   English

如何在ASP.NET Web API上获取对象?

[英]How to get object on ASP.NET Web API?

This is my Web API and it works fine, I mean when i enter this URL on my browser: 这是我的Web API,它运行正常,我的意思是当我在浏览器上输入此URL时:

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

I retrieve this result: 我检索这个结果:

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

My codes: 我的代码:

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 want to know, How can i have a complex or object type of MyClass? 我有另一个控制台应用程序来使用我的Web API并想知道,我如何拥有MyClass的复杂或对象类型?

Codes on my Console are below but it returns 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);
        }
    }

Your response is probably coming to your console application as 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进入您的控制台应用程序(您的浏览器接收它作为XML的原因是因为不同的Accept标头,如果您查看内容协商 ,您可以了解这一点)。 So what you need to do is parse the JSON and have it deserialize it into your object. 所以你需要做的就是解析JSON并将它反序列化到你的对象中。 There's quite a few libraries that can do that for you. 有很多库可以帮到你。

First make sure that your MyClass is defined in a Class Library project that both your Web API project and your Console project are referencing. 首先确保您的MyClass是在您的Web API项目和Console项目引用的类库项目中定义的。 This allows us to reuse the class definition without needing to have a separate copy in both projects. 这允许我们重用类定义,而无需在两个项目中都有单独的副本。

Next, you need a JSON parsing library. 接下来,您需要一个JSON解析库。 There's one built into .NET, but there's a 3rd party one called Json.NET that is the gold standard. 有一个内置于.NET,但有一个名为Json.NET的第三方是黄金标准。 My answer will use that one since I'm more familiar with it. 我的回答将使用那个,因为我对它更熟悉。 Install the Newtonsoft.Json package into your console app. Newtonsoft.Json包安装到您的控制台应用程序中。

Then, change your console app 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 serializing and deserializing the JSON. JsonConvert类处理JSON的序列化和反序列化。 When deserializing, we just tell is which class to deserialize to and it will attempt to convert the JSON to an instance of that class and return it. 反序列化时,我们只告诉要反序列化的类,它将尝试将JSON转换为该类的实例并返回它。

Here is the full solution end-to-end. 这是端到端的完整解决方案。 We are hosting a Web Api that returns MyClass and then we are calling the API and getting data formatted as XML through a console application. 我们正在托管一个返回MyClass的Web Api,然后我们调用API并通过控制台应用程序将数据格式化为XML。

First, we have MyClass annotated as a DataContract : 首先,我们将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; }
}

The MyClass Web API: MyClass Web API:

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

and a Console app that uses HttpWebRequest to call the Web Api. 和一个使用HttpWebRequest来调用Web Api的控制台应用程序。

Here's that code (the bottom half is 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'll need to figure out if you want to share a reference to MyClass between the two assemblies or if you just want to have a copy of the code file in each project. 注意:您需要确定是否要在两个程序集之间共享对MyClass的引用,或者您是否只想在每个项目中拥有代码文件的副本。

You can use method "GetAsync" which will return object of class "HttpResponseMessage" and then you can call "ReadAsAsync" on Content property. 您可以使用方法“GetAsync”,它将返回类“HttpResponseMessage”的对象,然后您可以在Content属性上调用“ReadAsAsync”。 Please 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>();

        }
    }

You could just remove XML Formatter inside your WebApiConfig.cs 您可以在WebApiConfig.cs删除XML Formatter

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 would return just like in your example: 然后在你的控制器中你会像你的例子一样返回:

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

UPDATE 1: I did my answer become more consistent with the question 更新1:我的回答与问题更加一致

When making a Request from a Console Application, you could use RestSharp . 从控制台应用程序发出请求时,您可以使用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 that class. 当您执行client.Execute<MyClass>(request)它会将响应反序列化为该类的对象。 If field names match it should work. 如果字段名称匹配,它应该工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM