C# Web API

 效果图:

1.appsettings.json 配置文件,连接数据库

 "ConnectionStrings": {
   "connString": "server=.; database=CRM; uid=sa; pwd=123456;Encrypt=True;TrustServerCertificate=True;"
 }

2.  Program.cs

 public class Program
 {
     public static void Main(string[] args)
     {
         // builder构建器,把当前应用程序构建(编译,生成)。主要提供一个Ioc
         var builder = WebApplication.CreateBuilder(args);

         builder.Services.AddControllers();// 把所有的控件器“扔”到Ioc容器

         builder.Services.AddEndpointsApiExplorer();
         builder.Services.AddSwaggerGen();

         //注册上下文:AOP里面可以获取IOC对象,如果有现成框架比如Furion可以不写这一行
         builder.Services.AddHttpContextAccessor();
         //注册SqlSugar用AddScoped
         builder.Services.AddScoped<ISqlSugarClient>(s => 
         {
             //1. 构建配置对象
             var configBuilder = new ConfigurationBuilder()
                 .SetBasePath(Directory.GetCurrentDirectory()) // 配置文件的目录
                 // optional: true如果该文件不存在也不会抛出异常
                 //reloadOnChange: true表示当配置文件发生改变时自动重新加载配置
                 .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
             IConfigurationRoot configuration = configBuilder.Build();

             //2. 获取连接字符串
             string? connString = configuration.GetConnectionString("connString");

             //3. 创建SqlSugarClient实例
             SqlSugarClient sqlSugar = new SqlSugarClient(new ConnectionConfig() 
             {
                 DbType = SqlSugar.DbType.SqlServer,//指定数据库类型
                 ConnectionString = connString,
                 IsAutoCloseConnection = true,//自动关闭数据库连接
             },
             db => 
             {
                 //配置了一个AOP(面向切面编程)
                 db.Aop.OnLogExecuting = (sql, pars)=>{ };
             });
             return sqlSugar;
         });

         // 把服务“扔”到Ioc
         builder.Services.AddSingleton<IStudent, StudentService>();

         // app当前应用程序实例
         // 向应用程序的Ioc容器中“扔”了很多的服务,必须构建之后,服务才和当前应用融合。
         var app = builder.Build();

         if (app.Environment.IsDevelopment()) // 判断是否是开发环境,才启用接口调试的功能(即使用Swagger)
         {
             app.UseSwagger(); // 规律:UseXXX() ,使用某种服务提供的功能。
             app.UseSwaggerUI();
         }

         app.UseHttpsRedirection();// 一个中间件,用于将HTTP请求重定向到HTTPS

         app.UseAuthorization();// 授权

         // 把控件器中定义的各种接口(服务,方法)映射成一个“地址”
         app.MapControllers();

         app.Run();
     }
 }

3.Models中的Student

[SugarTable("Student")]
public class Student
{
    [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
    public int Id { get; set; }

    [SugarColumn(IsNullable = false, ColumnDataType = "varchar(50)")]
    public string Name { get; set; }
}

 4.Services中的IStudentStudentService

 public interface IStudent
 {
     bool Add(Student model);
     List<Student> Search(string strWhere);
     bool Update(Student model);
     bool Delete(int id);
 }
public class StudentService : IStudent
{
    public bool Add(Student model)
    {
        return true;
    }

    public bool Delete(int id)
    {
        return true;
    }

    public List<Student> Search(string strWhere)
    {
        // 模拟数据,省略读取数据库的逻辑:ORM框架可选:ADO.NET, EF, Dapper等。 
        return new List<Student>()
        {
            new Student(){ Id=1,Name="张三"},
            new Student(){ Id=2,Name="李四"}
        };
    }

    public bool Update(Student model)
    {
        return true;
    }
}

5.Controllers中的StuddentController

规律:
查询可以使用查询字符串传参[FromQuery]路径传参{id}/{name}不涉及安全性
提交,修改,删除这些动作是有危险,建议使用请求体传参[FromBody]

 [ApiController]
 [Route("api/[controller]")]  // 生成路由:api/Student/XXX
 public class StuddentController : ControllerBase
 {
     private readonly IStudent stdentService;
     private readonly ISqlSugarClient db;

     public StuddentController(IStudent stdentService, ISqlSugarClient db)
     {
         this.stdentService = stdentService;
         this.db = db;
     }

     #region GET 查询

     // HttpGet特性表示是GET请求,主要用来获取数据
     [HttpGet("S1")] // api/Student/S1
     public IEnumerable<Student> Hello()
     {

         return new List<Student>()
         {
             new Student(){ Id=1,Name="zs"},
             new Student(){ Id=2,Name="ls"},
         };
     }

     [HttpGet("S2")]  // api/Student/S2
     public IEnumerable<Student> Hello2()
     {
         // 使用SqlSugar ORM框架
         return this.db.Queryable<Student>().ToList();
     }

     // GET请求传参问题? 异步GET?
     //传参方式1:使用查询字符串  ?key1=val1&key2=val2
     [HttpGet("S3")]
     public IEnumerable<Student> Hello3(string? name)
     {
         ISugarQueryable<Student> query = this.db.Queryable<Student>();
         if (!string.IsNullOrEmpty(name))
         {
             query = query.Where(s => s.Name.Contains(name));
         }
         return query.ToList();
     }

     // 传参数方式2:占位符(路径参数)
     [HttpGet("S4/{name}")] //friendly url友好的URL,利于推广
     public IEnumerable<Student> Hello4(string? name)
     {
         ISugarQueryable<Student> query = this.db.Queryable<Student>();
         if (!string.IsNullOrEmpty(name))
         {
             query = query.Where(s => s.Name.Contains(name));
         }
         return query.ToList();
     }

     [HttpGet("S5")]
     public IEnumerable<Student> Hello5([FromQuery] string? name)
     {
         ISugarQueryable<Student> query = this.db.Queryable<Student>();
         if (!string.IsNullOrEmpty(name))
         {
             query = query.Where(s => s.Name.Contains(name));
         }
         return query.ToList();
     }

     // 异步Get方式1
     [HttpGet("S6")]
     public async Task<List<Student>> Hello6()
     {
         return await db.Queryable<Student>().ToListAsync();
     }

     //异步Get方式2:返回简单类型
     [HttpGet("S7")]
     public async IAsyncEnumerable<int> Hello7()
     {
         for (int i = 0; i < 10; i++)
         {
             await Task.Delay(1000);// 模拟长时间处理
             yield return i;  // yield生成
         }
     }

     // 异步Get方式2:返回复杂类型
     [HttpGet("S8")]
     public async IAsyncEnumerable<Student> Hello8()
     {
         for (int i = 0; i < 3; i++)
         {
             await Task.Delay(1000);
             yield return new Student() { Id = i, Name = "name" + 1 };// yield生成
         }
     }
     #endregion


     #region Post 提交

     [HttpPost("add1")]
     public IActionResult Add1()
     {
         // 响应的格式:https://blog.youkuaiyun.com/weixin_43394129/article/details/132444340

         // 常用的响应格式:OkResult、JsonResult、 BadRequestResult、NotFoundResult、 NoContentResult

         // BadRequestResult  400 客户端请求的语法错误,服务器无法理解
         //BadRequest();

         // NotFoundResult  404 请求的路径不存在。
         //NotFound();

         // NoContentResult  没有内容响应
         //NoContent();

         // OkResult   200成功响应

         var obj = new //创建匿名对象
         {
             Code = 200,  //状态码
             Message = "添加成功!",
             Data = "hello world"  //实际要返回的数据
         };
         return Ok(obj);//在ASP.NET Core Web API中的一种常见返回方式
     }

     // POST请求传参,推荐使用FromBody,复杂数据类型(引用类型)webapi可以推断,FromBody省略
     [HttpPost("add2")]
     public IActionResult Add2([FromBody] Student model)
     {
         this.db.Insertable<Student>(model).ExecuteCommand();
         return Ok(new
         {
             Code = 200,
             Message = "添加成功!"
         });
     }

     // 异步的Post请求
     [HttpPost("add3")]
     public async Task<IActionResult> Add3([FromBody] Student model)
     {
         await this.db.Insertable<Student>(model).ExecuteCommandAsync();
         return Ok(new
         {
             Code = 200,
             Message = "添加成功!"
         });
     }
     #endregion


     #region PUT 修改

     // 传参方式1:FromBody
     [HttpPut("put1")]
     public IActionResult Put1([FromBody] Student model)
     {
         this.db.Updateable<Student>(model).ExecuteCommand();
         return Ok(new
         {
             Code = 200,
             Message = "修改成功!"
         });
     }

     // 传参方式2:路径参数(占位符)
     [HttpPut("pu2")]
     public IActionResult Put2(int id,string name)
     {
         Student model = this.db.Queryable<Student>().InSingle(id);
         model.Name = name;
         this.db.Updateable<Student>(model).ExecuteCommand();
         return Ok(new
         {
             Code = 200,
             Message = "修改成功!"
         });
     }

     [HttpPut("put3/{id}/{name}")]
     public IActionResult Put3([FromRoute] int id, [FromRoute] string name)
     {
         Student model = this.db.Queryable<Student>().InSingle(id);
         model.Name = name;
         this.db.Updateable<Student>(model).ExecuteCommand();
         return Ok(new
         {
             Code = 200,
             Message = "修改成功!"
         });
     }

     // 传参方式3:查询字符串(传递的参数出现在URL中,容易被普通用户修改。不安全)
     [HttpPut("put4")]
     public IActionResult Put4([FromQuery] int id, [FromQuery] string name)
     {
         Student model = this.db.Queryable<Student>().InSingle(id);
         model.Name = name;
         this.db.Updateable<Student>(model).ExecuteCommand();
         return Ok(new
         {
             Code = 200,
             Message = "修改成功!"
         });
     }

     // 异步的PUT
     [HttpPut("put5")]
     public async Task<IActionResult> Put5([FromBody] Student model)
     {
         await this.db.Updateable<Student>(model).ExecuteCommandAsync();
         return Ok(new
         {
             Code = 200,
             Message = "修改成功!"
         });
     }
     #endregion


     #region Delete 删除

     // 传参方式1:请求体
     [HttpDelete("del1")]
     public IActionResult Del1([FromBody] int id)
     {
         this.db.Deleteable<Student>(id).ExecuteCommand();
         return Ok(new
         {
             Code = 200,
             Message = "删除成功!"
         });
     }

     // 传参方式2:路径参数
     [HttpDelete("del2/{id}")]
     public IActionResult Del2([FromRoute] int id)
     {
         this.db.Deleteable<Student>(id).ExecuteCommand();
         return Ok(new
         {
             Code = 200,
             Message = "删除成功!"
         });
     }

     // 传参方式3:查询字符串
     [HttpDelete("del3")]
     public IActionResult Delete3([FromQuery] int id)
     {
         this.db.Deleteable<Student>(id).ExecuteCommand();
         return Ok(new
         {
             Code = 200,
             Message = "删除成功!"
         });
     }

     //异步的Delete
     [HttpDelete("del4")]
     public async Task<IActionResult> Del4([FromBody] int id)
     {
         await this.db.Deleteable<Student>(id).ExecuteCommandAsync();
         return Ok(new
         {
             Code = 200,
             Message = "删除成功!"
         });
     }
     #endregion
 }

### C# Web API 开发教程和常见问题解决方案 #### 创建 Web API 项目 为了创建一个新的 C# Web API 项目,在 Visual Studio 中可以选择 ASP.NET Core Web Application 模板并选择 API 类型来初始化新项目[^1]。 ```csharp var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); // Add services to the container. var app = builder.Build(); app.MapControllers(); // Map default controller routes. app.Run(); ``` #### 配置 Swagger/OpenAPI 文档支持 Swagger 是一种用于描述 RESTful APIs 的工具,可以方便开发者测试 API 接口。在创建项目时应勾选 OpenAPI 支持选项;如果忘记勾选,则可以通过 NuGet 安装 `Swashbuckle.AspNetCore` 包,并配置中间件以启用 Swagger UI 和 JSON 文档端点[^3]。 ```csharp builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new() { Title = "My API", Version = "v1" }); }); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(options => options.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1")); } ``` #### 发布到 IIS 平台下的注意事项 当准备将应用程序部署至 Internet Information Services (IIS) 上运行之前,确保已安装 .NET Hosting Bundle。另外需要注意的是,对于生产环境而言,建议设置 HTTPS 终结点以及适当的安全策略[^2]。 #### 常见错误及其解决办法 - **跨域资源共享(CORS)**:默认情况下浏览器会阻止来自不同源服务器请求资源的行为。通过向 Startup.cs 文件中的 ConfigureServices 方法添加 CORS 策略可允许特定域名访问 API 资源。 ```csharp builder.Services.AddCors(options => options.AddPolicy(name: MyAllowSpecificOrigins, policy => { policy.WithOrigins("http://example.com") .AllowAnyHeader() .AllowAnyMethod(); })); ``` - **模型验证失败**:客户端提交的数据不符合预期格式或类型时可能会触发此异常。可以在控制器方法参数前加上 `[FromBody]` 属性指定输入来源于 HTTP 请求体,并利用数据注解特性来进行基本校验逻辑定义。 ```csharp public class WeatherForecastController : ControllerBase { [HttpPost] public IActionResult Post([FromBody]WeatherData data) { if (!ModelState.IsValid) { return BadRequest(ModelState); } // Process valid request... } } public class WeatherData { [Required(ErrorMessage="Temperature is required")] public double Temperature { get; set; } ... } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值