Web API赢得';t返回对象

本文关键字:返回 对象 API 赢得 Web | 更新日期: 2023-09-27 18:26:59

我有一个非常简单的Web API应用程序。似乎所有的东西都是基本类型的。你不会发现任何花哨的身份验证或任何东西,但我可以在IIS Express上使用运行它

  • http://localhost:25095/Workbench/GetObject,或者:
  • http://localhost:25095/Workbench/GetNumber

当我启动这个web应用程序时,我可以将浏览器指向GetNumber,并在窗口中看到15。但是,当我指向GetObject时,我会看到WebAPI.DemoApp.SampleObject。这并不一定困扰我,只是我很困惑为什么。

我有一个代码(显示进一步向下),假定它强制Web API返回JSON。因此,无论是GetNumber还是GetObject,我都希望返回类似(伪代码)的内容:

  • {15}
  • {姓名:JoeOb}

无论哪种方式,我的控制台应用程序的ReadAsStringAsync都会产生相同的结果,而ReadAsAsync会产生错误:

  • 没有MediaTypeFormatter可用于从媒体类型为"text/html"的内容中读取"SampleObject"类型的对象

我的控制台应用程序非常简单:

static void Main(string[] args)
{
    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri("http://localhost:25095/");
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        //HttpResponseMessage response = client.GetAsync("Workbench/GetObject").Result;
        HttpResponseMessage response = client.GetAsync("Workbench/GetNumber").Result;
        //SampleObject getObject = response.Content.ReadAsAsync<SampleObject>().Result;
        var getNumber = response.Content.ReadAsStringAsync().Result;
        Console.WriteLine(getNumber);
        Console.Read();
    }
}

我想提到的是,这个项目最初是作为一个生成的ASP.NetWeb API项目(没有Azure)。从那时起,一切都在走下坡路。我以为我是在强迫Web API只返回JSON,但这一切都没有像我预期的那样起作用。

实际上,所有代码都在Global.asax.cs文件中,我将其复制/粘贴到下面:

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Runtime.Serialization;
using System.Web.Http;
using System.Web.Mvc;
namespace WebAPI.DemoApp
{
    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            System.Web.Routing.RouteTable.Routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}",
                defaults: new { controller = "Workbench", action = "GetObject", id = UrlParameter.Optional }
            );
            var jsonFormatter = new JsonMediaTypeFormatter();
            GlobalConfiguration.Configuration.Services.Replace(typeof(IContentNegotiator), new JsonContentNegotiator(jsonFormatter));
        }
    }
    public class JsonContentNegotiator : IContentNegotiator
    {
        private readonly JsonMediaTypeFormatter _jsonFormatter;
        public JsonContentNegotiator(JsonMediaTypeFormatter formatter)
        {
            _jsonFormatter = formatter;
        }
        public ContentNegotiationResult Negotiate(Type type, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters)
        {
            var result = new ContentNegotiationResult(_jsonFormatter, new MediaTypeHeaderValue("application/json"));
            return result;
        }
    }
    public class WorkbenchController : Controller
    {
        public SampleObject GetObject()
        {
            return (new SampleObject() { Name = "JoeBob" });
        }
        public int GetNumber()
        {
            return 15;
        }
    }
}

Web.config同样简单:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings></appSettings>
  <system.web>
    <authentication mode="None" />
    <compilation debug="true" targetFramework="4.5"/>
    <httpRuntime targetFramework="4.5" />
  </system.web>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-5.2.0.0" newVersion="5.2.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

除了Stripped-down引用(我删除了所有OWIN引用)之外,项目中几乎没有其他内容。

我的目标只是将我的对象转移到控制台应用程序。

PS:SampleObject存在于两个项目之间共享的一个单独的DLL中。

    [DataContract]
    public class SampleObject
    {
        [DataMember]
        public string Name { get; set; }
    }

Web API赢得';t返回对象

事实证明,要返回对象,需要从ApiController继承,而不是从Controller继承。这也意味着我的App_Start必须具有:

GlobalConfiguration.Configure(WebApiConfig.Register);

并执行您在默认Web API应用程序中看到的配置:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}