目录
第一种
第二种
第三种
Vue3前端访问
在我们开发api的时候,需要让接口返回统一的接口,这样容易理解,也容易管理。所以封装返回的统一结果是非常必要的。
下面介绍3种方案。
第一种
建立一个控制器,让所有控制器都继承它
文件总览
1.建立ApiResult.cs
namespace net6ApiResult.Common
{
public class ApiResult<T>
{
/// <summary>
/// 错误代码
/// </summary>
public ApiResultCode Code { get; set; }
/// <summary>
/// 错误信息
/// </summary>
public string Message { get; set; }
/// <summary>
/// 具体数据
/// </summary>
public T Data { get; set; }
}
}
2.建立ApiResultCode.cs
namespace net6ApiResult.Common
{
public enum ApiResultCode
{
//失败
Failed,
//成功
Success,
//数据为空
Empty,
}
}
3.建立CommonController.cs
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using net6ApiResult.Common;
namespace net6ApiResult.Controllers
{
[ApiController]
[Route("api/[controller]/[action]")]
public class CommonController : ControllerBase
{
protected ApiResult<T> GenActionResultGenericEx<T>(T datas, ApiResultCode code = ApiResultCode.Success, string message = "", Exception ex = null)
{
if (ex != null)
{
code = ApiResultCode.Failed;
message = string.IsNullOrWhiteSpace(message) ? ex.Message : $"{message}\n{ex.Message}";
#if Debug
message = string.IsNullOrWhiteSpace(message) ? ex.Message : $"{message}\n{ex.Message}";
#endif
}
else if (datas == null)
{
code = ApiResultCode.Empty;
message = "数据为空";
}
var result = new ApiResult<T>
{
Code = code,
Message = message,
Data = datas
};
return result;
}
}
}
4.WeatherForecastController.cs中使用
using Microsoft.AspNetCore.Mvc;
using net6ApiResult.Common;
namespace net6ApiResult.Controllers
{
[ApiController]
[Route("api/[controller]/[action]")]
public class WeatherForecastController : CommonController
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
[HttpGet]
public ApiResult<IEnumerable<WeatherForecast>> Get111()
{
return GenActionResultGenericEx(Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
);
}
[HttpGet]
public ApiResult<string> GetA()
{
//可以根据业务进行判断,然后赋值,再返回
return GenActionResultGenericEx("123", ApiResultCode.Success, "成功");
}
}
}
5.效果
第二种
使用dynamic动态增加
只需要修改返回的地方
1.WeatherForecastController.cs代码
using Microsoft.AspNetCore.Mvc;
//using net6ApiResult.Common;
using Newtonsoft.Json;
namespace net6ApiResult.Controllers
{
[ApiController]
[Route("api/[controller]/[action]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
[HttpGet]
public object Get111()
{
dynamic retObject; //使用object retObject;也可以,最好使用dynamic
var retdata = Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray(); //业务数据,可以根据业务进行判断,然后赋值
//object data1 = JsonConvert.SerializeObject(retdata); //如果加上会出现转义符
retObject = new { retcode = "0", retmsg = "成功", data = retdata };
return retObject;
}
[HttpGet]
public object GetA()
{
dynamic retObject;
var retdata = "123"; //业务数据,可以根据业务进行判断,然后赋值
retObject = new { retcode = "0", retmsg = "成功", data = retdata };
//return JsonConvert.SerializeObject(retObject); //这里不要序列化,如果改成序列化后,接口的值是字符串,一行值。
return retObject;
}
}
}
2.效果
第三种
建立一个类,使用过滤器,继承IResultFilter或者IAsyncResultFilter接口。
1.ApiResult.cs代码
namespace net6ApiResult.Common
{
public class ApiResult<T>
{
public int Code { get; set; }
public string Message { get; set; }
public T Data { get; set; }
}
}
2.ResultFilter.cs代码
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc;
using System.Net;
using Newtonsoft.Json;
using Microsoft.AspNetCore.SignalR;
namespace net6ApiResult.Common
{
public class ResultFilter : IResultFilter
{
public void OnResultExecuted(ResultExecutedContext context)
{
//返回结果之后
}
public void OnResultExecuting(ResultExecutingContext context)
{
//var result = new ApiResult<IActionResult>
//{
// Code = 1,
// Message = "",
// Data = context.Result
//};
返回结果之前
//context.Result = new ContentResult
//{
// // 返回状态码设置为200,表示成功
// StatusCode = (int)HttpStatusCode.OK,
// // 设置返回格式
// ContentType = "application/json;charset=utf-8",
// Content = JsonConvert.SerializeObject(result)
//};
object? data = null;
if (context.Result is ObjectResult result)
{
data = result.Value;
}
var result1 = new ApiResult<object>();
if (data == null || data.ToString()?.Length == 0)
{
result1.Code = 0;
result1.Message = "数据为空";
}
else
{
result1.Code = 1;
result1.Message = "成功";
}
result1.Data = data;
//返回结果之前
context.Result = new ContentResult
{
// 返回状态码设置为200,表示成功
StatusCode = (int)HttpStatusCode.OK,
// 设置返回格式
ContentType = "application/json;charset=utf-8",
Content = JsonConvert.SerializeObject(result1)
};
}
}
}
3.使用的时候,不需要调用,自动根据返回结果进行过滤
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
//using net6ApiResult.Common;
using Newtonsoft.Json;
namespace net6ApiResult.Controllers
{
[ApiController]
[Route("api/[controller]/[action]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
[HttpGet]
public object Get111()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
[HttpGet]
public object GetA()
{
var retdata = "123"; //业务数据,可以根据业务进行判断,然后赋值
return retdata;
}
[HttpGet]
public object GetB()
{
var retdata = ""; //业务数据,可以根据业务进行判断,然后赋值
return retdata;
}
[HttpGet]
public object GetC()
{
object retdata = null; //业务数据,可以根据业务进行判断,然后赋值
return retdata;
}
}
}
4.全局注册
using net6ApiResult.Common;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddControllers(o => o.Filters.Add(typeof(ResultFilter))); //全局注册
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
5.效果
Vue3前端访问
当我们做好了webapi接口后,然后就需要在前端进行访问了。
1.在axios中,进行响应拦截,把需要的数据传递给前端的页面
import axios from 'axios'
//export将service传出去
export const service = axios.create({
baseURL: '/api'
})
//下面有2种写法,一种是声明函数的写法,一种是箭头函数的写法,都可以
//request interceptor 请求拦截器
service.interceptors.request.use(
function(config) {
return config
},
function(error) {
// 对请求错误做些什么
console.log(error)
console.log('这里是请求错误')
return Promise.reject(error)
}
)
//响应拦截器
service.interceptors.response.use(
res => {
// 在请求成功后的数据处理
if (res.status === 200) {
console.log(res.status)
console.log('这里是请求成功后')
return res.data;//返回需要的数据
} else {
console.log(res.status)
console.log('这里是请求失败后')
return res;
}
},
err => {
// 在响应错误的时候的逻辑处理
console.log('这里是响应错误')
return Promise.reject(err)
});
2.同时,前端需要进行接收,就不用判断状态了
<script setup>
import {
ref,
onMounted,
reactive
} from 'vue'
import {
service
} from "/store/demoAxios.js"
// import axios from 'axios'
let user = ref("admin")
let passWord = ref("123456")
const form = reactive({
params: '',
pagesize: 2,
pagenum: 4,
data: {
}
})
console.log(form)
const Login = async () => {
await service.get(`/WeatherForecast/GetA`).then(res => {
// if (res.status == 200) {
console.log(1111)
console.log(res)
console.log(res.Code)
console.log(res.Data)
console.log(res.Message)
console.log(222)
//}
})
// await service.get(`http://localhost:5000/api/User/Login?userId=1&pwd=1`).then(res => {
// if (res.status == 200) {
// console.log(1111)
// console.log(res.data)
// console.log(222)
// }
// })
}
//初始化后执行
onMounted(() => {
Login()
})
</script>
<template>
</template>
<style scoped>
a {
color: #42b983;
}
</style>
3.效果
在前端界面,就能看到对应的值了,这样前后端基本上就统一了返回格式,当然还可以继续优化的更好。
可结合这个一起看
VUE3中,使用Axios_故里2130的博客-CSDN博客_vue3中安装axios