引言:什么是 ASP.NET Web API 2.2?
ASP.NET Web API 2.2 是一个强大的框架,用于构建基于 HTTP 的 RESTful 服务。它建立在 ASP.NET MVC 基础之上,允许开发者创建能够被各种客户端(如浏览器、移动应用、桌面应用)消费的 Web API。本文将为您提供一份详尽的开发文档和实战入门教程,帮助您从零开始掌握 ASP.NET Web API 2.2。
核心特性
RESTful 支持
:天然支持 REST 架构风格。
内容协商
:自动处理 JSON、XML 等多种数据格式。
路由机制
:灵活的路由配置,支持属性路由。
依赖注入
:易于集成依赖注入容器。
OData 支持
:支持 OData 协议,提供强大的查询能力。
1. 环境准备与项目创建
1.1 必需软件
Visual Studio 2013 或更高版本
(推荐使用 Visual Studio 2015+ 以获得更好的工具支持)。
.NET Framework 4.5 或更高版本
。
NuGet 包管理器
(通常已集成在 Visual Studio 中)。
1.2 创建新项目
打开 Visual Studio。
选择
文件 > 新建 > 项目
。
在模板中选择
ASP.NET Web 应用程序 (.NET Framework)
。
命名项目(例如
MyWebApi
),点击
确定
。
在下一个窗口中选择
Web API
模板(确保不选择 MVC,除非您需要两者)。
点击
确定
创建项目。
2. 理解控制器与路由
2.1 控制器基础
控制器是处理 HTTP 请求的核心组件。每个控制器类通常对应一个资源集合。
示例:创建一个产品控制器
using System.Collections.Generic;
using System.Web.Http;
namespace MyWebApi.Controllers
{
public class ProductsController : ApiController
{
// 模拟数据库
private static List
{
new Product { Id = 1, Name = “Laptop”, Price = 999.99 },
new Product { Id = 2, Name = “Smartphone”, Price = 499.99 }
};
// GET: api/products
public IEnumerable
{
return products;
}
// GET: api/products/5
public Product GetProduct(int id)
{
return products.Find(p => p.Id == id);
}
// POST: api/products
public IHttpActionResult PostProduct(Product product)
{
product.Id = products.Count + 1;
products.Add(product);
return CreatedAtRoute(“DefaultApi”, new { id = product.Id }, product);
}
// PUT: api/products/5
public IHttpActionResult PutProduct(int id, Product product)
{
var existingProduct = products.Find(p => p.Id == id);
if (existingProduct == null)
{
return NotFound();
}
existingProduct.Name = product.Name;
existingProduct.Price = product.Price;
return Ok(existingProduct);
}
// DELETE: api/products/5
public IHttpActionResult DeleteProduct(int id)
{
var product = products.Find(p => p.Id == id);
if (product == null)
{
return NotFound();
}
products.Remove(product);
return Ok();
}
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
}
}
2.2 路由配置
在
App_Start/WebApiConfig.cs
文件中配置路由。
using System.Web.Http;
namespace MyWebApi
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API 配置和服务
// Web API 路由
config.MapHttpAttributeRoutes(); // 启用属性路由
config.Routes.MapHttpRoute(
name: “DefaultApi”,
routeTemplate: “api/{controller}/{id}”,
defaults: new { id = RouteParameter.Optional }
);
}
}
}
3. 数据传输与内容协商
3.1 JSON 与 XML 格式
Web API 自动支持 JSON 和 XML 格式。客户端可以通过
Accept
头指定首选格式。
示例:全局配置 JSON 格式
在
WebApiConfig.cs
中添加:
config.Formatters.JsonFormatter.SupportedMediaTypes
.Add(new System.Net.Http.Headers.MediaTypeHeaderValue(“text/html”));
3.2 使用 DTO(数据传输对象)
为了安全和灵活性,建议使用 DTO 而不是直接暴露实体类。
public class ProductDto
{
public int Id { get; set; }
public string Name { get; set; }
// 不暴露 Price 字段
}
4. 错误处理与验证
4.1 全局异常过滤器
创建一个全局异常过滤器来捕获未处理的异常。
using System.Web.Http.Filters;
using System.Net;
using System.Net.Http;
using System.Web.Http.ExceptionHandling;
public class CustomExceptionFilter : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
var exception = context.Exception;
var response = new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent($”An error occurred: {exception.Message}”),
ReasonPhrase = “Internal Server Error”
};
context.Response = response;
}
}
在
WebApiConfig.cs
中注册:
config.Filters.Add(new CustomExceptionFilter());
4.2 模型验证
使用 DataAnnotations 进行模型验证。
using System.ComponentModel.DataAnnotations;
public class Product
{
public int Id { get; set; }
[Required(ErrorMessage = “Name is required”)]
[StringLength(100, ErrorMessage = “Name cannot exceed 100 characters”)]
public string Name { get; set; }
[Range(0.01, 10000, ErrorMessage = “Price must be between 0.01 and 10000”)]
public double Price { get; set; }
}
在控制器中检查
ModelState.IsValid
:
public IHttpActionResult PostProduct(Product product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// … 保存逻辑
}
5. 身份验证与授权
5.1 基于令牌的身份验证(JWT)
虽然 Web API 2.2 原生支持基于声明的身份验证,但这里展示一个简化的 JWT 实现。
安装 NuGet 包:
Microsoft.AspNet.Identity.Owin
Microsoft.Owin.Security.Jwt
生成 JWT 令牌:
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
public string GenerateJwtToken(string username)
{
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(“YourSuperSecretKeyYourSuperSecretKey”));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
var claims = new[]
{
new Claim(ClaimTypes.Name, username),
new Claim(ClaimTypes.Role, “Admin”)
};
var token = new JwtSecurityToken(
issuer: “http://yourdomain.com”,
audience: “http://yourdomain.com”,
claims: claims,
expires: DateTime.Now.AddHours(3),
signingCredentials: credentials
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
验证 JWT 令牌:
在
App_Start/Startup.Auth.cs
中配置:
using Microsoft.Owin;
using Microsoft.Owin.Security.Jwt;
using Owin;
[assembly: OwinStartup(typeof(MyWebApi.Startup))]
namespace MyWebApi
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
var issuer = “http://yourdomain.com”;
var audience = “http://yourdomain.com”;
var secret = Encoding.UTF8.GetBytes(“YourSuperSecretKeyYourSuperSecretKey”);
app.UseJwtBearerAuthentication(
new JwtBearerAuthenticationOptions
{
AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = issuer,
ValidAudience = audience,
IssuerSigningKey = new SymmetricSecurityKey(secret)
}
});
}
}
}
6. 依赖注入(DI)
6.1 使用 Autofac 集成
Autofac 是一个流行的 DI 容器。
安装 NuGet 包:
Autofac
Autofac.WebApi2
配置 Autofac:
using Autofac;
using Autofac.Integration.WebApi;
using System.Reflection;
using System.Web.Http;
public static class AutofacConfig
{
public static void Register()
{
var builder = new ContainerBuilder();
// 注册控制器
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
// 注册服务
builder.RegisterType
var container = builder.Build();
// 设置依赖解析器
var config = GlobalConfiguration.Configuration;
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}
}
在
Global.asax
中调用:
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
AutofacConfig.Register(); // 添加这一行
}
7. 测试与调试
7.1 使用 Postman 测试 API
GET 请求
:
GET http://localhost:port/api/products
POST 请求
:
URL:
http://localhost:port/api/products
Body: Raw JSON
{
“Name”: “Tablet”,
“Price”: 299.99
}
添加 Authorization 头
:
Bearer
7.2 单元测试
使用 MSTest 或 NUnit 编写测试。
using System.Web.Http;
using System.Web.Http.Results;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
[TestClass]
public class ProductsControllerTests
{
[TestMethod]
public void GetProduct_ShouldReturnProduct_WhenExists()
{
// Arrange
var mockService = new Mock
mockService.Setup(s => s.GetById(1)).Returns(new Product { Id = 1, Name = “Test” });
var controller = new ProductsController(mockService.Object);
// Act
var result = controller.GetProduct(1);
// Assert
var okResult = result as OkNegotiatedContentResult
Assert.IsNotNull(okResult);
Assert.AreEqual(1, okResult.Content.Id);
}
}
8. 部署
8.1 IIS 部署步骤
发布项目
:在 Visual Studio 中右键项目 -> 发布 -> 选择文件夹。
配置 IIS
:
确保安装了
URL 重写模块
。
在 IIS 中添加网站,指向发布文件夹。
确保应用程序池使用 .NET CLR v4.0。
Web.config 调整
:
9. 常见问题与解决方案
9.1 循环引用问题
问题
:序列化实体时出现循环引用。
解决方案
:
使用 DTO。
在
WebApiConfig.cs
中移除 XML 格式器:
config.Formatters.Remove(config.Formatters.XmlFormatter);
使用 JSON.NET 的
[JsonIgnore]
特性。
9.2 路由冲突
问题
:多个路由匹配同一个请求。
解决方案
:使用属性路由明确指定路径。
[RoutePrefix(“api/v1/products”)]
public class ProductsController : ApiController
{
[Route(“{id:int}”)]
public IHttpActionResult GetProduct(int id) { … }
}
10. 进阶主题
10.1 OData 集成
OData 允许客户端执行查询操作(如过滤、分页)。
安装 NuGet 包
:
Microsoft.AspNet.OData
配置 OData 路由
:
using System.Web.OData.Builder;
using System.Web.Http;
public static class ODataConfig
{
public static void Register(HttpConfiguration config)
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet
config.MapODataRoute(“ODataRoute”, “odata”, builder.GetEdmModel());
}
}
控制器示例
:
using System.Web.OData;
public class ProductsController : ODataController
{
// 支持 $filter, $orderby 等查询
[EnableQuery]
public IQueryable
{
return products.AsQueryable();
}
}
结语
ASP.NET Web API 2.2 是一个成熟且功能丰富的框架,适用于构建现代 Web 服务。通过本指南,您应该已经掌握了从创建项目到部署的完整流程。继续探索高级功能如 OData、SignalR 集成以及微服务架构,将使您的 API 更加强大和高效。