使用FluentValidation进行前端和服务端验证

FluentValidation与DataAnnotations对比分析 FluentValidation 在代码组织、复杂逻辑支持、可测试性等方面优于 DataAnnotations,适合中大型项目;而 DataAnnotations 适合简单场景,快速实现基本验证。根据项目需求灵活选择即可。,它通过流畅的接口(Fluent API)和 lambda 表达式来定义验证规则,使验证逻辑更清晰、灵活且易于维护。与传统的 DataAnnotations(通过属性标记验证)相比,它在复杂场景中更具优势。简单规则(如必填、格式)足够,但复杂逻辑受限。等属性直接在模型类中定义规则。 阅读详情

luent Validation 翻译为:流畅验证
 
  开源Codeplex其主页简介:该组件是一个轻量级的.NET类库,使用流畅的接口定义和lambda表达式为构建一个业务类的验证规则(A small validation library for .NET that uses a fluent interface and lambda expression for building validation rules for you business objects.)

 

将其应用到我们的项目中,首先新建一个业务实体类。注意需要引用 FluentValidation.dll 和 FluentValidation.Mvc;

  [Validator(typeof(BankCardValidator))]
    public class BankCardModel
    {
        public string AccountCurrency { get; set; }
        /// <summary>
        /// 汇款单号
        /// </summary>
        public string RemitOrderNo { get; set; }

        /// <summary>
        /// 汇款交易号
        /// </summary>
        public string TradeNo { get; set; }

        /// <summary>
        /// 汇款人账户
        /// </summary>
        public string RemittorAccount { get; set; }
        /// <summary>
        /// 汇款人姓名
        /// </summary>
        public string RemittorName { get; set; }
        /// <summary>
        /// 汇款方式
        /// </summary>
        public string RemitWay { get; set; }
        /// <summary>
        /// 汇款金额
        /// </summary>
        public decimal RemitAmount { get; set; }

    }

然后是验证类

public class BankCardValidator : AbstractValidator<BankCardModel>
{
    public BankCardValidator()
    {
            RuleFor(x => x.AccountCurrency).NotEmpty().WithMessage("请输入AccountCurrency");
            RuleFor(x => x.RemitAmount).NotEmpty().WithMessage("请输入RemitAmount");
            RuleFor(x => x.RemitOrderNo).NotEmpty().WithMessage("请输入RemitOrderNo");
            RuleFor(x => x.RemittorName).NotEmpty().WithMessage("请输入RemittorName");
     }
}

 

如果需要在页面上使用,需要辅以 jquery.validate.min.js 和 jquery.validate.unobtrusive.js 两个js验证插件

 

由于其不是ASP.NET MVC的默认验证规则类库,我们就需要注册到ASP.NET MVC的验证规则库中

FluentValidationModelValidatorProvider provider = new FluentValidationModelValidatorProvider(new AttributedValidatorFactory());
ModelValidatorProviders.Providers.Add(provider);
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

最后出来的效果就是这样哒

 

 本文引用自:https://www.jb51.net/article/57904.html

C# FluentValidation 入门指南:让验证变得简单又优雅 FluentValidation 还允许你定义自定义的验证逻辑。🎉 恭喜你完成了这篇深入浅出的 FluentValidation 入门指南!现在你已经掌握了使用 FluentValidation 进行基本的数据验证。记得不断练习,让自己的技能更加熟练!🚀。 阅读详情

相关推荐

5分钟掌握FluentValidation?C#开发者的数据验证新宠

通过本文,你将深入了解如何使用FluentValidation来简化和增强你的数据验证逻辑。希望这篇文章能激发你的兴趣,并帮助你在日常开发中更好地利用FluentValidation提升数据验证的质量和效率!FluentValidation是一个轻量级、灵活且易于使用的.NET库,专门用于构建复杂的验证规则。现在,我们需要对这个类进行数据验证,确保产品的名称符合特定的格式(例如,不能包含数字),并且价格必须是正数。现在,我们需要对这个类进行数据验证,但验证规则取决于订单金额是否超过1000元。

java专栏 1168

FluentValidation验证教程

Must如果您想灵活控制可重用的验证器, 则可以使用Must方法编写自定义规则,此方法允许您手动创建与验证错误关联的实例。} });} }} });} }此方法的优点是它允许您为同一规则返回多个错误。在某些情况下, 针对某些属性的验证逻辑非常复杂, 我们希望将基于属性的自定义逻辑移动到单独的类中,可通过重写类来完成。if(list!} }继承时, 必须重写IsValid方法,此方法接受一个对象, 并返回一个布尔值, 指示验证是否成功,可通过Instance。

极客神殿 2289

ASP.NET Core WebApi中使用FluentValidation验证数据模型的方法

介绍 验证用户输入是一个Web应用中的基本功能。对于生产系统,开发人员通常需要花费大量时间,编写大量的代码来完成这一功能。如果我们使用FluentValidation构建ASP.NET Core Web API,输入验证的任务将比以前容易的多。 FluentValidation是一个非常流行的构建强类型验证规则的.NET库。 配置项目 第一步:下载FluentValidation 我们可以使用Nuget下载最新的 FluentValidation 库 PM> Install-Package FluentValidation.AspNetCore 第二步:添加FluentValidatio

FluentValidation在C#中是怎么进行数据验证的

介绍FluentValidation 是一个基于 .NET 开发的验证框架,用于构建强类型验证规则的 .NET 库。开源免费支持 .Net所有平台 包括.NetFramework和.Net...

dotNET跨平台 826

【线粒体基因组数据提交实战】从注释校验到GenBank批量入库的避坑指南

本文详细介绍了线粒体基因组数据从注释校验到GenBank批量上传的全流程避坑指南。重点解析了GB2sequin工具的正确使用方法、TBL注释文件的精修技巧,以及BankIt平台提交的隐藏要点,帮助科研人员高效完成NCBI数据提交,特别适合需要批量上传线粒体基因组数据的研究者。

weixin_28726671的博客 442

Python主要智能优化算法库汇总

最近几年简单浏览和对比了一些智能算法的库。现将各种库的主要信息、相关优缺点简单整理如下,各位同学可根据自己的需求和喜好进行选择。 文章目录1、DEAP2、mealpy3、scikit-opt (国产良心)4、Geat2(国产用心)5、pygmo26、pyswarms7、SciPy(想不到吧)小结 1、DEAP 项目地址:https://github.com/DEAP/deap 安装: pip install deap 优点: 起点高,发表在Journal of Machine Learning Rese

半个冯博士 2万+

FluentValidation基本用法

一、基本使用 二、在FluentVaildation中注册服务

weixin_57062986的博客 531

【校园网代理连接问题】已解决,“该设备或资源(Web 代理)未设置为接受端口“7890”上的连接“

我遇到这个问题很多次。每次都是vpn的问题,不止通俗意义上的梯子(clash之类的),还包括校园网vpn。点击“ 拨号和虚拟专用网络设置”中的“设置”, 关闭代理服务器。在打开vpn后或者关闭vpn后无法浏览网页,网页诊断显示“关闭“手动设置代理”中的“使用代理服务器”,关闭对应的本地代理即可。

聆雨。 1万+

使用 FluentValidation 实现数据校验、验重

最近项目里用到了 FluentValidation 对网站用户输入的数据进行了验证,使用起来比较舒服,下面整理一下项目中集成的过程。 需要集成的项目是一个 asp.net core 2.1 版本的项目。第一步,安装 FluentValidation.AspNetCore,VS会自动安装依赖的 FluentValidation、DI 等包。安装完成后,找到你要验证的数据类,比如我这里是一个修改密码...

叮当的博客 5548

微信小程序 - error_msg:net::ERR_CONNECTION_RESET“(“errno“:600001,“errMsg“:“uploadFile:fail errcode:-101)

"errno":600001,"errMsg":"uploadFile:fail errcode:-101 cronet_error_code:-101 error_msg:net::ERR_CONNECTION_RESET"微信小程序,微信小程序wx.uploadFile报错,uniapp微信小程序uni.uploadFile上传文件报错,微信小程序调用wx.uploadFile返回错误ERR_CONNECTION_RESET,如何解决这个问题,上传图片出现报错,小程序上传视频报错,上传文件出现报错,如何

🏆 前端领域优质创作者 5410

YOLOv8改进策略【Neck】| BiFPN:双向特征金字塔网络-跨尺度连接和加权特征融合

可扩展的高效物体检测BiFPN(加权双向特征金字塔网络)

Limiiiing的博客 1081

SlimMessageBus FluentValidation 插件实战:消息生产端与消费端双向校验

SlimMessageBus 是一款轻量级的 .NET 消息总线框架,而 SlimMessageBus.Host.FluentValidation 插件为它带来了强大的消息校验能力。借助这个插件,你可以在消息生产端(Publish/Send 发出前)和消费端(投递给消费者/处理器前)对消息做双向校验,让非法消息在进入系统之前就"原路返回",避免脏数据污染下游业务。本文带你快速上手这套消息校验机制。

gitblog_00702的博客 484

作物生长模型Oryza V3实战9:控制文件参数详解

control.dat是ORYZA水稻模型的核心配置文件,主要包含三部分:1)基础参数设置与模拟时间定义;2)关键文件路径配置,包括土壤参数文件(soil.sol)、作物参数文件(cultivar.crp)、田间管理文件(manage.exp)及气象数据目录,同时指定输出结果文件(res.dat)和运行日志(model.log);3)可选参数和输出控制选项。该文件通过关联各类输入数据(气象、土壤、品种特性等)和输出结果,实现模型运行的全流程控制,支持参数调整后继续模拟和中断恢复功能。

220

使用FluentValidation添加数据验证

最近开始研究nopCommerce框架,发现其验证使用FluentValidation组件进行Model验证,很是方便。对于Model验证的问题一直都困扰着我,既不想在实体模型上加特性,加个ViewModel的话,WebAPI要用也不好复用,也不太想放在Service层,放在Service层的话,还要引用MVC及其他MVC相关,个人感觉不好。现在有了FluentValidation,我觉得至少以上...

弑十四的博客 2604

基于泰勒展开改进的物理信息神经网络

基于泰勒展开改进的物理信息神经网络

天天酷科研的博客 503

爬虫反爬:一文掌握 BotBrowser 的原理和使用(能绕过很多验证码的指纹浏览器)

BotBrowser是使用经过修改的Chromium内核(修改Chromium的C++源代码)的隐形浏览器,可靠地绕过Cloudflare、Shape、PerimeterX、Datadome、Akamai、Kasada、hCaptcha和reCAPTCHA。BotBrowser是一个跨平台的自动化工具,它重新定义了web自动化。专为爬虫、RPA(机器人流程自动化)和 Web 测试设计。与 Puppeteer/Selenium 不同,它通过无头模式(Headless)和API 级控制。

数据知道的博客 1万+

.net使用FluentValidation进行服务端验证。

背景 最近使用asp.mvc 做一个在线口语系统项目,在服务端验证问题遇到了一些小问题。 自己根据数据库表user定义一个数据库表实体对象UserDbEntity 1 [Table("User")] 2 public class UserDbEntity : DbEntityModelBase 3 { ...

diedi5902的博客 234

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

FluentValidation.Blazor:为Blazor表单验证注入强大动力

FluentValidation.Blazor:为Blazor表单验证注入强大动力 在现代Web开发中,表单验证是不可或缺的一部分。然而,传统的验证方式往往难以满足复杂业务需求。今天,我们向您推荐一款强大的开源项目——FluentValidation.Blazor,它为Blazor应用带来了全新的验证体验。 项目介绍 FluentValidation.Blazor 是一个基于 FluentVali...

gitblog_00440的博客 905

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Ant Design Blazor 中 FluentValidation 验证组件的使用问题解析

在 Blazor 企业级应用开发中,表单验证是不可或缺的重要环节。Ant Design Blazor 作为基于 Ant Design 设计体系的 Blazor 组件库,提供了强大的表单验证功能。然而,许多开发者在集成第三方验证库如 FluentValidation 时遇到了各种问题。本文将深入解析 Ant Design Blazor 中 FluentValidation 的使用问题,并提供完整的解...

gitblog_01418的博客 407

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

FluentValidation 入门实战:用 AbstractValidator 与 RuleFor 构建强类型验证规则

FluentValidation 是面向 .NET 的流行验证库,它以**流式接口(fluent interface)**与 **Lambda 表达式**为核心,为业务对象编写强类型(strongly-typed)验证规则。本文以仓库内 [src/FluentValidation/README.md](https://link.gitcode.com/i/d2f2cdddeafdea1ba0984

gitblog_00366的博客 348

FluentValidation 高级扩展点实战:PreValidate 钩子、RootContextData 与自定义验证异常

**导读**:本文基于 FluentValidation 官方文档 [docs/advanced.md](https://link.gitcode.com/i/df0ae42fb2452784a99d0b472026f080) 展开,深入讲解三个日常开发中不常用、但能在特定场景下显著提升框架可扩展性的高级特性:每次验证前都会触发的 `PreValidate` 钩子、用于向验证管线注入任意数据的 `

gitblog_00485的博客 960

Blazor Server vs WebAssembly:Blazored.FluentValidation 两种托管模型的验证器配置指南

在 Blazor 开发中,表单校验几乎是每个页面的刚需,而 **Blazored.FluentValidation** 正是把 FluentValidation 无缝接入 Blazor 表单的最佳方案之一。不过很多新手在配置时都会遇到同一个困惑:**Blazor Server 和 Blazor WebAssembly 两种托管模型下,验证器的配置方式似乎不太一样?** 这篇指南将从两种托管模型的核

gitblog_00914的博客 329

FluentValidation 规则组合实战:用 Include 拆分、复用与组装验证逻辑

规则验证逻辑随着业务复杂度增长,往往会膨胀成一个数百行的巨型验证器。FluentValidation 提供了 `Include` 机制,让你可以把针对**同一模型类型**的验证规则拆分到多个独立的验证器类中,再像其他语言中的 trait / mixin 一样组合起来。本文以官方文档 [docs/including-rules.md](https://link.gitcode.com/i/7b1f4

gitblog_00592的博客 150

FluentValidation 继承验证(Inheritance Validation)完全指南:按运行时类型分派子验证器

本篇技术指南聚焦 FluentValidation 提供的 `SetInheritanceValidator` 多态验证能力:当待校验属性声明为基类或接口类型时,如何根据其**运行时实际类型**自动选择并执行对应的子类验证器。读完本文,你将掌握在单体对象与集合元素上配置继承验证的完整写法、惰性构造回调重载、规则集(RuleSet)组合方式,以及该机制在 [PolymorphicValidator

gitblog_00182的博客 81

探索 MicroElements.Swashbuckle.FluentValidation:简化API验证与文档化的魅力

探索 MicroElements.Swashbuckle.FluentValidation:简化API验证与文档化的魅力 在开发高质量的Web API时,准确且高效的请求验证和详尽的API文档是至关重要的。今天,我们将深入探讨一个强大的开源工具——MicroElements.Swashbuckle.FluentValidation,它将FluentValidation的灵活性引入到Swagger(...

gitblog_00346的博客 308
上一篇: 记一次时间查询转UTC时间筛选不正确的问题
下一篇: 项目中涉及到金额操作时,应注意的问题
oopts
博客等级 码龄9年 0粉丝 77原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值