zoukankan      html  css  js  c++  java
  • Asp.Net Web API 2第九课——自承载Web API

    前言

    阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html

    Asp.Net Web API可以需要IIS。你可以在你自己的主机上来承载一个Web API。

    本教程来展示在控制台应用程序中来承载一个Web API。使用的开发工具为VS2013。

    本文示例代码下载链接http://pan.baidu.com/s/1d56zf

    创建一个控制台应用程序

     

    这里我默认的Framework版本为4.5的。然后通过Nuget来下载安装Microsoft.AspNet.WebApi.SelfHost。

    创建Model和Controller

     首先添加一个public公共类Product。

        public class Product
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public string Category { get; set; }
            public decimal Price { get; set; }
        }

    然后添加一个public公共类ProductsController,并且这个类继承自System.Web.Http.ApiController。记得添加扩展引用System.Web.Http

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Text;
    using System.Threading.Tasks;
    using System.Web.Http;
    
    namespace SelfHost
    {
        public class ProductsController:ApiController
        {
            Product[] products = new Product[]  
            {  
                new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },  
                new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },  
                new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }  
            };
            public IEnumerable<Product> GetAllProducts()
            {
                return products;
            }
            public Product GetProductById(int id)
            {
                var product = products.FirstOrDefault((p) => p.Id == id);
                if (product == null)
                {
                    throw new HttpResponseException(HttpStatusCode.NotFound);
                }
                return product;
            }
            public IEnumerable<Product> GetProductsByCategory(string category)
            {
                return products.Where(p => string.Equals(p.Category, category,
                        StringComparison.OrdinalIgnoreCase));
            }
        }
    }

    这个控制器定义了三个Get方法:

    承载Web API

     打开Program.cs,然后添加如下使用语句:

    using System.Web.Http;
    using System.Web.Http.SelfHost; 

    当然如果你没有引用,还是先要添加引用的(另外还有System.Net.Http)。然后添加如下代码到Program.cs里:

    var config = new HttpSelfHostConfiguration("http://localhost:8080");
    
    config.Routes.MapHttpRoute(
        "API Default", "api/{controller}/{id}", 
        new { id = RouteParameter.Optional });
    
    using (HttpSelfHostServer server = new HttpSelfHostServer(config))
    {
        server.OpenAsync().Wait();
        Console.WriteLine("Press Enter to quit.");
        Console.ReadLine();
    }

    现在你可以运行控制台程序了。

    现在可以通过URI来简单测试Web API的正确性。

    (可选的)添加一个HTTP URL命名空间保留(没遇到这个问题,暂未测试)

     这个应用程序侦听到"http://localhost:8080"。在默认情况下,侦听一个特殊的HTTP URL是需要管理员权限的。当你运行上面的控制台应用程序的时候,你可能会得到这样的一个错误:"HTTP could not register URL http://+:8080",这儿有两种方式去避免这个错误:

      1.以管理员身份运行Visual Studio。

      2.使用Netsh.exe给与你的账号权限去保留这个URL。

    若要使用Netsh.exe,以管理员身份打开命令提示框,并键入以下命令:

    netsh http add urlacl url=http://+:8080/ user=machineusername

    其中machineusername是您的用户帐户。

    当你使用完自托管的时候,最好是确定删除这个保留的URL。

    netsh http delete urlacl url=http://+:8080/

    通过客户端应用程序来调用Web API

    让我们来写一个简单的控制台应用程序来调用Web API。

    添加一个控制台应用程序,并命名为"ClientApp"。

    同样的通过Nuget来添加Microsoft.AspNet.WebApi.Client。

    当然还需要应用SelfHost这个项目。

    打开ClientApp项目的Program.cs文件,添加如下using语句

    using System.Net.Http; 

    添加一个静态的HttpClient实例:

    namespace ClientApp
    {
        class Program
        {
            static HttpClient client = new HttpClient();
            static void Main(string[] args)
            {
            }
        }
    }

    添加三个方法 获得所有产品列表信息,通过ID获得指定产品信息,通过目录获得产品列表信息。

    static void ListAllProducts()
    {
        HttpResponseMessage resp = client.GetAsync("api/products").Result;
        resp.EnsureSuccessStatusCode();
    
        var products = resp.Content.ReadAsAsync<IEnumerable<SelfHost.Product>>().Result;
        foreach (var p in products)
        {
            Console.WriteLine("{0} {1} {2} ({3})", p.Id, p.Name, p.Price, p.Category);
        }
    }
    
    static void ListProduct(int id)
    {
        var resp = client.GetAsync(string.Format("api/products/{0}", id)).Result;
        resp.EnsureSuccessStatusCode();
    
        var product = resp.Content.ReadAsAsync<SelfHost.Product>().Result;
        Console.WriteLine("ID {0}: {1}", id, product.Name);
    }
    
    static void ListProducts(string category)
    {
        Console.WriteLine("Products in '{0}':", category);
    
        string query = string.Format("api/products?category={0}", category);
    
        var resp = client.GetAsync(query).Result;
        resp.EnsureSuccessStatusCode();
    
        var products = resp.Content.ReadAsAsync<IEnumerable<SelfHost.Product>>().Result;
        foreach (var product in products)
        {
            Console.WriteLine(product.Name);
        }
    }

    每个方法遵循相同的模式:

      1.调用HttpClient.GetAsync来发送一个HTTP Get请求到适当的URI。

      2.调用HttpResponseMessage.EnsureSuccessStatusCode ,如果HTTP响应状态是一个错误码,那么这个方法将抛出一个异常。

      3.调用ReadAsAsync<T> 反序列化一个来自HTTP响应的CLR类型。 这个方法是一个扩展方法,被定义在System.Net.Http.HttpContentExtensions


    GetAsync ReadAsAsync 这两个方法都是异步方法。它们通过返回Task 对象来代表异步操作。获取Result属性阻止线程,直到操作完成。

    在调用这些方法之前, BaseAddress 上的属性设置为"http://localhost:8080"的 HttpClient 实例。例如:

    static void Main(string[] args)
    {
        client.BaseAddress = new Uri("http://localhost:8080");
    
        ListAllProducts();
        ListProduct(1);
        ListProducts("toys");
    
        Console.WriteLine("Press Enter to quit.");
        Console.ReadLine();
    }

    接下来,进行测试。设置启动项目。

    预测输出内容,应该会输出以下内容:

    1 Tomato Soup 1.0 (Groceries)
    2 Yo-yo 3.75 (Toys)
    3 Hammer 16.99 (Hardware)
    ID 1: Tomato Soup
    Products in 'toys':
    Yo-yo
    Press Enter to quit.

    运行程序,查看结果

    总结

    感觉还是比较简单的吧,就这样一步一步的下来还是没什么阻碍的。

    本文的参考链接http://www.asp.net/web-api/overview/hosting-aspnet-web-api/self-host-a-web-api

    本文已同步到Web API系列导航 http://www.cnblogs.com/aehyok/p/3446289.html

    本文示例代码下载链接http://pan.baidu.com/s/1d56zf

  • 相关阅读:
    bzoj1711
    bzoj1458
    bzoj1433
    hdu2732
    bzoj1066
    hdu3549
    poj1698
    [ZJOI2007]时态同步
    SA 学习笔记
    [LUOGU]2016 Sam数
  • 原文地址:https://www.cnblogs.com/aehyok/p/3456841.html
Copyright © 2011-2022 走看看