Bootstrap

一步一步从微信小程序获取asp.net Core API的数据

前面我们说过,如何使用微信小程序获取asp.net的数据,这里我们继续介绍如何获取asp.net core api的数据。两者之间还是有一些差别的。本篇博文旨在详细介绍如何一步一步从微信小程序获取asp.net Core API的数据。


文章原出处:
https://blog.csdn.net/haigear/article/details/143208403

一、建立并了解asp.net core web API

1、建立工程

有webapi经验的可以略过本章节,首先,建立一个asp.net core web api项目,比如我们起名为websiteAPItest,下面

在这里插入图片描述

2、关于两个重要的文件

建立好工程,下面正式开工了。进入我们建立好的工程,我们最需要关注的就是这两个文件了。首先我们就从这两个文件入手来了解。
在这里插入图片描述
从上图,我们注意到,最应该注意到的就是红色箭头所指的两个文件,因为就是他们两个具体负责我们API对外部访问所提供的数据,我们不要忘记,我们之所以要建立这个API工程,目的就是对外提供数据访问。
观察两个文件,我们发现,都很普通,尤其第一个,就是一个简单的类,或者我们在MVC中称之为Model的类,还一个在controllers下,名称叫做WeatherForecastController.cs,一看这个名字你肯定已经猜测到它就是MVC中称之为Controller的类。那么还有一个View的类呢?其实我们的微信小程序前端就是这个View了!
来,我们具体来看看代码:
WeatherForecast.cs

namespace websiteAPItest
{
    public class WeatherForecast
    {
        public DateOnly Date { get; set; }

        public int TemperatureC { get; set; }

        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);

        public string? Summary { get; set; }
    }
}

很显然,上面的WeatherForecast.cs文件平淡无奇,就是一个普通带有几个属性的类。下面我们看看
WeatherForecastController.cs

using Microsoft.AspNetCore.Mvc;

namespace websiteAPItest.Controllers
{
    [ApiController]
    [Route("[controller]")]
    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(Name = "GetWeatherForecast")]
        public IEnumerable<WeatherForecast> Get()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }
}

这个类倒是有些新的东西,每个方法前都有一个特性描述,类的前面也有特性描述。除此没有其他特别了,至于这里实现了一个枚举接口的Get方法,也不是controller类必须的。其实随便的一个添加了特性描述的方法的controller类都是可以的。后面我们将自己建立一个最简单的controller类。

文章原出处:
https://blog.csdn.net/haigear/article/details/143208403

3、API的访问测试

预览效果我们会发现,会呈现一个web端的swagger访问页面,这里出现的就是我们在项目中对应的weatherforecast的接口。
在这里插入图片描述
打开这个接口我们可以通过普通的http协议来访问,也就是说,我们可以在web浏览器上直接输入地址访问,点开get栏的下拉图标,我们会发现Request URL中有一个url地址,我们试试访问一下:
在这里插入图片描述
在这里插入图片描述
这就是我们通过url访问得到的jason格式的数据,这些数据我们就可以直接拿到微信小程序中去使用了。

4、自己来写一个控制器类

我们来自己编写一个控制器类,添加一个类,选择API控制器-空:
在这里插入图片描述

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace websiteAPItest.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        [HttpGet(Name = "Hello")]
        public string SayHello()
        {
            return "welcome to asp.net core web api";
        }
    }
   
}

在这里插入图片描述
文章原出处:
https://blog.csdn.net/haigear/article/details/143208403

在这里插入图片描述

5、设置字段的名称大小写

前面我们应该发现了一个小问题,那就是所有的属性在jason文件中都是小写,我们实际在使用的时候如果是需要区别大小写的,那就需要我们去一个个修正,尤其是与数据库访问结合的时候就会出错,那太麻烦了,这里微软也给出了一个设置的方法来解决这样的问题。
我们来看看没有修正之前的状况:
在这里插入图片描述
首先在依赖中引入Microsoft.AspNetCore.Mvc.NewtonsoftJson,
在这里插入图片描述
同时,在程序中引入 然后在program.cs中将builder.Services.AddControllers()x修改为下面的代码即可。
using Microsoft.AspNetCore.Mvc.NewtonsoftJson;

builder.Services.AddControllers().AddNewtonsoftJson(options => { 

options.SerializerSettings.ContractResolver=new DefaultContractResolver();

});

修改后,显示效果如下:
在这里插入图片描述

7、添加过滤器

我们在获取一个刚刚初始化类的实例对象时往往获得的都是空值,但对于我们的小程序而言,可能就比较麻烦,好多的空值会引起错误,或者也缺乏辨识度,比如字符串类型的API给出的默认值就是string,我们来看看默认设定默认值之前是什么样的效果:
如,我这里有一个PersonalInfo类,我们实现了最简单的控制器,代码如下:

using System;
namespace websiteAPItest.Models
{

    public class PersonalInfo
        {
            public string Name { get; set; }
            public int Age { get; set; }
            public string Gender { get; set; }
            public string Email { get; set; }
            public string PhoneNumber { get; set; }
            public DateTime BirthDate { get; set; }
            public string Address { get; set; }
            public string Occupation { get; set; }
            public string Nationality { get; set; }
        }
}

控制器代码

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using websiteAPItest.Models;

namespace websiteAPItest.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class PersonalInfoController : ControllerBase
    {
        [HttpGet(Name ="getPersonList")]
        
        public IList<PersonalInfo> GetPersonalInfoList(int sid,int eid)
        {
            // 假设这里有一些数据获取逻辑,可以根据实际情况修改
            List<PersonalInfo> personList = new List<PersonalInfo>();
            for (int i = sid; i <= eid; i++)
            {
                personList.Add(new PersonalInfo { Name = $"Person {i}", Age = i % 10 + 20 });
            }
            return personList;
        }
    }
}

在这里插入图片描述

很显然,这里出现了很多的string,这不是我们需要的。我们现在增加一个过滤器来看看:
在这里插入图片描述

显然,那成堆的string消失了。那么我们怎么办到的呢?这就是使用了过滤器,过滤器的增加分为两步:
1、在builder.Services.AddSwaggerGen中添加option

builder.Services.AddSwaggerGen(option =>
{

   option.SchemaFilter<CommSchemaFilter>();

});

2、添加一个过滤器类并实现其接口(过滤器名称自己定),这里我们名称为CommSchemaFilter

using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace websiteAPItest.Assist
{
    public class CommSchemaFilter : ISchemaFilter
    {
        public void Apply(OpenApiSchema schema, SchemaFilterContext context)
        {
            if (schema == null) return;
            var objectSchema = schema;
            foreach (var property in objectSchema.Properties)
            {
                if (property.Value.Type == "string" && property.Value.Default == null)
                {
                    property.Value.Default = new OpenApiString("");
                }
                if (property.Key == "pageIndex")
                {
                    property.Value.Default = new OpenApiInteger(1);
                }
                else if (property.Key == "pageSize")
                {
                    property.Value.Default = new OpenApiInteger(10);
                }
            }
        }
    }
}

8、默认值的设定

虽然过滤掉了那些string,但我们为了防止空值导致程序错误,我们还是需要为刚刚实例化的对象添加默认值,添加默认值的办法有很多,比如在过滤器中用语句判断,这个实现起来比较灵活,但麻烦。下面我们就特性标注的方法来实现它。也就是说在模型类中为每个属性添加特性标注。如:

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace websiteAPItest.Models
{
    public class PersonalInfo
    {
        [Required]
        [StringLength(50)]
        [DefaultValue("张三")]
        public string Name { get; set; }

        [Required]
        [Range(0, 150)]
        [DefaultValue(24)]
        public int Age { get; set; }

        [Required]
        [StringLength(10)]
        [DefaultValue("男")]
        public string Gender { get; set; }

        [Required]
        [EmailAddress]
        [DefaultValue("[email protected]")]
        public string Email { get; set; }

        [Required]
        [Phone]
        [DefaultValue("13788888888")]
        public string PhoneNumber { get; set; }

        [Required]
        [DataType(DataType.Date)]
        [DefaultValue("2000-01-01")]
        public DateTime BirthDate { get; set; }

        [Required]
        [StringLength(100)]
        [DefaultValue("张家口市张家镇张家村张家冲21号")]
        public string Address { get; set; }

        
        [StringLength(50)]
        [DefaultValue("码农")]
        public string Occupation { get; set; }

        [Required]
        [StringLength(30)]
        [DefaultValue("China")]
        public string Nationality { get; set; }
    }
}

效果如下:
在这里插入图片描述
好了,数据基本处理好了,那接下来是我们如何用微信小程序获取到我们需要的数据了。至于我们需要读取数据库中的内容来提供给微信小程序来访问,我们可以后面专门来讲。因为数据里面的内容也算不少了,比如说sqlsugar等ORM框架

文章原出处:
https://blog.csdn.net/haigear/article/details/143208403

二、微信小程序获取数据

1、准备数据

我先偷了个懒,没有使用数据库,我们首先对刚刚的控制器进行了一些改造,令其随机生成了一些个人信息,以供后面的测试使用(当然,你也可以把一些数据写死,这也是没有问题的,只是没有什么新鲜感而已),访问的效果是这样:
在这里插入图片描述
显然有点男女不分,但我们先不管它了,我们继续我们的小程序。

2、建立小程序工程

有过小程序基础的可以直接跳过阅读本节。而且我们也直接建立一个新的页面开始。
在这里插入图片描述
我们在pages文件夹中添加一个新的页面我们叫做PersonalInfo,点击编译旁边的下拉箭头,增加一个编译模式,目的在于把当前编辑仿真的页面修改为刚刚新建立的页面:
在这里插入图片描述

3、页面版面布局

<view class="infoContainer">
   <view class="title">个人信息详情</view>
  <view class="info">
    <view class="titem">姓名:{{currentInfo.Name}}</view>
    <view class="titem">年龄:{{currentInfo.Age}}</view>
    <view class="titem">性别:{{currentInfo.Gender}}</view>
    <view class="titem">邮箱:{{currentInfo.Email}}</view>
    <view class="titem">电话:{{currentInfo.PhoneNumber}}</view>
    <view class="titem">出生日期:{{currentInfo.BirthDate}}</view>
    <view class="titem">地址:{{currentInfo.Address}}</view>
    <view class="titem">职业:{{currentInfo.Occupation}}</view>
    <view class="titem">国籍:{{currentInfo.Nationality}}</view>
  </view>
</view>
  <view class="btn">
    <button bindtap="prevInfo" class="bitem">上一个</button>
    <button bindtap="nextInfo" class="bitem">下一个</button>
  </view>

文章原出处:
https://blog.csdn.net/haigear/article/details/143208403

4、获取数据和页面加载事件

事件主要是页面加载的时候我们通过api获取数据后放置在personalInfoList中,默认的游标我们设置为currentIndex0,onload中

data: {
    personalInfoList: [],
    currentIndex: 0
  },
onLoad: function () {
    // 发起网络请求获取数据
    wx.request({
      url: 'http://localhost:5043/api/PersonalInfo',
      data: {
        sid: 3,
        eid: 6
      },
      success: res => {
        this.setData({
          personalInfoList: res.data,
          currentIndex: 0 // 设置当前索引为第一个元素
        });
        // 如果有数据,显示第一个元素的信息
        if (res.data.length > 0) {
          this.setData({
            // 分别设置各个属性到对应的数据绑定变量中
            'currentInfo.Name': res.data[0].Name,
            'currentInfo.Age': res.data[0].Age,
            'currentInfo.Gender': res.data[0].Gender,
            'currentInfo.Email': res.data[0].Email,
            'currentInfo.PhoneNumber': res.data[0].PhoneNumber,
            'currentInfo.BirthDate': res.data[0].BirthDate,
            'currentInfo.Address': res.data[0].Address,
            'currentInfo.Occupation': res.data[0].Occupation,
            'currentInfo.Nationality': res.data[0].Nationality
          });
        }
      }
    });
  },

这里使用 wx.request获取数据,然后将数据res.data存储在数组中personalInfoList,没有微信小程序基础的情参考我前面的博文,这里不再逐一讲解。

5、上下翻页

上下翻页比较简单,就是利用index来改变访问数组的游标。这里大家看看代码就可以了。没有什么技术含量:

prevInfo: function () {
    let index = this.data.currentIndex;
    index = index > 0? index - 1 : this.data.personalInfoList.length - 1;
    this.setData({
      currentIndex: index
    });
    // 更新显示的信息
    this.setData({
      'currentInfo.Name': this.data.personalInfoList[index].Name,
      'currentInfo.Age': this.data.personalInfoList[index].Age,
      'currentInfo.Gender': this.data.personalInfoList[index].Gender,
      'currentInfo.Email': this.data.personalInfoList[index].Email,
      'currentInfo.PhoneNumber': this.data.personalInfoList[index].PhoneNumber,
      'currentInfo.BirthDate': this.data.personalInfoList[index].BirthDate,
      'currentInfo.Address': this.data.personalInfoList[index].Address,
      'currentInfo.Occupation': this.data.personalInfoList[index].Occupation,
      'currentInfo.Nationality': this.data.personalInfoList[index].Nationality
    });
  },
  nextInfo: function () {
    let index = this.data.currentIndex;
    index = index < this.data.personalInfoList.length - 1? index + 1 : 0;
    this.setData({
      currentIndex: index
    });
    // 更新显示的信息
    this.setData({
      'currentInfo.Name': this.data.personalInfoList[index].Name,
      'currentInfo.Age': this.data.personalInfoList[index].Age,
      'currentInfo.Gender': this.data.personalInfoList[index].Gender,
      'currentInfo.Email': this.data.personalInfoList[index].Email,
      'currentInfo.PhoneNumber': this.data.personalInfoList[index].PhoneNumber,
      'currentInfo.BirthDate': this.data.personalInfoList[index].BirthDate,
      'currentInfo.Address': this.data.personalInfoList[index].Address,
      'currentInfo.Occupation': this.data.personalInfoList[index].Occupation,
      'currentInfo.Nationality': this.data.personalInfoList[index].Nationality
    });
  },
 get currentInfo() {
    return this.data.personalInfoList[this.data.currentIndex];
  }

6、总体的效果为:

在这里插入图片描述
对了,样式我没有特别的去美化,也没有用vant这类UI框架,只为展示一下数据获取,所以,这里就简单的写了一些CSS,代码如下:

/* pages/PersonalInfo/PersonalInfo.wxss */
.infoContainer
{
   display: flex;
   flex-direction: column;
   justify-content: left;
   padding-top: 140rpx;
   margin-left: 80rpx;
}
.title
{
   font-size: large;
   font-weight: 800;
   margin-bottom: 80rpx;
   justify-content: center;
}
.titem
{
  padding: 20rpx;
}
.btn
{
  display: flex;
  flex-direction: row;
  justify-content: left;
  padding-top: 40rpx;

}
.bitem
{
  width: 60rpx; /* 减小宽度 */
  height: 80rpx; /* 减小高度 */
 
   background-color: rgb(236, 248, 248);
   padding: 20rpx;
   margin: 80rpx;
  
}

文章随时可能更新,感兴趣的情关注文章原出处:
https://blog.csdn.net/haigear/article/details/143208403

;