【问题标题】:how to use WebAPI by creating an instance of it like ASMX web service如何通过创建像 ASMX Web 服务这样的实例来使用 WebAPI
【发布时间】:2017-12-29 19:20:23
【问题描述】:

我将 Asp.NET WebApi 作为业务层。我想通过简单地调用业务控制器来调用它的方法。 像这样:(但我无法像服务引用一样添加这个 webapi)

Business.API.UserController Users = new Business.API.UserController();
Users.GetAllUser();

以前我正在使用 WCF Web 服务,我可以通过“添加服务引用”添加它并设置一些端点来创建一个 Web 服务实例。 我不能在 WebAPI 中做到这一点(我认为)。我已经阅读了很多关于它的文章,但其中大多数是关于通过 HttpRequest 调用它的方法。 这样:

using (var client = new HttpClient())    
{    
    client.BaseAddress = new Uri("http://localhost:38104/");
    client.DefaultRequestHeaders.Accept.Clear();    
    HttpResponseMessage response;    
    response = await client.GetAsync("api/Weather");    
    if (response.IsSuccessStatusCode)    
    {    
        WeatherClient[] reports = await response.Content.ReadAsAsync<WeatherClient[]>();                   
     }    
}    

我认为使用 Web 服务是荒谬的。 是我错了还是我有什么问题?

【问题讨论】:

  • 您可以使用 swagger(为您的 Web 服务生成 api 描述的工具),然后使用一些可以从该 api 描述生成客户端的工具,尽管我承认我自己从未这样做过。
  • 我在您的代码中看到的主要问题是您为每个请求创建了一个新的HttpClient。这是一个共享对象,因此您不会耗尽服务器连接。

标签: c# asp.net asp.net-web-api


【解决方案1】:

虽然您没有任何问题,但这也不是一种可笑的使用网络服务的方式。实际上;它是唯一使用网络服务的方式; WCF 为您隐藏了该代码。

免责声明:还有其他 .NET 类和库可以执行 HTTP 请求,并且可能具有更简单的 API,但没有任何东西可以像 WCF 那样将其隐藏为类

WCF 服务发布关于它们自己的元数据,这就是“服务引用”起作用的原因。 Web API 没有类似的概念,你必须手动做 HTTP 请求。您当然可以将该代码包装到一些通用函数中以供重用。

使用正确的辅助方法,您可以接近“RPC”接口,只需要传入每个方法的端点而不是名称。

【讨论】:

  • 谢谢。这种方法的主要问题是面临流输出和输入。我很想知道如何使用 HttpRequests 传递流或获取流。所以我必须阅读我认为的基础知识。
  • @RezaNoei 至少有一个 .NET Http 类具有流 API。通常,它们处理起来很痛苦,但不是首选。
  • 所以似乎没有这么明确的方法可以走。再次感谢。
  • 要在 Stream 中返回数据而不是使用内存,请返回值 HttpResponseMessage。在从 ApiController 派生的控制器类中创建返回值:responseMessage = this.Request.CreateResponse(HttpStatusCode.Ok)。创建流:Stream streamToReturn = ...;;将此流作为内容放入响应消息中:`responseMessage.Content = newStreamContent(streamToReturn);返回响应消息;
  • @HaraldCoppoolse 虽然有用,但我相信 OP 更关心的是成为一个 Web 服务 consumer 而不是创建一个新的
【解决方案2】:

类最好依赖接口而不是直接实例化HttpClient。我见过使用 WCF 服务正确执行此操作的应用程序 - 取决于服务接口 - 但是对于 Web API,它们抛弃了抽象并直接合并 Http 请求。

在您的应用程序中,您仍然可以定义一个表示某些服务的接口,以便抽象实现(Web API、mock 等)。

比如你可能依赖这个接口

public interface IFooService
{
    FooDto GetFoo(Guid id);
    List<FooDto> GetAllFoos();
    Guid InsertFoo(FooInsertDto foo);
    void UpdateFoo(FooDto updating);
    void DeleteFoo(Guid id);
}

并使用此实现:

public class FooServiceClient : IFooService
{
    private readonly RestClient _restClient;

    public FooServiceClient(string baseUrl)
    {
        _restClient = new RestClient(baseUrl.TrimEnd('/'));
    }

    public FooDto GetFoo(Guid id)
    {
        var request = new RestRequest($"api/foo/get{id}", Method.GET);
        var foo = _restClient.Execute<FooDto>(request).Data;
        return foo;
    }

    public List<FooDto> GetAllFoos()
    {
        var request = new RestRequest("api/foo/getall", Method.GET);
        var foos = _restClient.Execute<List<FooDto>>(request).Data;
        return foos;
    }

    public Guid InsertFoo(FooInsertDto foo)
    {
        var request = new RestRequest("api/foo/insert", Method.POST)
            { RequestFormat = DataFormat.Json};
        request.AddBody(foo);
        return _restClient.Execute<Guid>(request).Data;
    }

    public void UpdateFoo(FooDto updating)
    {
        var request = new RestRequest("api/foo/update", Method.POST)
        { RequestFormat = DataFormat.Json };
        request.AddBody(updating);
        _restClient.Execute(request);
    }

    public void DeleteFoo(Guid id)
    {
        var request = new RestRequest("api/foo/delete", Method.POST)
        { RequestFormat = DataFormat.Json };
        request.AddBody(id);
        _restClient.Execute(request);
    }
}

这也演示了RestSharp 的使用。不建议为每次使用创建和处置 HttpClient。 RestSharp 帮助管理这一点,并提供了简化发送请求和读取响应的方法。

【讨论】:

  • 谢谢。我拥有这些知识还有很长的路要走。
猜你喜欢
  • 1970-01-01
  • 2010-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-06
  • 2018-02-14
  • 1970-01-01
  • 2014-01-18
相关资源
最近更新 更多