【Core】.net core 3.1 api 返回实体类数据存在null,导致小程序调用接口也直接显示了null,原来要这样设置才可

news/2024/5/19 23:24:34 标签: .netcore, mvc

对接过API接口的小伙伴都知道,接口返回的Json格式数据,有些字段可能会出现null的情况,并且还是个字符串,直接显示在用户界面上给人感觉出bug了

文章目录

      • 【开发环境】
      • 【场景描述】
      • 【返回null值重现】
        • 1)创建新项目
        • 2)项目命名
        • 选择目标框架
        • 4)默认项目结构
        • 5)启动文件Startup
        • 6)创建一个实体类
        • 7)实体序列化
        • 8)默认情况运行效果
        • 9)设置可空类型
      • 【空值处理】
        • 1)安装插件
        • 2)设置自定义类
        • 3)启动类配置
      • 【空值处理效果】
        • 【温故而知新】

返回null值效果

在这里插入图片描述

【开发环境】

操作系统:win11 家庭版
开发工具:Visual Studio 2019
开发框架:.net core 5.0
接口模式:MVC(三层模式:ModelView Controller 模型-视图-控制器)

【场景描述】

在实际项目开发中,我们难免会遇到调用接口返回字段值为null的情况。
如果不做处理,那么直接显示在客户端,会给人一种不专业的感觉,这个也是开发人员需要特别注意的。

【返回null值重现】

以下创建一个.net core 5.0进行场景重现,由于core是功能配置化,
默认情况只添加了部分功能示例,比如:MVC属于独立模块,所以需要配置添加到容器里才能使用

1)创建新项目

选择创建项目的模板:Web应用程序(模型视图控制器)
用于创建包含ASP.NET Core MVC视图和控制器的ASP.NET Core应用程序的项目模板
在这里插入图片描述

2)项目命名

在这里插入图片描述

选择目标框架

在这里插入图片描述

4)默认项目结构

在这里插入图片描述

5)启动文件Startup

.net core 2.1和.net core 3.1的启动文件方法代码还是有区别的,MVC方法都换了,以下是.net core 3.1的启动代码

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        // 配置MVC控制器视图
        services.AddControllersWithViews();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }
        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();
        
        // 配置MVC默认路由         
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

6)创建一个实体类

实体类内容,编号、姓名、年龄,三个字段

7)实体序列化

在这里插入图片描述

8)默认情况运行效果

从下图可以知道常用的值数据类型的默认值

编号类型名称默认值
1int整型0
2string字符串空值
3DateTime时间0000-01-01
4float单精度浮点值0.0
5double双精度浮点值0.0
6decimal精确值0.0
7bool布尔值false
在这里插入图片描述

9)设置可空类型

  • 从下图可知

字符串无需额外说明可空,默认就是可空类型在这里插入图片描述

  • 从下图可知
    在C#开发语言里,设置可空类型标识,是在关键词后面加一个问号后缀,设定可空类型后,所有值默认就是返回null值,到这里就重新了接口返回null值得情况,那么接下来就是解决如何处理这类null值,实际开发中避免不了会有空值null,但是又不能把null返回到客户端显示!
    在这里插入图片描述

【空值处理】

1)安装插件

Nuget搜索安装:Microsoft.AspNetCore.Mvc.NewtonsoftJson
注意版本选择,因为是.net core3.1所以需要选择对应3.1版本,否则会提示版本不一致的错误
在这里插入图片描述

2)设置自定义类

这里只针对字符串为null的情况进行处理
时间、布尔值、整型、浮点等数据类型,如果要处理,那么应该统一转换成字符串类型,然后和前端人员对接好即可

using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace NullValue
{
    /// <summary>
    /// DefaultContractResolver,默认解析器类来源于Newtonsoft.Json.dll
    /// </summary>
    public class NullDefaultContractResolver : DefaultContractResolver
    {
        /// <summary>
        /// 重新父类方法 - 创建属性
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="memberSerialization">序列化成员</param>
        /// <returns></returns>
        protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
        {
            return type.GetProperties().Select(c =>
            {
                var jsonProperty = base.CreateProperty(c, memberSerialization);
                jsonProperty.ValueProvider = new NullValueProvider(c);
                return jsonProperty;
            }).ToList();
        }
    }

    /// <summary>
    /// IValueProvider,值处理类来源于Newtonsoft.Json.dll
    /// </summary>
    public class NullValueProvider : IValueProvider
    {
        // 反射变量
        private readonly PropertyInfo _propertyInfo;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="memberInfo"></param>
        public NullValueProvider(PropertyInfo propertyInfo)
        {
            _propertyInfo = propertyInfo;
        }

        /// <summary>
        /// 获取Value
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        public object GetValue(object target)
        {
            var result = _propertyInfo.GetValue(target);

            // 整型
            if (_propertyInfo.PropertyType == typeof(int?) && result == null)
            {
                result = 0;
            }

            // 字符串
            if (_propertyInfo.PropertyType == typeof(string) && result == null)
            {
                result = string.Empty;
            }

            // 长整型
            if (_propertyInfo.PropertyType == typeof(long?) && result == null)
            {
                result = 0L;
            }

            // 时间
            if (_propertyInfo.PropertyType == typeof(DateTime?) && result == null)
            {
                result = DateTime.MinValue;
            }

            // 布尔值
            if (_propertyInfo.PropertyType == typeof(bool?) && result == null)
            {
                result = false;
            }

            return result;
        }

        /// <summary>
        /// 设置Value
        /// </summary>
        /// <param name="target"></param>
        /// <param name="value"></param>
        public void SetValue(object target, object value)
        {
            _propertyInfo.SetValue(target, value);
        }
    }
}

3)启动类配置

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();

    services.AddControllers()
    .AddNewtonsoftJson(options =>
    {
        // 自定义返回值处理
        options.SerializerSettings.ContractResolver = new NullDefaultContractResolver();
    });
}

【空值处理效果】

在这里插入图片描述

【温故而知新】

下面简单整理下微软技术Core框架的特点

编号特点描述
1跨平台能够在 Windows、macOS 和 Linux 操作系统上运行
2)紧跟潮流,再不跨平台,市场份额就要被削减了
2部署灵活1)Docker容器上部署
2)IIS上部署
3)独立的托管程序运行
3兼容性.NET Core 通过 .NET Standard 与 .NET Framework、Xamarin 和 Mono 兼容
4开放源代码1).NET Core 平台是开放源代码,使用 MIT 和 Apache 2 许可证。.NET Core 是一个.NET Foundation 项目
2)这个也是个趋势,毕竟java一直以来都是开源,只有开源才能有更多优秀的开发者完善和改进功能,甚至是创新
5Microsoft 支持.NET Core 由 Microsoft该项目提供支持

每天进步一点点,要想成长和进步,只有不断的努力和尝试


http://www.niftyadmin.cn/n/659396.html

相关文章

optparse 模块

一、optparse是专门用来在命令行添加选项的一个模块。支持python2.3及以上版本&#xff0c;从2.7版本之后&#xff0c;python不再更新该模块&#xff0c;2.7之后的版本推荐使用argparse模块。 二、optparse使用一种更加声明式的命令行解析风格&#xff1a;你创建一个OptionPars…

ZipArchive 生成压缩包

压缩多个文件 压缩多个文件&#xff0c;其实就是addFile执行多次&#xff0c;可以通过数组的遍历来实现。 $fileList array(   "c:/wamp/www/log.txt",   "c:/wamp/www/weixin.class.php"); $name time().rand(100,999)..zip; $filename ./Upload/t…

【关键词】简单了解下优化版的关键词匹配回复功能和示例代码

&#x1f389;&#x1f389; 最近chatGPT持续火爆&#xff0c;一路狂飙&#xff0c;对应如何注册和使用的优质文章非常多。 所以&#xff0c;此篇文章除了整理chatGPT文章外&#xff0c;主要是讲解如何获取API Key进行接口的调用&#x1f389;&#x1f389; 目录1、chatGPT解读…

MySQL无法启动重启竟是因为改了Linux主机名

MySQL无法重启、无法关闭、无法启动、无法使用&#xff0c;如果是因为修改了主机名&#xff0c;可以这样解决&#xff1a;关闭掉所有mysql进程&#xff0c;然后在启动一些mysql&#xff01; 有时候&#xff0c;只要执行如下MySQL初始化命令即可解决&#xff1a;/usr/local/mysq…

11.27第二天冲刺记录

&#xfeff;&#xfeff;&#xfeff;&#xfeff;&#xfeff;&#xfeff;&#xfeff;&#xfeff;&#xfeff; 昨天&#xff08;11.27&#xff09;我们都干了啥 小组组员今日完成今日新增遇到困难images2tags刘泽、张一卓人脸情绪性别年龄分析的论文阅读和api的查找。4h工…

BZOJ4894 天赋 【矩阵树定理】

题目链接 BZOJ4894 题解 双倍经验P5297题解 #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<map> #define Redge(u) for (int k h[u],to; k; k ed[k].nxt) #define REP(i,n) for (int i 1; i < (n); i)…

python 自定义异常

#自定义异常 需要继承Exceptionclass MyException(Exception):def __init__(self, *args):self.args args#raise MyException(爆出异常吧哈哈)#常见做法定义异常基类,然后在派生不同类型的异常class loginError(MyException):def __init__(self, code 100, message 登录异常…

Java 高级开发必修知识---内部类

摘自&#xff1a;http://www.cnblogs.com/lsy131479/p/8798912.html Java 内部类分为&#xff1a; 1&#xff09;成员内部类 2&#xff09;静态嵌套类 3&#xff09;方法内部类 4&#xff09;匿名内部类 内部类的共性 1、内部类仍然是一个独立的类&#xff0c;在编译之后内部类…