Liwendong.Frameworks.MvcExtend 1.7.1

dotnet add package Liwendong.Frameworks.MvcExtend --version 1.7.1
                    
NuGet\Install-Package Liwendong.Frameworks.MvcExtend -Version 1.7.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Liwendong.Frameworks.MvcExtend" Version="1.7.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Liwendong.Frameworks.MvcExtend" Version="1.7.1" />
                    
Directory.Packages.props
<PackageReference Include="Liwendong.Frameworks.MvcExtend" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Liwendong.Frameworks.MvcExtend --version 1.7.1
                    
#r "nuget: Liwendong.Frameworks.MvcExtend, 1.7.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Liwendong.Frameworks.MvcExtend@1.7.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Liwendong.Frameworks.MvcExtend&version=1.7.1
                    
Install as a Cake Addin
#tool nuget:?package=Liwendong.Frameworks.MvcExtend&version=1.7.1
                    
Install as a Cake Tool

Liwendong.Frameworks.MvcExtend

MVC 扩展,提供 MVC5(net451/net46/net47/net48)与 ASP.NET Core(netcoreapp3.1/net8.0)的统一异常处理、统一 JSON 返回、模型校验、请求日志、分页结果等基础设施。

主要内容

MVC5(NetFrameworkMvcBaseController)

继承 System.Web.Mvc.Controller 的基类控制器:

  • 统一异常处理(OnException):EasyErrorException 返回业务提示(沿用异常自带的 ResultErrorCode)并按需记录 Tip 日志;ArgumentException 返回参数错误提示并记录 Warn 日志;其他异常返回通用提示"系统异常,请联系相关人员"(ResultErrorCode.Exception),不向客户端暴露内部异常细节,完整信息仅写入 Exception 日志。
  • 统一 JSON 返回:重写 Json(...),全部走 JsonNetResult(Newtonsoft.Json,忽略循环引用、无长度限制)。
  • 快捷方法:JsonResultInfo(...) 系列(含 ResultErrorCode 重载)返回统一 ResultInfo 包装;PageJsonResultInfo(...) 返回分页结果;LargeJson(...) 用于大数据量返回。

ASP.NET Core(MvcBaseController)

继承 Microsoft.AspNetCore.Mvc.Controller 的基类控制器,与 MVC5 基类对等:

  • 统一异常处理:通过实现 IExceptionFilter 接入管道(Core 3.x 的 Controller 已不再提供 OnException 重写点),处理逻辑与 CommonResultExceptionFilter 共用同一实现;同时注册全局过滤器时以先到者为准(均有 ExceptionHandled 判断,不会重复处理)。
  • 快捷方法:与 MVC5 基类一致的 JsonResultInfo(...) / PageJsonResultInfo(...) 系列。
public class HomeController : MvcBaseController
{
    public IActionResult Index()
    {
        return JsonResultInfo(true, new { Name = "test" });
    }
}

MVC5(JsonNetResult)

基于 Newtonsoft.Json 的 JsonResult,解决 MVC5 默认 JavaScriptSerializer 的循环引用与长度限制问题,支持 ignoreNullValue 配置。

异常过滤器(Filter.CommonResultExceptionFilter,Core)

IAsyncExceptionFilter 实现,与两个基类控制器共用 CommonResultExceptionHandler 处理逻辑:

services.AddControllers(options =>
{
    options.Filters.Add<CommonResultExceptionFilter>();
});

响应已开始写入(HasStarted)时跳过写回,处理完成后置 ExceptionHandled = true。

模型校验(Filter.ModelStateValidationFilterAttribute)

ModelState 无效时直接返回统一错误结果(ResultErrorCode.Tips,消息为各字段错误拼接),不再进入 Action:

  • MVC5:继承 ActionFilterAttribute,可直接 [ModelStateValidationFilter] 打在 Controller/Action 上。
  • Core:实现 IActionFilter,可 [ModelStateValidationFilter] 直接使用,也可全局注册 options.Filters.Add<ModelStateValidationFilterAttribute>()。

请求日志(Filter.RequestLogActionFilter)

记录入参、返回值与执行耗时(Tip 级别,LogManage.WriteTipLog):

  • 入参/返回值超过 MaxContentLength(默认 2000 字符)自动截断。
  • 未处理的异常不在此记录(交给异常过滤器,避免重复)。
  • MVC5:可直接 [RequestLogActionFilter] 打在 Controller/Action 上,也可 GlobalFilters.Add(new RequestLogActionFilter()) 全局注册;计时状态存放于 HttpContext.Items,过滤器实例共享安全。
  • Core:options.Filters.Add<RequestLogActionFilter>() 全局注册,或 [TypeFilter(typeof(RequestLogActionFilter))]。

分页模型(Models.PageResult<T>)

继承 ResultInfo<T>(总记录数复用基类 Count),包含 Items(当前页数据)、PageIndex/PageSize/TotalPages 与 HasPreviousPage/HasNextPage,配合基类的 PageJsonResultInfo(...) 使用:

return PageJsonResultInfo(list, pageIndex, pageSize, totalCount);
// 返回:{ Success, Info, Code, Count(总数), Items, PageIndex, PageSize, TotalPages, HasPreviousPage, HasNextPage }

使用注意

  • 未知异常的 Info 不返回 Exception.Message(可能包含 SQL、路径等内部细节),统一为通用提示 TipsResources.Abnormal,如前端依赖具体错误消息排查问题,请改为查看服务端日志。
  • EasyErrorException 的错误码使用异常自带的 ResultErrorCode(默认值即 Tips,未显式指定错误码的调用行为不变)。
  • GetExceptionMethodDescrption(拼写错误的旧方法名)已标记 [Obsolete],请改用 GetExceptionMethodDescription,旧方法在后续大版本中移除。
  • Core 基类控制器与异常过滤器同时生效时不会重复处理(内部有 ExceptionHandled 判断),推荐二选一:要么继承 MvcBaseController,要么全局注册 CommonResultExceptionFilter。
  • Core 侧 JsonResultInfo/PageJsonResultInfo 返回的 JsonResult 由宿主的 JSON 配置决定序列化方式(默认 System.Text.Json,调用 AddNewtonsoftJson() 后为 Newtonsoft.Json);异常过滤器内部固定使用 Newtonsoft.Json 序列化 ResultInfo。

更新日志

1.7.0 (2026-10-15)

新增

  • 目标框架扩展为 net8.0;netcoreapp3.1;net451;net46;net47;net48(新增 net8.0 与 net47):ASP.NET Core 侧经共享框架 Microsoft.AspNetCore.App 引用编译(源码沿用 #if NETCOREAPP3_1_OR_GREATER 条件编译,自动覆盖 net8.0),MVC5 侧沿用 Microsoft.AspNet.Mvc 5.3.0;无行为变更。

1.6.0 (2026-10-10)

新增

  • Core 版基类控制器 MvcBaseController:与 MVC5 NetFrameworkMvcBaseController 对等,提供统一异常处理(实现 IExceptionFilter 接入,Core 3.x 无 OnException 重写点)与 JsonResultInfo/PageJsonResultInfo 快捷方法。
  • 模型校验过滤器 ModelStateValidationFilterAttribute(MVC5/Core 双实现):ModelState 无效时直接返回 ResultErrorCode.Tips 的统一错误结果,字段错误拼接为提示消息。
  • 请求日志过滤器 RequestLogActionFilter(MVC5/Core 双实现):记录入参、返回值与执行耗时(Tip 级别),超长内容截断(MaxContentLength,默认 2000);未处理异常不重复记录。
  • 分页模型 PageResult<T>:继承 ResultInfo<T>,提供 Items/PageIndex/PageSize/TotalPages/HasPreviousPage/HasNextPage,两端基类配套 PageJsonResultInfo(...)。
  • 基类 JsonResultInfo 新增 ResultErrorCode 重载(含带数据版本),与 EasyErrorException.ResultErrorCode 配合直接返回错误码。

优化

  • 两端异常处理逻辑收敛到公共的 CommonResultExceptionHandler(映射 ResultInfo + 日志),MVC5 基类、Core 基类、Core 异常过滤器三处复用,消除重复代码。
  • MVC5 基类 EasyErrorException 的日志级别由 Warn 统一为 Tip(与 Core 过滤器一致),controller_action 作为 events,方法描述写入 keyword。

1.5.0 (2026-10-10)

修复

  • CommonResultExceptionFilter 未标记异常已处理:OnExceptionAsync 之前未设置 ExceptionHandled = true,异常会继续冒泡导致响应被二次写入、状态码被覆盖;现已修复。
  • CommonResultExceptionFilter 响应写入未等待:Response.WriteAsync 的 Task 之前被直接丢弃,现改为 await;并增加 HasStarted 判断,响应已开始时不再写回。
  • 异常信息泄露:MVC5 基类与 Core 过滤器之前把未知异常的 Exception.Message 原样返回给客户端(可能包含 SQL、路径等内部细节),现统一返回通用提示"系统异常,请联系相关人员",完整信息仅写入日志。
  • Action 重载导致二次异常:GetExceptionActionDescription 中 GetMethod 遇到重载会抛 AmbiguousMatchException,现统一由 ExceptionDescribeHelper 捕获处理。
  • MVC5 错误码固定为 Tips:EasyErrorException 分支现使用异常自带的 ResultErrorCode,与 Core 过滤器行为一致。

优化

  • 删除 CommonResultExceptionFilter 中约 40 行注释掉的死代码。
  • 异常方法描述逻辑(Action/TargetSite → Description)抽取为公共的 ExceptionDescribeHelper,MVC5 与 Core 两端复用,消除重复代码。
  • LargeJson(...) 由 MVC5 默认的 JavaScriptSerializer 改为 JsonNetResult(Newtonsoft.Json),与 Json(...) 重写行为一致,避免两套序列化规则。
  • Core 过滤器中的 Action 名称正则改为 static readonly Regex(Compiled),避免每次请求重新编译。
  • JsonNetResult:ArgumentNullException("context") 改为 nameof(context),补齐 XML 注释。

新增

  • 新增正确拼写的 GetExceptionMethodDescription(MVC5 基类与 Core 过滤器均有);旧的 GetExceptionMethodDescrption 标记 [Obsolete]。
  • 目标框架新增 net48,与 Liwendong.Frameworks 依赖链保持一致。
  • 包内附带 README.md 与 XML 文档注释(GenerateDocumentationFile),消费方获得 IntelliSense;显式声明 Newtonsoft.Json 依赖。

版本历史

1.7.1 (2026-10-17)

  • 修复:CommonResultExceptionFilter 改 try/finally 置位 ExceptionHandled(写响应抛异常时标记不再失效);MvcBaseController.OnException 补 response.HasStarted 判断;NetFrameworkMvcBaseController.OnException 的 ExceptionHandled=true 移入真正处理分支
  • 修复:CommonResultExceptionHandler 日志调用包 try/catch 兜底(失败输出 Trace),日志设施异常不再打断异常处理链
  • 修复:CommonResultExceptionFilter 的正则补 matchTimeout(5 秒)
  • 修复:Core 版 ModelStateValidationFilterAttribute 补 [AttributeUsage(Class | Method)]
  • 修复:PageResult 对 pageSize/totalCount 增加负数校验(按 0 处理)
  • 优化:RequestLogActionFilter 入参/返回值日志对 password/pwd/token/secret/phone/mobile 等敏感字段值脱敏为 ***(字段名列表可静态配置);JsonNetResult 注明 Data==null 时不写响应体的历史行为
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp3.1 is compatible. 
.NET Framework net451 is compatible.  net452 was computed.  net46 is compatible.  net461 was computed.  net462 was computed.  net463 was computed.  net47 is compatible.  net471 was computed.  net472 was computed.  net48 is compatible.  net481 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.7.1 89 10/20/2026
1.4.0 294 9/1/2025
1.3.0 315 8/26/2025
1.2.2 201 7/29/2025
1.2.1 199 7/29/2025
1.2.0 198 7/29/2025
1.0.4 633 8/8/2022
1.0.3 627 6/23/2022
1.0.2 682 6/23/2022
1.0.1 598 6/23/2022
1.0.0 818 6/18/2021