2026年.NET笔试题及详细答案_第1页
2026年.NET笔试题及详细答案_第2页
2026年.NET笔试题及详细答案_第3页
2026年.NET笔试题及详细答案_第4页
2026年.NET笔试题及详细答案_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

2026年.NET笔试题及详细答案考试时长:90分钟满分:100分适用场景:.NET开发岗位(初级/中级)说明:本试卷贴合2026年.NET最新技术栈(.NET8为主),覆盖基础语法、框架核心、Web开发、数据访问、并发编程、性能优化等高频考点,题型全面,答案通俗易懂,贴合实际开发场景,避免理论与实践脱节。一、单项选择题(每题2分,共20分)下列关于C#中值类型和引用类型的描述,错误的是()

A.值类型存储在栈上,引用类型存储在堆上

B.string属于引用类型,但具有值类型的特性(不可变性)

C.结构体(struct)是引用类型,类(class)是值类型

D.装箱是值类型转换为引用类型,拆箱是引用类型转换为值类型

在.NET8中,关于async/await的说法,正确的是()

A.async方法必须返回Task或Task<T>类型,不能返回void

B.await关键字只能在async标记的方法中使用,用于暂停异步操作的执行

C.async/await会开启新的线程,本质和Thread一样

D.异步方法中,await之后的代码会在主线程中执行

ASP.NETCore中,中间件的执行顺序正确的是()

A.异常处理→静态文件→路由→授权→端点

B.静态文件→异常处理→路由→授权→端点

C.路由→异常处理→静态文件→授权→端点

D.授权→路由→异常处理→静态文件→端点

下列关于EntityFrameworkCore(EFCore)的说法,错误的是()

A.EFCore是ORM框架,可实现对象与数据库表的映射

B.IQueryable查询会将LINQ表达式转换为SQL,在数据库端执行

C.IEnumerable查询比IQueryable查询性能更优,适合大数据量场景

D.可通过FluentAPI或数据注解配置实体与数据库的映射关系

.NET依赖注入(DI)中,下列哪种生命周期是“同一HTTP请求内实例唯一,不同请求创建新实例”()

A.Transient(瞬时)

B.Scoped(作用域)

C.Singleton(单例)

D.以上都不是

下列关于字符串操作的说法,正确的是()

A.string是可变的,修改字符串会直接改变原对象

B.StringBuilder是不可变的,每次修改都会创建新对象

C.频繁修改字符串时,使用StringBuilder比string效率更高

D.string.Format方法比插值表达式(${})执行效率更高

关于.NET8的AOT编译,下列描述错误的是()

A.AOT编译是提前将IL代码编译为机器码,启动速度更快

B.AOT编译不支持动态特性(如反射、动态类型)

C.AOT编译生成的可执行文件体积更小,适合跨平台部署

D.ASP.NETCore应用使用AOT编译后,可提升请求处理性能

下列哪种集合类底层使用红黑树实现,适合有序查找场景()

A.List<T>

B.Dictionary<TKey,TValue>

C.SortedDictionary<TKey,TValue>

D.ConcurrentDictionary<TKey,TValue>

关于C#中ref和out关键字的区别,正确的是()

A.ref参数在传递前必须初始化,out参数无需初始化

B.out参数在传递前必须初始化,ref参数无需初始化

C.ref和out参数都必须在传递前初始化

D.ref和out参数都无需在传递前初始化

在高并发场景下,下列哪种方式能有效避免线程安全问题()

A.使用ArrayList存储共享数据

B.使用lock关键字对共享资源加锁

C.使用static变量存储共享数据

D.不做任何处理,依赖.NET自动线程安全

二、多项选择题(每题3分,共15分,多选、少选、错选均不得分)下列属于C#中值类型的有()

A.int

B.string

C.DateTime

D.struct

E.object

ASP.NETCore中,常用的中间件有()

A.异常处理中间件

B.跨域中间件(CORS)

C.身份验证中间件

D.路由中间件

E.静态文件中间件

EFCore中,查询数据的方式有()

A.LINQtoEntities

B.原生SQL语句

C.存储过程

D.批量插入

E.延迟加载

关于.NET多线程编程,下列说法正确的有()

A.Thread是操作系统级线程,开销较大

B.Task基于线程池,开销较小,适合高并发场景

C.ThreadPool可自动管理线程,避免手动创建线程的开销

D.ConcurrentDictionary是线程安全的字典,无需手动加锁

E.多线程中,共享资源必须加锁,否则会出现线程安全问题

下列属于.NET性能优化手段的有()

A.禁用EFCore的变更跟踪(AsNoTracking)

B.使用缓存(MemoryCache、Redis)

C.频繁字符串操作使用StringBuilder

D.数据库查询使用索引优化

E.尽量使用同步方法,避免异步方法的开销三、判断题(每题1分,共10分,对的打√,错的打×)C#中,抽象类(abstractclass)可以有构造函数,接口(interface)不能有构造函数。().NET中的垃圾回收(GC)会自动回收所有对象,包括静态对象和非托管资源。()ASP.NETCore是跨平台的,可以运行在Windows、Linux、MacOS上。()EFCore中,延迟加载会导致N+1查询问题,影响性能。()string.IsNullOrEmpty和string.IsNullOrWhiteSpace的功能完全一样,都能判断字符串是否为空或空白。().NET8的最小API比传统的MVC控制器更简洁,适合简单的API开发场景。()多线程中,lock关键字可以锁定任意类型的对象,包括值类型。()依赖注入的核心思想是“控制反转”,将对象的创建权交给容器,降低耦合度。()Redis可以用来替代Session和Cookie,解决Session丢值和Cookie不安全的问题。()C#中,new关键字既可以用来创建对象,也可以用来隐藏基类的方法。()四、填空题(每空1分,共15分).NET中,垃圾回收(GC)采用________回收机制,分为0代、1代、2代,主要回收________上无引用的对象。ASP.NETCore中,自定义中间件需要实现________接口,或使用________委托的方式编写。EFCore中,________方法用于禁用变更跟踪,提升只读查询的性能;________方法用于只查询需要的字段,避免查询所有字段。C#中,________关键字用于声明一个不能被继承的类;________关键字用于声明一个必须被重写的方法。.NET依赖注入的三种生命周期分别是________、________、________。处理几十万条并发数据时,可使用________或________来保证数据操作的线程安全。ASP.NETCore中,________特性用于标记API控制器,可自动进行模型验证并返回400错误。五、简答题(每题5分,共20分)简述ASP.NETCore与传统ASP.NET的核心区别(至少3点)。说明.NET依赖注入中Transient、Scoped、Singleton三种生命周期的区别,并分别举例适用场景。简述EFCore中延迟加载、立即加载和显式加载的区别,以及如何避免N+1查询问题。简述.NET8中AOT编译的优势和局限性,以及适用的应用场景。六、编程题(每题10分,共20分)使用C#编写一个方法,接收一个整数数组,返回数组中出现次数最多的元素(若有多个元素出现次数相同,返回第一个出现的元素),要求代码简洁、高效,适配大数据量场景。基于ASP.NETCore8,编写一个简单的用户接口(API),实现以下功能:①新增用户(接收用户名、手机号参数,校验手机号格式);②查询所有用户;③根据ID查询单个用户。要求使用依赖注入、EFCore实现数据访问,代码符合RESTful规范。参考答案及详细解析一、单项选择题(每题2分,共20分)答案:C

解析:结构体(struct)是值类型,类(class)是引用类型,这是C#中最基础的类型区分。A选项表述正确,值类型存栈、引用类型存堆;B选项string是引用类型,但不可变(每次修改都会创建新对象),具备值类型的特性;D选项装箱和拆箱的定义正确。答案:B

解析:A选项错误,async方法可以返回void(多用于事件处理),但不推荐,推荐返回Task/Task<T>;C选项错误,async/await本质是状态机,不一定开启新线程(如await非阻塞操作时,不会开启新线程),与Thread(直接操作操作系统线程)本质不同;D选项错误,await之后的代码执行线程不确定,取决于await的任务是否完成,可能在主线程,也可能在线程池线程。答案:A

解析:ASP.NETCore中间件的经典执行顺序:异常处理(最优先,捕获后续中间件的异常)→静态文件(无需路由匹配,优先返回静态资源)→路由(匹配请求路径)→授权(验证权限,无权限则拦截)→端点(执行具体的控制器/Action)。答案:C

解析:C选项错误,IEnumerable查询会将所有数据加载到内存中再进行筛选(内存端执行),IQueryable查询会将LINQ表达式转换为SQL在数据库端执行,大数据量场景下IQueryable性能更优。A、B、D选项表述均正确。答案:B

解析:Transient(瞬时):每次请求服务都创建新实例;Scoped(作用域):同一HTTP请求内实例唯一,不同请求创建新实例(如EFCore的DbContext默认是Scoped);Singleton(单例):整个应用生命周期内只有一个实例。答案:C

解析:A选项错误,string是不可变的,每次修改都会创建新的string对象;B选项错误,StringBuilder是可变的,修改时不会创建新对象,效率更高;D选项错误,插值表达式(${})是string.Format的语法糖,执行效率基本一致,插值表达式更简洁易读。答案:C

解析:A、B、D选项表述正确;C选项错误,AOT编译会提前将IL代码编译为机器码,生成的可执行文件体积更大(包含机器码),但启动速度更快,适合对启动速度要求高的场景(如控制台应用、云原生应用)。答案:C

解析:A选项List<T>底层是数组,适合随机访问、增删不频繁的场景;B选项Dictionary<TKey,TValue>底层是哈希表,适合根据键快速查找;C选项SortedDictionary<TKey,TValue>底层是红黑树,适合有序查找、排序场景;D选项ConcurrentDictionary<TKey,TValue>是线程安全的字典,底层是哈希表,适合高并发场景。答案:A

解析:ref和out都是按引用传递参数,核心区别:ref参数在传递前必须初始化(传递的是已有变量的引用),out参数无需初始化(传递的是未初始化的变量,方法内部必须赋值后才能返回)。答案:B

解析:A选项ArrayList是非线程安全的,高并发下存储共享数据会出现线程安全问题;B选项lock关键字可对共享资源加锁,保证同一时刻只有一个线程访问共享资源,避免线程安全问题;C选项static变量是全局共享的,高并发下存储共享数据会出现线程安全问题;D选项.NET不会自动保证线程安全,需手动处理。二、多项选择题(每题3分,共15分)答案:ACD

解析:值类型包括:基本数据类型(int、float等)、DateTime、struct、枚举(enum);引用类型包括:string、class、interface、object、数组等。B选项string和E选项object均为引用类型。答案:ABCDE

解析:ASP.NETCore中常用中间件包括:异常处理中间件(UseExceptionHandler)、跨域中间件(UseCors)、身份验证中间件(UseAuthentication)、授权中间件(UseAuthorization)、路由中间件(UseRouting)、静态文件中间件(UseStaticFiles)、端点中间件(UseEndpoints)等。答案:ABC

解析:EFCore查询数据的方式主要有3种:①LINQtoEntities(最常用,通过LINQ表达式查询);②原生SQL语句(通过FromSqlRaw/FromSqlInterpolated方法);③存储过程(通过ExecuteSqlRaw或调用存储过程的LINQ方法)。D选项批量插入是数据操作(新增),不是查询方式;E选项延迟加载是查询的加载机制,不是查询方式。答案:ABCD

解析:A选项正确,Thread是操作系统级线程,创建和销毁开销较大;B选项正确,Task基于线程池,无需手动管理线程,开销小,适合高并发;C选项正确,ThreadPool会自动管理线程的创建、复用和销毁,避免手动创建线程的开销;D选项正确,ConcurrentDictionary是线程安全的字典,内部已实现锁机制,无需手动加锁;E选项错误,并非所有共享资源都需要加锁,如使用线程安全的集合(ConcurrentDictionary、ConcurrentList)时,无需手动加锁。答案:ABCD

解析:A选项正确,禁用EFCore的变更跟踪(AsNoTracking),可减少内存占用,提升只读查询性能;B选项正确,使用缓存(MemoryCache本地缓存、Redis分布式缓存)可减少数据库查询次数,提升性能;C选项正确,频繁字符串操作时,StringBuilder比string效率更高(避免频繁创建新对象);D选项正确,数据库查询添加合适的索引,可提升查询速度;E选项错误,异步方法可提高程序的并发能力,减少线程阻塞,适合I/O密集型场景,并非要尽量使用同步方法。三、判断题(每题1分,共10分)答案:√

解析:抽象类可以有构造函数(用于初始化抽象类的字段/属性,供派生类调用);接口不能有构造函数,也不能有字段、实现方法,只能定义方法、属性、事件的签名。答案:×

解析:GC只能自动回收托管资源(如class对象、string等),无法自动回收非托管资源(如文件句柄、数据库连接、网络连接等);静态对象会一直存在于内存中,直到应用程序结束,GC不会回收静态对象。答案:√

解析:ASP.NETCore是开源、跨平台的框架,基于.NETCoreruntime,可运行在Windows、Linux、MacOS等操作系统上,而传统ASP.NET仅支持Windows。答案:√

解析:延迟加载是指查询主实体时,不主动加载关联实体,当访问关联实体时才会单独查询数据库,这会导致N+1查询问题(1次查询主实体,N次查询关联实体),影响性能,可通过立即加载(Include)或显式加载避免。答案:×

解析:两者功能不同:string.IsNullOrEmpty判断字符串是否为null或空字符串("");string.IsNullOrWhiteSpace判断字符串是否为null、空字符串("")或仅包含空白字符(如空格、制表符),后者判断范围更广。答案:√

解析:.NET8引入的最小API,无需创建控制器类,可直接在Program.cs中通过MapGet、MapPost等方法定义API,代码更简洁,适合简单的API开发场景(如小型接口、微服务接口),复杂场景仍推荐使用MVC控制器。答案:×

解析:lock关键字不能锁定值类型,因为值类型会被装箱(每次装箱都会创建新对象),导致锁失效;lock应锁定引用类型(如object、string,但不推荐锁定string,因为string有驻留机制),通常建议锁定专门用于加锁的object对象。答案:√

解析:依赖注入(DI)的核心是控制反转(IOC),即将对象的创建权从类内部转移到容器(如ASP.NETCore的IServiceCollection),由容器统一管理对象的创建、生命周期和依赖关系,降低类之间的耦合度。答案:√

解析:Redis是分布式缓存,可用于存储用户会话信息(替代Session),避免Session在多服务器部署时丢值;也可存储敏感信息(替代Cookie),避免Cookie存储敏感信息的安全隐患。答案:√

解析:new关键字的两个核心用途:①创建对象(如varuser=newUser());②隐藏基类的方法(如在派生类中用new关键字定义与基类同名的方法,隐藏基类方法,区别于override重写)。四、填空题(每空1分,共15分)答案:分代;堆

解析:.NET的GC采用分代回收机制,根据对象的存活时间分为0代、1代、2代,优先回收存活时间短的对象(0代),提高回收效率;GC主要回收堆上无引用的托管对象,栈上的值类型会随方法执行完毕自动释放。答案:IMiddleware;RequestDelegate

解析:ASP.NETCore自定义中间件有两种方式:①实现IMiddleware接口(需注册到依赖注入容器);②使用RequestDelegate委托(通过Use方法直接编写,更简洁)。答案:AsNoTracking;Select

解析:AsNoTracking方法用于禁用EFCore的变更跟踪,适合只读查询场景,可提升查询性能;Select方法用于投影查询,只查询需要的字段,避免查询所有字段造成的性能浪费。答案:sealed;abstract

解析:sealed关键字用于修饰类,标识该类不能被继承(如string类就是sealed类);abstract关键字用于修饰方法,标识该方法是抽象方法,必须在派生类中重写(抽象方法只能存在于抽象类中)。答案:Transient(瞬时);Scoped(作用域);Singleton(单例)

解析:.NET依赖注入的三种核心生命周期,对应不同的实例创建策略,适配不同的开发场景。答案:ConcurrentDictionary;lock

解析:处理高并发数据时,可使用线程安全的集合(如ConcurrentDictionary),或通过lock关键字对共享资源加锁,保证数据操作的线程安全;也可使用Interlocked类处理简单的数值操作。答案:[ApiController]

解析:[ApiController]特性用于标记ASP.NETCore的API控制器,具备自动模型验证、参数来源自动推断、校验失败自动返回400BadRequest等功能,简化API开发。五、简答题(每题5分,共20分)答案:

1.跨平台支持:ASP.NETCore可运行在Windows、Linux、MacOS等操作系统,传统ASP.NET仅支持Windows;

2.性能更优:ASP.NETCore基于.NETCoreruntime,采用更高效的中间件管道、AOT编译等特性,性能远超传统ASP.NET;

3.内置依赖注入:ASP.NETCore内置依赖注入容器,无需第三方框架,可直接实现控制反转,降低耦合度;传统ASP.NET无内置依赖注入,需手动集成第三方框架;

4.轻量级:ASP.NETCore不再强依赖System.Web模块,可按需引用组件,部署包体积更小,适合云原生、容器化部署;传统ASP.NET依赖System.Web,体积大、冗余多;

5.灵活的中间件:ASP.NETCore的中间件管道可灵活配置,按需添加/移除中间件,控制请求处理流程;传统ASP.NET的HttpModule、HttpHandler机制不够灵活。

(答出任意3点即可得满分,多答不扣分)答案:

1.Transient(瞬时):每次请求服务时,都会创建一个新的实例;生命周期最短,每次获取都是新对象。

适用场景:轻量级、无状态的服务(如工具类、辅助方法类,如日志辅助类、加密辅助类)。

2.Scoped(作用域):同一HTTP请求内,获取服务时始终得到同一个实例;不同HTTP请求,创建新的实例。

适用场景:与请求相关的服务(如EFCore的DbContext、用户上下文信息,确保同一请求内数据一致性)。

3.Singleton(单例):整个应用程序生命周期内,只创建一个实例,所有请求共享该实例。

适用场景:重量级、无状态、全局共享的服务(如配置服务、缓存服务、日志服务,避免频繁创建销毁实例,提升性能)。

注意:避免将Scoped服务注入到Singleton服务中(生命周期倒挂),会导致Scoped服务无法正常释放,引发内存泄漏或数据异常。答案:

1.区别:

-延迟加载:默认开启(需配置),查询主实体时不加载关联实体,当首次访问关联实体时,才会单独查询数据库获取关联数据;优点是按需加载,减少初始查询数据量;缺点是会导致N+1查询问题,影响性能。

-立即加载:通过Include方法,查询主实体时,同时加载关联实体,一次性查询所有需要的数据;优点是避免N+1查询,性能更优;缺点是初始查询数据量较大,适合关联数据必须使用的场景。

-显式加载:先查询主实体,后续通过Entry方法手动加载关联实体;优点是灵活控制加载时机,按需加载关联数据;缺点是需要手动编写加载代码,略繁琐。

2.避免N+1查询的方法:

-使用立即加载(Include),一次性加载主实体和关联实体;

-使用投影查询(Select),只查询需要的字段,避免加载不必要的关联数据;

-禁用延迟加载(在DbContext中配置LazyLoadingEnabled=false),强制手动控制加载时机。答案:

1.优势:

-启动速度更快:提前将IL代码编译为机器码,应用启动时无需即时编译(JIT),启动时间大幅缩短;

-运行性能更优:机器码直接执行,无需JIT编译环节,请求处理速度更快,适合高并发场景;

-减少内存占用:避免JIT编译产生的临时代码,降低内存消耗;

-适合容器化/云原生:编译后的可执行文件可直接运行,无需依赖.NETruntime(自包含部署),部署更便捷。

2.局限性:

-不支持动态特性:如反射、动态类型(dynamic)、LateBinding等,会导致编译失败;

-编译时间更长:AOT编译需要提前将所有代码编译为机器码,编译时间比JIT更长;

-可执行文件体积更大:包含机器码和依赖的库,体积比JIT部署更大;

-部分第三方库不支持:部分依赖反射的第三方库,无法在AOT编译环境中正常运行。

3.适用场景:

-控制台应用、工具类应用(对启动速度要求高);

-云原生、容器化部署的ASP.NETCore应用(提升启动速度和运行性能);

-嵌入式应用(资源有限,需要减少内存占用和启动时间);

不适用场景:依赖反射、动态特性的应用(如插件化应用)。六、编程题(每题10分,共20分)答案:

解析:使用Dictionary统计每个元素的出现次数,遍历数组时记录次数最多的元素,适配大数据量场景(时间复杂度O(n),空间复杂度O(n)),代码简洁高效。

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Linq;

publicclassArrayHelper

{

///<summary>

///查找数组中出现次数最多的元素(若有多个,返回第一个出现的)

///</summary>

///<paramname="array">整数数组</param>

///<returns>出现次数最多的元素</returns>

///<exceptioncref="ArgumentNullException">数组为null时抛出异常</exception>

///<exceptioncref="ArgumentException">数组为空时抛出异常</exception>

publicstaticintFindMostFrequentElement(int[]array)

{

//校验参数,避免空引用和空数组

if(array==null)

thrownewArgumentNullException(nameof(array),"数组不能为null");

if(array.Length==0)

thrownewArgumentException("数组不能为空",nameof(array));

//用于统计每个元素的出现次数

Dictionary<int,int>countDict=newDictionary<int,int>();

intmaxCount=0;//最大出现次数

intresult=array[0];//结果(默认第一个元素)

//遍历数组,统计次数并更新结果

foreach(intnuminarray)

{

if(countDict.ContainsKey(num))

{

countDict[num]++;

}

else

{

countDict[num]=1;

}

//若当前元素出现次数大于最大次数,更新最大次数和结果

//若次数相等,不更新(保证返回第一个出现的元素)

if(countDict[num]>maxCount)

{

maxCount=countDict[num];

result=num;

}

}

returnresult;

}

//测试代码

publicstaticvoidMain()

{

int[]testArray1={1,2,3,2,2,3,1,4,2};

Console.WriteLine(FindMostFrequentElement(testArray1));//输出:2

int[]testArray2={5,5,3,3,5,3,2};

Console.WriteLine(FindMostFrequentElement(testArray2));//输出:5(第一个出现次数最多的)

}

}

评分标准:参数校验(2分)、统计逻辑正确(3分)、返回第一个出现的元素(2分)、代码简洁高效(2分)、有测试代码或注释(1分)。答案:

解析:基于ASP.NETCore8,使用EFCore实现数据访问,依赖注入解耦,符合RESTful规范,包含参数校验(手机号格式),代码结构清晰,可直接运行。

//1.实体类(User.cs)

usingSystem.ComponentModel.DataAnnotations;

namespaceNetTestApi.Entities

{

///<summary>

///用户实体

///</summary>

publicclassUser

{

///<summary>

///用户ID(自增主键)

///</summary>

publicintId{get;set;}

///<summary>

///用户名

///</summary>

[Required(ErrorMessage="用户名不能为空")]

[MaxLength(50,ErrorMessage="用户名长度不能超过50个字符")]

publicstringUserName{get;set;}

///<summary>

///手机号

///</summary>

[Required(ErrorMessage="手机号不能为空")]

[RegularExpression(@"^1[3-9]\d{9}$",ErrorMessage="手机号格式不正确")]

publicstringPhoneNumber{get;set;}

///<summary>

///创建时间

///</summary>

publicDateTimeCreateTime{get;set;}=DateTime.Now;

}

}

//2.DbContext(AppDbContext.cs)

usingMicrosoft.EntityFrameworkCore;

usingNetTestApi.Entities;

namespaceNetTestApi.Data

{

publicclassAppDbContext:DbContext

{

publicAppDbContext(DbContextOptions<AppDbContext>options):base(options)

{

}

//用户表

publicDbSet<User>Users{get;set;}

}

}

//3.接口(IUserService.cs)

usingNetTestApi.Entities;

namespaceNetTestApi.Services

{

publicinterfaceIUserService

{

///<summary>

///新增用户

///</summary>

///<paramname="user">用户信息</param>

///<returns>新增后的用户</returns>

Task<User>AddUserAsync(Useruser);

///<summary>

///查询所有用户

///</summary>

///<returns>用户列表</returns>

Task<List<User>>GetAllUsersAsync();

///<summary>

///根据ID查询单个用户

///</summary>

///<paramname="id">用户ID</param>

///<returns>单个用户(无则返回null)</returns>

Task<User>GetUserByIdAsync(intid);

}

}

//4.接口实现(UserService.cs)

usingMicrosoft.EntityFrameworkCore;

usingNetTestApi.Data;

usingNetTestApi.Entities;

usingNetTestApi.Services;

namespaceNetTestApi.Implements

{

publicclassUserService:IUserService

{

privatereadonlyAppDbContext_dbContext;

//依赖注入AppDbContext

publicUserService(AppDbContextdbContext)

{

_dbContext=dbContext;

}

publicasyncTask<User>AddUserAsync(Useruser)

{

//新增用户

_dbContext.Users.Add(user);

await_dbContext.SaveChangesAsync();

returnuser;

}

publicasyncTask<List<User>>GetAllUsersAsync()

{

//查询所有用户,按创建时间降序

returnawait_dbContext.Users.OrderByDescending(u=>u.CreateTime).ToListAsync();

}

publicasyncTask<User>GetUserByIdAsync(intid)

{

//根据ID查询用户,无则返回null

returnawait_dbContext.Users.FindAsync(id);

}

}

}

//5.控制器(UserController.cs)

usingMicrosoft.AspNetCore.Mvc;

usingNetTestApi.Entities;

usingNetTestApi.Services;

namespaceNetTestApi.Controllers

{

[ApiController]

[Route("api/[controller]")]//RESTful规范,路由:api/User

publicclassUserController:ControllerBase

{

privatereadonlyIUserService_userService;

//依赖注入IUserService

publicUserController(IUserServiceuserService)

{

_userService=userService;

}

///<summary>

///新增用户

///</summary>

///<paramname="user">用户信息(用户名、手机号)</param>

///<returns>新增后的用户</returns>

[HttpPost]//POST请求,对应新增操作

publicasyncTask<IActionResult>AddUser([FromBody]Useruser)

{

//模型验证(自动触发,基于实体类的DataAnnotations)

if(!ModelState.IsValid)

{

returnBadRequest(ModelState);//验证失败,返回400

}

varnewUser=await_userService.AddUserAsync(user);

//返回201Created,包含新增用户信息和访问路径

returnCreatedAtAction(nameof(GetUserById),new{id=newUser.Id},newUser);

}

///<summary>

///查询所有用户

///</summary>

///<returns>用户列表</returns>

[HttpGet]//GET请求,对应查询所有操作

publicasyncTask<IActionResult>GetAllUsers()

{

varusers=await_userService.GetAllUsersAsync();

returnOk(users);//返回200OK,包含用户列表

}

///<sum

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论