.net フレームワーク webapi

vs2017

新しいプロジェクト

.net フレームワーク 4.6.1
写真の説明を追加してください
写真の説明を追加してください

目次

写真の説明を追加してください

バッグ

ここに画像の説明を挿入
Dapper 1.60.6 .NET オブジェクト マッパー
FluentValidation 8.6.1 型検証ルール
Mysql.Data 8.0.32 mysql データベース接続

FluentValidation は簡単に使用できます

ここに画像の説明を挿入

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;

namespace netceshi.Filter
{
    
    
    public class ParamsFilterAttribute : ActionFilterAttribute
    {
    
    
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
    
    
            //如果参数非法
            if (!actionContext.ModelState.IsValid)
            {
    
    
                actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);

            }
            //如果没有输入参数
            else if (actionContext.ActionArguments.Values.First() == null)
            {
    
    
                actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, "请输入参数!");
            }
        }
    }
}

ここに画像の説明を挿入

FluentValidationModelValidatorProvider.Configure(config);

ここに画像の説明を挿入

using FluentValidation;
using FluentValidation.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace netceshi.Models
{
    
    
    [Validator(typeof(PersonValidator))]
    public class Person
    {
    
    
        public int Id {
    
     get; set; }
        public string Name {
    
     get; set; }
        public string Sex {
    
     get; set; }
        public int Age {
    
     get; set; }
    }
    public class PersonValidator : AbstractValidator<Person>
    {
    
    
        public PersonValidator()
        {
    
    
            RuleFor(m => m.Id).NotEmpty().NotNull().WithMessage("Id不能为空");
            RuleFor(m => m.Name).NotEmpty().NotNull().WithMessage("Name不能为空");
        }
    }
}

ここに画像の説明を挿入

using netceshi.Filter;
using netceshi.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace netceshi.Controllers
{
    
    
    public class PersonController : ApiController
    {
    
    
        Person[] person = new Person[]
      {
    
    
            new Person {
    
     Id = 1, Name = "张三", Sex = "男", Age = 18 },
             new Person {
    
     Id = 1, Name = "李四", Sex = "女", Age = 18 },
              new Person {
    
     Id = 1, Name = "王二", Sex = "男", Age = 22 },
               new Person {
    
     Id = 1, Name = "麻子", Sex = "男", Age = 23 },

      };

        [HttpGet]
        public Person[] Index()
        {
    
    
            return person;
        }
        [HttpPost]
        [ParamsFilter]
        public Person Person([FromBody]Person p)
        {
    
    
            return p;
        }
    }
}

ここに画像の説明を挿入
ここに画像の説明を挿入

using FluentValidation.WebApi;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace netceshi
{
    
    
    public static class WebApiConfig
    {
    
    
        public static void Register(HttpConfiguration config)
        {
    
    
            // Web API 配置和服务
            FluentValidationModelValidatorProvider.Configure(config);
            // Web API 路由
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new {
    
     id = RouteParameter.Optional }
            );
            var formatters = config.Formatters.Where(formatter =>
                  formatter.SupportedMediaTypes.Where(media =>
                  media.MediaType.ToString() == "application/xml" || media.MediaType.ToString() == "text/html").Count() > 0) //找到请求头信息中的介质类型
                  .ToList();

            foreach (var match in formatters)
            {
    
    
                config.Formatters.Remove(match);  //移除请求头信息中的XML格式
            }
        }
    }
}

ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入

mysql データベースの簡単な追加、削除、変更操作

ここに画像の説明を挿入
データベース接続構成

  <connectionStrings>
    <add name="test" connectionString="Database=cloud-user;Data Source=127.0.0.1;Port=3306;User Id=root;Password=123456;SslMode = none;Charset=utf8;"/>
  </connectionStrings>

ここに画像の説明を挿入

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;

namespace netceshi.Filter
{
    
    
    public class DapperTools
    {
    
     
        //数据库连接字符串
        public static readonly string ConnectionString = ConfigurationManager.ConnectionStrings["test"].ConnectionString;
    }
}

データベース構造 cloud-user (データベース名)

/*
Navicat MySQL Data Transfer

Source Server         : 111
Source Server Version : 50722
Source Host           : localhost:3306
Source Database       : cloud-user

Target Server Type    : MYSQL
Target Server Version : 50722
File Encoding         : 65001

Date: 2023-02-17 17:03:23
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for tb_user
-- ----------------------------
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(100) DEFAULT NULL COMMENT '收件人',
  `address` varchar(255) DEFAULT NULL COMMENT '地址',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;

以下、さりげなくビルドしました
ここに画像の説明を挿入

using FluentValidation;
using FluentValidation.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace netceshi.Models
{
    
    
    public class User
    {
    
    
        public int Id {
    
     get; set; }
        public string UserName {
    
     get; set; }
        public string Address {
    
     get; set; }
    }
}

ここに画像の説明を挿入

using netceshi.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace netceshi.Server
{
    
    
    interface UserServer
    {
    
    
        /*
         * 列表
         */
        Object GetUsers();
        /*
         * 添加
         */
        Object AddUser(User u);
        /*
         * 删除
         */
        Object DelUser(int id);
        /*
         * 修改
         */
        Object UpdateUser(User u);

    }
}

ここに画像の説明を挿入

using Dapper;
using MySql.Data.MySqlClient;
using netceshi.Filter;
using netceshi.Models;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;

namespace netceshi.DAL
{
    
    
    public class DALUser
    {
    
    
        static string getList = "SELECT * FROM `tb_user`";
        static string del = "DELETE FROM `tb_user` WHERE (`id`=?id)";
        static string add = "INSERT INTO `tb_user` (`username`, `address`) VALUES (?username, ?address)";
        static string update = "UPDATE `tb_user` SET `username`=?UserName, `address`=?Address WHERE (`id`=?Id)";


        public Object GetUsers()
        {
    
    
            using (IDbConnection connection = new MySqlConnection(DapperTools.ConnectionString))
            {
    
    
                var result = connection.Query<User>(getList);
                return result;
            }
        }
        public Object DelUsers(int id)
        {
    
    
            using (IDbConnection connection = new MySqlConnection(DapperTools.ConnectionString))
            {
    
    
                User u = new User();
                u.Id = id;
                var result = connection.Execute(del, u);
                return result;
            }
        }
        public Object UpdteUsers(User u)
        {
    
    
            using (IDbConnection connection = new MySqlConnection(DapperTools.ConnectionString))
            {
    
    
                var result = connection.Execute(update, u);
                return result;
            }
        }
        public Object AddUsers(User u)
        {
    
    
            using (IDbConnection connection = new MySqlConnection(DapperTools.ConnectionString))
            {
    
    
                var result = connection.Execute(add, u);
                return result;
            }
        }

    }
}

ここに画像の説明を挿入

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using netceshi.Models;

namespace netceshi.Server.Impl
{
    
    
    class UserServerImpl : UserServer
    {
    
    
        DAL.DALUser daluser = new DAL.DALUser();
        public Object AddUser(User u)
        {
    
    
            return daluser.AddUsers(u);
        }

        public Object DelUser(int id)
        {
    
    
            return daluser.DelUsers(id);
        }

        public Object GetUsers()
        {
    
    
            return daluser.GetUsers();
        }

        public Object UpdateUser(User u)
        {
    
    
            return daluser.UpdteUsers(u);
        }
    }
}

ここに画像の説明を挿入

using netceshi.Server.Impl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace netceshi.Controllers
{
    
    
    public class UserController : ApiController
    {
    
    
        UserServerImpl userServerImpl = new UserServerImpl();

        [HttpGet]
        public Object Index()
        {
    
    
            return userServerImpl.GetUsers();

        }
        [HttpDelete]
        public Object Del(int id)
        {
    
    
            return userServerImpl.DelUser(id);

        }
        [HttpPost]
        public Object Add(Models.User u)
        {
    
    
            return userServerImpl.AddUser(u);

        }
        [HttpPut]
        public Object Update(Models.User u)
        {
    
    
            return userServerImpl.UpdateUser(u);

        }
    }
}

テスト
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入

統一された応答

統一された応答は後で使用できない場合があります
ここに画像の説明を挿入

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace netceshi.Models
{
    
    
    public interface IHttpResponseResult
    {
    
    
    }

    /// <summary>
    /// 响应数据输出泛型接口
    /// </summary>
    /// <typeparam name="T"></typeparam>
    // ReSharper disable once UnusedTypeParameter
    public interface IHttpResponseResult<T> : IHttpResponseResult
    {
    
    
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace netceshi.Models
{
    
    
    public class HttpResponseResult<T> : IHttpResponseResult<T>
    {
    
    
        /// <summary>
        /// 状态码
        /// </summary>
        public int Code {
    
     get; set; }

        /// <summary>
        /// 消息
        /// </summary>
        public string Message {
    
     get; set; }

        /// <summary>
        /// 数据
        /// </summary>
        public T Data {
    
     get; set; }

        /// <summary>
        /// 成功
        /// </summary>
        /// <param name="data">数据</param>
        /// <param name="msg">消息</param>
        public HttpResponseResult<T> Success(T data = default, string msg = null)
        {
    
    
            Code = 0;
            Data = data;
            Message = msg;
            return this;
        }

        /// <summary>
        /// 失败
        /// </summary>
        /// <param name="code">状态码</param>
        /// <param name="msg">消息</param>
        /// <param name="data">数据</param>
        /// <returns></returns>
        public HttpResponseResult<T> Fail(T data = default, int code = -1, string msg = null)
        {
    
    
            Code = code;
            Message = msg;
            Data = data;
            return this;
        }
    }

    /// <summary>
    /// 响应数据静态输出
    /// </summary>
    public static class HttpResponseResult
    {
    
    
        /// <summary>
        /// 成功
        /// </summary>
        /// <param name="data">数据</param>
        /// <param name="msg">消息</param>
        /// <returns></returns>
        public static IHttpResponseResult Success<T>(T data, string msg = "message")
        {
    
    
            return new HttpResponseResult<T>().Success(data, msg);
        }

        /// <summary>
        /// 失败
        /// </summary>
        /// <param name="data">数据</param>
        /// <param name="msg">消息</param>
        /// <param name="code">状态码</param>
        /// <returns></returns>
        public static IHttpResponseResult Fail<T>(T data, string msg = null, int code = -1)
        {
    
    
            return new HttpResponseResult<T>().Fail(data, code, msg);
        }
    }
}

jwt

ここに画像の説明を挿入
ログインデータ

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace netceshi.Models
{
    
    
    public class LoginUser
    {
    
    
        public string UserName {
    
     get; set;}
        public string PassWord {
    
     get; set; }
    }
}

ここに画像の説明を挿入
ここに画像の説明を挿入
jwt ツール

using JWT.Algorithms;
using JWT.Exceptions;
using JWT.Serializers;
using JWT;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace netceshi.Filter
{
    
    
    public class JWTHelper
    {
    
    
        private static string Key {
    
     get; set; } = "bfdhargrtjuykreawtuyjtretryjgafasdgrth";
        private IJwtAlgorithm algorithm {
    
     get; set; }  // 这是 HMACSHA256加密算法
        private IJsonSerializer serializer {
    
     get; set; }// 这是JSON序列化工具
        private IBase64UrlEncoder urlEncoder {
    
     get; set; } // 这是BASE64编码工具
        private IDateTimeProvider provider {
    
     get; set; }// 时间提供器  用来提供 格式一致的时间
        private IJwtValidator validator {
    
     get; set; }

        public JWTHelper()
        {
    
    

            Key = "klklergsflergldsarertlherdsigerklgld";// 这个密钥
            algorithm = new HMACSHA256Algorithm(); // 这是 HMACSHA256加密算法
            serializer = new JsonNetSerializer();// 这是JSON序列化工具
            urlEncoder = new JwtBase64UrlEncoder(); // 这是BASE64编码工具
            provider = new UtcDateTimeProvider(); // 时间提供器
            validator = new JwtValidator(serializer, provider); // 令牌校验器,用来验证有效期和签名
        }

        public string GetToken(Dictionary<string, object> payload, int expSeconds)
        {
    
    
            var unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); // or use JwtValidator.UnixEpoch
            var now = provider.GetNow();
            payload["exp"] = Math.Round((now - unixEpoch).TotalSeconds) + expSeconds;// exp 有效期
            IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);//  JWT加密工具
            var token = encoder.Encode(payload, Key); // 加密生成TOKEN
            return token;
        }
        // 解密
        public string GetPayload(string token)
        {
    
    
            try
            {
    
    
                IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm); // 创建解密工具
                var json = decoder.Decode(token, Key, verify: true);//token 中的载体的 JSON 格式字符串
                return json;  // payload
            }
            catch (TokenExpiredException)
            {
    
    
                Console.WriteLine("Token has expired");
                return null;
            }
            catch (SignatureVerificationException)
            {
    
    
                Console.WriteLine("Token has invalid signature");
                return null;
            }
            catch(Exception e)
            {
    
    
                Console.WriteLine(e);
                return null;
            }

        }
    }
}

認証操作

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http.Controllers;
using System.Web.Http;
using netceshi.DAL;

namespace netceshi.Filter
{
    
    
    public class MyAuth : AuthorizeAttribute
    {
    
    
        JWTHelper jwt = new JWTHelper();


        static string name = null;

        //public override void OnActionExecuting(ActionExecutingContext filterContext)
        //{
    
    

        //}

        public override void OnAuthorization(HttpActionContext actionContext)
        {
    
    
            try
            {
    
    
                var header = actionContext.Request.Headers.GetValues("Authorization");


                if (header != null)
                {
    
    
                    string token = header.First();


                    var json = jwt.GetPayload(token);

                    if (json != null)
                    {
    
    
                        Dictionary<string, object> dic = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
                        actionContext.ControllerContext.RouteData.Values["username"] = dic["username"];
                        name = dic["username"].ToString();
                    }
                    else
                    {
    
    
                        actionContext.Response = new HttpResponseMessage(HttpStatusCode.OK);
                        var x = new ResponseData() {
    
     code = 0, message = "token错误" };
                        actionContext.Response.Content = new StringContent(JsonConvert.SerializeObject(x), Encoding.UTF8, "appliaction/json");
                    }
                }
                else
                {
    
    
                    actionContext.Response = new HttpResponseMessage(HttpStatusCode.OK);
                    var x = new ResponseData() {
    
     code = 0, message = "没有token" };
                    actionContext.Response.Content = new StringContent(JsonConvert.SerializeObject(x), Encoding.UTF8, "appliaction/json");
                }

            }
            catch
            {
    
    
                actionContext.Response = new HttpResponseMessage(HttpStatusCode.OK);
                var x = new ResponseData() {
    
     code = 0, message = "错误 0099999" };
                actionContext.Response.Content = new StringContent(JsonConvert.SerializeObject(x), Encoding.UTF8, "appliaction/json");
            }
        }

        public static string Username()
        {
    
    
            return name;
        }


    }
    public class ResponseData
    {
    
    
        public int code {
    
     get; set; }
        public object data {
    
     get; set; }
        public string message {
    
     get; set; }
    }
}

ここに画像の説明を挿入
ユーザーはログインし、データベースを操作しませんが、固定値を書き込みます

[HttpPost]
        public IHttpResponseResult Login(LoginUser loginUser)
        {
    
    
            JWTHelper jWT= new JWTHelper();
            Dictionary<string, object> payload = new Dictionary<string, object>();
            payload.Add("username", loginUser.UserName);
            var jst = jWT.GetToken(payload,30);
            return HttpResponseResult.Success(jst, "成功");
        }

ここに画像の説明を挿入

[MyAuth] // 走认证
        [HttpGet]
        public IHttpResponseResult Index2()
        {
    
    
        //MyAuth.Username()   认证成功在jwt里取出来的,,,,可以去看看jwt工具和认证MyAuth
            return HttpResponseResult.Success(MyAuth.Username(), "成功");
        }
        [MyAuth]// 走认证
        [HttpGet]
        public Object Index()
        {
    
    
            return userServerImpl.GetUsers();

        }

クロスドメイン構成

ここに画像の説明を挿入

 <httpProtocol>
		  <customHeaders>
			  <remove name="Access-Control-Allow-Origin" />
			  <remove name="Access-Control-Allow-Headers" />
			  <remove name="Access-Control-Allow-Methods" />
			  <add name="Access-Control-Allow-Origin" value="*" />
			  <add name="Access-Control-Allow-Headers" value="Content-Type" />
			  <add name="Access-Control-Allow-Methods" value="*" />
		  </customHeaders>
	  </httpProtocol>

ここに画像の説明を挿入

 /// <summary>
        /// 跨域设置
        /// </summary>
        public void Application_BeginRequest()
        {
    
    
            //OPTIONS请求方法的主要作用:
            //1、获取服务器支持的HTTP方法;也就是黑客经常用的方法。
            //2、用来检查服务器的性能。如Ajax进行跨域请求是的预检,需要想另外一个域名的资源发送OPTIONS请求头,用以判断发送的请求是否安全
            if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
            {
    
    
                //表示对输出的内容进行缓冲,执行page.Response.Flush()时,会等所有内容缓冲完毕,将内容发送到客户端
                //这样就不会出错,造成页面卡死状态,让用户无限制等下去
                Response.Flush();
            }
        }

IIS をインストールする

ここに画像の説明を挿入
ここに画像の説明を挿入
時間がかかる場合があります。失敗した場合は、もう一度お試しください
ここに画像の説明を挿入
ここに画像の説明を挿入

IIS で発生する可能性のあるエラー

IIS运行.net web程序报错:不能在此路径中使用此配置节。如果在父级别上锁定了该节,便会出现这种情况。锁定是默认设置的(overrideModeDefault=“Deny“),或...

以管理员身份运行命令行:
%windir%\system32\inetsrv\appcmd unlock config -section:system.webServer/handlers
%windir%\system32\inetsrv\appcmd unlock config -section:system.webServer/modules
HTTP 错误 500.21 - Internal Server Error
处理程序“ExtensionlessUrlHandler-Integrated-4.0”在其模块列表中有一个错误模块“ManagedPipelineHandler”

最可能的原因:
使用了托管处理程序,但是未安装或未完整安装 ASP.NET。
处理程序模块列表的配置中存在书写错误。
在应用程序初始化期间,要么应用程序初始化功能已将 skipManagedModules 设置为 True,要么重写规则设置了映射到托管处理程序的 URL 并且还设置了 SKIP_MANAGED_MODULES=1。

可尝试的操作:
如果要使用托管处理程序,请安装 ASP.NET。
请确保正确指定处理程序模块的名称。模块名称区分大小写,并使用 modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" 格式。
设置映射到托管处理程序的 URL (例如 .aspx)时,请确保所有应用程序初始化重写规则都设置 SKIP_MANAGED_MODULE=0
作为替代方法,请确保应用程序初始化重写规则将请求映射到非托管处理程序(例如,映射到 .htm 文件,该文件映射到 StaticFileHandler。)

执行命令:
dism /online /enable-feature /featurename:IIS-ISAPIFilter
dism /online /enable-feature /featurename:IIS-ISAPIExtensions
dism /online /enable-feature /featurename:IIS-NetFxExtensibility45
dism /online /enable-feature /featurename:IIS-ASPNET45
当前标识(IIS APPPOOL\.NET v4.5)没有对"C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files"的写访问权限。

以管理员身份运行命令行:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Aspnet_regiis.exe -ga 'IIS APPPOOL\.NET v4.5'

ここに画像の説明を挿入
ここに画像の説明を挿入
エラーメッセージへの対応が必要

部署 IIS

ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
iis を開き、Web サイトを追加します
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入

住所

プロジェクトアドレス

おすすめ

転載: blog.csdn.net/weixin_45381071/article/details/129088272