.netjava接口使用参数

ASP.NET MVC4 APP接口参数问题
1.因为我们的发送短信验证码的接口暴露被盗刷,所以我们将发送短信接口添加了一个参数密钥 k。
但是,总监要求,不希望用户强制更新,所以当没有更新版本的用户调用发送短信验证码的时候我们应该提示要更新版本才能使用发送短信的功能,但是我们测试时,发现原来的版本调用该接口时,有我们设置的返回值返回,但是却出现了网络错误的提示。
为了用户的体验度,我觉得不应该就这样提示网络错误,而是提示 请您更新版本。
一个原因:加了一个参数,那么久必须将该参数设置成有默认值(也就是说是可选)
另一个原因:返回的数据的类型要一致
经过测试,BUG解除。
MVC4.0网站发布和部署到IIS7.0上的方法
没有更多推荐了,Error 404 (Not Found)!!1
404. That’s an error.
The requested URL /1478/ was not found on this server.
That’s all we know.了解接口_百度文库
您的浏览器Javascript被禁用,需开启后体验完整功能,
享专业文档下载特权
&赠共享文档下载特权
&10W篇文档免费专享
&每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
总评分4.2|
用知识赚钱
试读已结束,如果需要继续阅读或下载,敬请购买
定制HR最喜欢的简历
你可能喜欢vb.net 如何访问数据接口_百度经验
&&&&&&&&&电脑软件vb.net 如何访问数据接口听语音1234567
百度经验:jingyan.baidu.com编程语言与数据库的连接是通过一个接口,达到两者交流,以便两者谈情说爱。百度经验:jingyan.baidu.com1一、接口种类:6种:& & & & 1、ODBC,面向C/C++。& & & & 2、DAO, & 面向VB,操作ACCEss& & & & 3、RDO,上面的加强型& & & & 4、OLE DB& & & & 5、ADO, & & &对OLE DB的加强型& & & & &6、ADO.net, & &ADO的加强型。2二、ADO.net概述:& & & & Ado.net基于XML和离线计算模型。& & & & ADO以Recorderset存储,类似单表,若要多表就要多表连接。必须在线& & & & ADO.net可以在线或离线,DataSet直接可以是多表。& & & & ADO使用Com技术,ADO.net基于XML格式,数据类型更丰富。& & & & &体系结构如下图:ADO.net的两个核心组件:.Net数据提供程序(左)、DataSet(右)。& & & & & .net数据提供程序用来与数据库的连接。包括Connection,Command,DataReader,DataAdapter四个。& & & & & &DataSet用来与XML数据连接。设计的目的是独立于任何数据源的数据访问,可有多种不同数据,也可用于XML数据。& & & & & && & & & & &DataSet& & & & & &它内部用XML描述数据,与平台无关。其内常用对象是DataTable和DataRow等。DataSet通过DataAdapter获得数据,& & & & & &DataAdapter就是DataSet与数据库之间的桥梁,也就是前面的搬运工。它把数据库中的结果集搬运到本地缓存中,这样& & & & & &就可与数据离线,直接处理DataSet,处理完后,再连接,再搬运回数据库。& & & &&& & & & & & DataSet有三个特点:& & & & & & &1、独立性:独立于各数据源。即与数据库不发生关系,专注于处理。& & & & & & & 2、离线连接: &一般是离线,只是返回数据库时,才保持连接。& & & & & & & 3、XML描述: &&DataSet对象是用XML格式表示的关系型数据视图。& & & & & & & 数据提供程序& & & & & & &它提供四个对象,保持与不同数据库连接。& & & & & & &1、SQLServer.net数据提供程序,空间:System.Data.SqlClient, 操作SQl2000或以上版本。& & & & & & & 2、OleDb.net数据提供程序,空间:System.Data.OleDb,主要访问Access,FoxPro等& & & & & & & 3、OracleDB.net数据提供程序,空间:System.Data.OracleClient,支持Oracle8.1.7以上版本。& & & & & & & 4、ODBC.net数据提供程序,空间:System.Data.Odbc3ADO.net的两个核心组件:.Net数据提供程序(左)、DataSet(右)。& & & & & .net数据提供程序用来与数据库的连接。包括Connection,Command,DataReader,DataAdapter四个。& & & & & &DataSet用来与XML数据连接。设计的目的是独立于任何数据源的数据访问,可有多种不同数据,也可用于XML数据。& & & & & && & & & & &DataSet& & & & & &它内部用XML描述数据,与平台无关。其内常用对象是DataTable和DataRow等。DataSet通过DataAdapter获得数据,& & & & & &DataAdapter就是DataSet与数据库之间的桥梁,也就是前面的搬运工。它把数据库中的结果集搬运到本地缓存中,这样& & & & & &就可与数据离线,直接处理DataSet,处理完后,再连接,再搬运回数据库。& & & &&& & & & & & DataSet有三个特点:& & & & & & &1、独立性:独立于各数据源。即与数据库不发生关系,专注于处理。& & & & & & & 2、离线连接: &一般是离线,只是返回数据库时,才保持连接。& & & & & & & 3、XML描述: &&DataSet对象是用XML格式表示的关系型数据视图。& & & & & & & 数据提供程序& & & & & & &它提供四个对象,保持与不同数据库连接。& & & & & & &1、SQLServer.net数据提供程序,空间:System.Data.SqlClient, 操作SQl2000或以上版本。& & & & & & & 2、OleDb.net数据提供程序,空间:System.Data.OleDb,主要访问Access,FoxPro等& & & & & & & 3、OracleDB.net数据提供程序,空间:System.Data.OracleClient,支持Oracle8.1.7以上版本。& & & & & & & 4、ODBC.net数据提供程序,空间:System.Data.Odbc三、ADO.net的五个核心对象& & & &这个说五个是:& & & &Connection对象负责连接数据库& & & &Command对象负责生成执行SQl语句& & & &DataReader对象负责读取数据库的数据& & & & DataAdapter对象负责在Command对象执行完SQL语句后生成并填充DataSet和DataTable。& & & & &DataSet对象负责存取和更新数据。& & & & 1、Connection对象& & & & & & &表示一个数据源的单个连接。4&例一:连接Access的例子:5例二:连接Sqlserver的例子:62、Command对象& & & & & & &它用来执行SQL语句,执行的结果由DataReader和DataAdapter填充到DataSet中,这样就完成 数据库数据操作的工作 。7注1:CommandType有三个:& & & & & & & & & & Text,说明是一个SQL语句,这是默认值,不设置时就是它。& & & & & & & & & & &TableDirect,一个要操作的数据表的名& & & & & & & & & & &StoredProcedure,一个存储过程。& & & & & & &注2:构造函数有四个,用第三个较多。& & & & & &2.1、Command的构造函数,& & & & & & 就是上面的四个方法,这个是重点。& & & & & & 2.2、ExecuteReader方法& & & & & & 通过DataReader类型的对象,应用程序可获得执行SQL命令后的结果集。& & & & & & 这个方法有两种定义:& & & & & & 一是ExecuteReader() :不带参数,直接返回一个DataReader结果集;& & & & & &二是ExecuteReader(CommandBehavior & behavior):根据参数Behavior取值类型,决定DataReader类型。& & & & & & & & & &如果behavior是CommandBehavior.SingleRow,则说明返回的ExecuteReader只是结果集中的第一条数据;& & & & & & & & & &如果behavior是CommandBehavior.SingleResult,则说明只返回在查询结果中多个表里的第一个。& & & & & & & & & &如果behavior是CommandBehavior.SequentialAccess,则说明对于返回的ExecuteReader对象只能顺序& & & & & & & & & & & & & & & &读取它包含的列。一旦读过某列,就不能返回再次读取了,以方便性为代价换取读取数据时的高效率。& & & & & & &无论何结果,ExecuteReader方法返回一个DataReader对象,该对象是一个仅向向的只读数据流,所以主要用来执行& & & & & & & & & & & &基本SQL查询,要求SQL语句返回记录集。& & & & & & &2.2例一:ExecuteReader。& & & & & & &用executeReader返回一个DataReader,然后用它来填充(加载到)另一个对象DataTable中,最后DataTable直接绑定到控件上。82.2例二:利用BindingSource来绑定& & & & & &前面用DataTable绑定数据,下面用BindingSource来绑定。界面一样,代码变化几句:92.3 ExecuteSaclar方法& & & & & & & Scalar,标量,是一个值。一个结果集可能有多个记录,每个记录可能有多个列值。因此,& & & & & & & 该方法返回的是首行首列的一个值,其它值忽略。主要用于那些聚合运算,比如求有多少个记录,总计是多少,等等。10&2.4 ExecuteNonQuery方法& & & & & & & & 即,非查询命令。主要用来执行insert,update,delete和那些没有返回结果集的SQL语句,并返回执行命令后影响的行数。& & & & & & & & &如果insert,update对应的记录不存在,则返回0;如果出错,则返回-1.& & & & & & & & &注意:因为这个用户不知道成功与否,所以要加入一些提示或再次显示原数据库,以便了解执行情况。& & & & & & & & &前面几节有这个大量的例子,不再列出。& & & & & & & & & &2.5 ADO.net事务处理。& & & & & & & & & &前面说了存储过程,存储过程就是一个批处理。& & & & & & & & & &事务也是一个批处理过程,只不过加强版,即要么全部都成功执行,要么全部失败。(SQL自动会控制它)& & & & & & & & & &所以事务有两个作用:& & & & & & & & & & & & & & &一致性:同时进行的查询和更新彼此不会发生冲突,其它用户不会看到发生了变化但尚未提交的数据;& & & & & & & & & & & & & & &可恢复性:一旦故障或失败,数据库会自动地完全恢复未完成的事务(Rollback)。& & & & & & & & & ADO.net中,使用Connection和Transaction对象来控制事务,事务顺序包括:& & & & & & & & & & & & & & & &一、调用Connecton对象的BeginTransaction方法来标记事务的开始。& & & & & & & & & & & & & & & &二、将Transaction对象分配给要执行的Command的Transaction属性;& & & & & & & & & & & & & & & &三、执行所需的命令;& & & & & & & & & & & & & & & &四、调用Transaction对象的Commit方法来完成事务,或调用RollBack方法来取消事务。& & & & & & & & & &ADO.net事务处理的优点:简单、运行速度快、独立于数据库。& & & & & & & & & & & & & & & & & & & & & & & & & & & 缺点:不能跨多个数据库连接。& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & 事务执行建立在数据库的连接层上,所以需要在事务过程中一直保持数据库连接。& & & & & & & & & & 编程流程:& & & & & & & & & & & & & & & & & &事务开始:Connection对象的BeginTransaction()声明开始& & & & & & & & & & & & & & & & & &提交事务:即去执行,用Transaction对象的Commit()方法来提交 && & & & & & & & & & & & & & & & & &回滚事务:即事务失败后的全部恢复,用Transaction对象的RollBack()方法来回滚事务。& & & & & & & & & & & && & & & & & & & & & & 2.5例:事务提交。& & & & & & & & & & &从 这个例子中,可以看到事务是多个SQL语句提交执行(批处理),当如果有一条不成功,则全部恢复(不管以前是否成功)。113、DataReader对象& & & & & & & & 首先说明:DataReader不能实例化,即不能用New。它只能由Command对象ExecuteReader()方法来创建,所以2.2例中没用NEw& & & & & && & & & & & & & &DataReader对象提供向前的、只读数据,所以只能依次来读:& & & & & & & & & & & & & & &DataReader的Read(),提供下一条记录的读取,返回值是布尔值,为真执行成功,为假说明下一条无记录。& & & & & & & & & & & & & & &这些记录是不能修改的。而DataSet因为是离线数据集,在本地内存中缓存,所以是可以任意修改的。&& & & & & & & & & DataReader从数据库中检索只读数据流,存储在客户端的网络缓存当中。在内存当中只存储一行,所以开销小,速度快。& & & & & & & & & 由于数据不在内存中缓存,所以在检索大量数据时,DataReader是一种较好的选择。& & & & & & & & & DataRader还是一个霸王,具有独占性,在已经打开DataReader的情况下,将不能对Connection进行任何操作,所以用完了它就& & & & & & & & & 应及时调用Close()方法关闭。& & & & & & & & & 通过Command对象返回多个结果集,并且通过DataReader对象NextResult()方法来使用。& & & & & & & & & 再次强调它不能New,只能由Command对象的ExecuteReader()方法来创建 。&& & & & & & & & & 创建后,读取DataReader对象中的数据有两种方法:& & & & & & & & & & & & & & &一通过和DataGridView等数据控件绑定,直接输出;& & & & & & & & & & & & & & &二利用循环将数据取出。(即Read()方法进行循环读取)。& & & & & & & & & 例子:用DataReader对象通过循环读取多条记录。124、DataAdapter& & & & & & & & &DataAdapter数据适配器,它就是一个搬运工:从数据源搬运到本地内存中以便来填充DataSet;或者从本地内中数据搬运回到数据源中。& & & & & & & & 这两者的数据可以是相同,也可是不同,DataAdapter会自动匹配,发挥“适配”的作用。& & & & & & & & 从数据源到本地内存,然后再填充就用Fill()方法。& & & & & & & & 从本地内存到数据源,进行数据库的更新用Update()方法。& & & & & & & & & & & & & & & & & & & & & &DataAdapter对象属性属&& 性说&& 明DeleteCommand获取或设置一个语句或存储过程,以从数据集删除记录InsertCommand获取或设置一个语句或存储过程,以在数据源中插入新记录SelectCommand获取或设置一个语句或存储过程,用于在数据源中选择记录UpdateBatchSize获取或设置每次到服务器的往返过程中处理的行数UpdateCommand获取或设置一个语句或存储过程,用于更新数据源中的记录& & & & & & & & & & & & & & & & & & & & & & &DataAdapter方法方法&& & & & & & & & & & & & 说明Dispose&& & & & & & & & 删除该对象Fill&& & & & & & & & & & & & & &用从源数据读取的数据行填充至DataSet对象中FillSchema& & & & & &&将一个DataTable加入到指定的DataSet中,并配置表的模式GetFillParameters&返回一个用于SELECT命令的DataParameter对象组成的数组Update&& & & & & & & & & & & 在DataSet对象中的数据有所改动后更新数据源。& & & & & & &&& & & & & & & & 4.1 & DataAdapter对象的构造函数& & & & & & & 搬运工就是双面间谍,要么向本机的DataSet填充数据,要么就向另一个方向的数据库更新数据。& & & & & & & & & & & & & & & & & & && & & & & & & & & & & & & & & & SqlDataAdapter类的构造函数SqlDataAdapter()&& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &不带参数,&创建SqlDataAdapter对象SqlDataAdapter(SqlCommand selectCommand) & & & & & & & & & & & & & & & & & & & & & selectCommand:指定新创建对象的SelectCommand属性& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &&用参数selectCommand设置其Select Command属性SqlDataAdapter(string selectCommandText,SqlConnection selectConnection)& & & & &&selectCommandText:指定新创建对象的SelectCommand属性值;& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &selectConnection:指定连接对象&& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &用参数selectCommandText设置其Select Command属性值,& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & 并设置其连接对象是selectConnectionSqlDataAdapter(string selectCommandText,String selectConnectionString) & & & & & &&selectCommandText:指定新创建对象的SelectCommand属性值;& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &selectConnectionString:指定新创建对象的连接字符串& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &将参数selectCommandText设置为Select Command属性值,& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & 其连接字符串是selectConnectionString&& & & & & & & 构造函数可以不带参数,或者带1,2,3个参数,由参数可以看到cmd有时超出自己的范围,跑到Connection的功能上去了。& & & & &&& & & & & & & & &4.2 DataAdapter对象的Fill()方法& & & & & & & & &这是搬运工填充本地内存的情况。& & & & & & & & &调用Fill()方法时,DataAdapter将向数据存储区传输一条Select语句,主要用来填充或刷新DataSet,返回值是影响DataSet的行数。& & & & & & & & & &&& & & & & & & & & & & & & & & & & & & & & & & & & & &&& & Fill()方法如下:int Fill (DataSet dataset) & & & & & & & & & & & dataset:需要更新的DataSet& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & 根据匹配的数据源,添加或更新参数所指定的DataSet,返回值是影响的行数int Fill (DataSet dataset, string srcTable) & & & & & & dataset:需要更新的DataSet;& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &srcTable:填充DataSet的dataTable名(就是别名,用户自己命名一个,可以与原表相同)&&& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &根据dataTable名填充DataSet& & & & & & & & &例子:前面已经有了,不再列出,参见:http://blog.csdn.net/dzweather/article/details/8564039& & & & & &&& & & & & & & & & 4.3 DataAdapter的Update()方法 &&& & & & & & & & &这是搬运工更新服务器数据库的情况。& & & & & & & & 调用Update()方法时,DataAdapter将检查参数DataSet每一行的RowState属性,根据RowState属性来检查DataSet里& & & & & & & & &的每一行是否改变及改变的类型,并依次执行所需的Insert,Update,Delete语句,再将改变提交到数据库中,同时& & & & & & & & &返回影响的DataSet的行数据。& & & & & & & & &例子:下面用一个添加一行记录,同时更新DataSet和数据库。& & & & & & & & &里面用到了DataRow,这个用于添加一个新行NewRow,然后给新行加值END经验内容仅供参考,如果您需解决具体问题(尤其法律、医学等领域),建议您详细咨询相关领域专业人士。投票(0)已投票(0)有得(0)我有疑问(0)◆◆说说为什么给这篇经验投票吧!我为什么投票...你还可以输入500字◆◆只有签约作者及以上等级才可发有得&你还可以输入1000字◆◆如对这篇经验有疑问,可反馈给作者,经验作者会尽力为您解决!你还可以输入500字相关经验101703热门杂志第1期你不知道的iPad技巧3812次分享第1期win7电脑那些事6667次分享第2期新人玩转百度经验1424次分享第1期Win8.1实用小技巧2669次分享第1期小白装大神1954次分享◆请扫描分享到朋友圈&&&&&&&&&&&&&
本来想写这个帖子已经很久了,但是公司事情多,做着做着就忘记了。公司因为需要做接口,而且用的还是asp.net的老框架,使用Handler来做,没得办法,自己照着MVC写了一个通过的接口操作模板。
上送json数据,返回的也是json数据。可以像MVC一样自动绑定并可以进行DataAnnotations验证。尽量达到在业务逻辑处理区域不用对上送参数做过多的获取和判断,能一次搞定就一次搞定。
话不多说,上代码!!!
BaseClass:用作接口参数的基类。接口参数类型可以继承该类,也可以不继承,或自己定义其他基类。
public abstract class BaseClass { }
EmptyClass:一个空类。当做一个参数类型传入到接口中,占用地方而已。
public class EmptyClass : BaseClass { }
ModelError:错误消息载体类型。
[Serializable]
public class ModelError {
public ModelError(Exception exception) : this(exception, null) { }
public ModelError(string errorMessage) {
this.ErrorMessage = errorMessage ?? string.E
public ModelError(Exception exception, string errorMessage) : this(errorMessage) {
if (exception == null)
throw new ArgumentNullException("exception");
this.Exception =
public Exception Exception { get; private set; }
public string ErrorMessage { get; private set; }
ModelErrorCollection:错误消息载体集合。
[Serializable]
public class ModelErrorCollection : Collection&ModelError& {
public void Add(string errorMessage) {
base.Add(new ModelError(errorMessage));
public void Add(Exception exception) {
base.Add(new ModelError(exception));
ModelState:模型绑定状态。
/// &summary&
/// 模型绑定状态
/// &/summary&
[Serializable]
public class ModelState {
private ModelErrorCollection _errors = new ModelErrorCollection();
public bool IsValid {
return _errors.Count == <span style="color: #;
public ModelErrorCollection Errors {
ModelBinder:模型绑定抽象类,需要继承此抽象类。用来绑定上送参数并验证的基类。
/// &summary&
/// 模型绑定抽象类,需要继承此抽象类。
/// &/summary&
/// &typeparam name="T"&&/typeparam&
public abstract class ModelBinder&T& where T : class {
protected ModelState _modelS
/// &summary&
/// 模型绑定状态
/// &/summary&
public ModelState ModelState {
if (_modelState == null)
_modelState = new ModelState();
return _modelS
/// &summary&
/// 绑定操作
/// &/summary&
/// &returns&&/returns&
public abstract T Binder();
/// &summary&
/// 验证实体数据合法性。如果有错误,请在ModelState参数中获取。
/// &/summary&
/// &param name="entity"&&/param&
protected void Valide(object entity) {
if (entity == null)
//获取T类型的所有公共属性
Type type = entity.GetType();
PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
if (properties != null && properties.Count() & <span style="color: #) {
//针对每一个公共属性,获取其特性
foreach (var property in properties) {
//如果当前属性为一个自定义类型
if (property.PropertyType != typeof(object) && Type.GetTypeCode(property.PropertyType) == TypeCode.Object) {
this.Valide(property.GetValue(entity, null));
ValideProperty(entity, property);
if (!_modelState.IsValid)
/// &summary&
/// 验证属性的每一个特性约束
/// &/summary&
/// &param name="entity"&&/param&
/// &param name="property"&&/param&
private void ValideProperty(object entity, PropertyInfo property) {
if (entity != null && property != null) {
var attributes = property.GetCustomAttributes(typeof(ValidationAttribute), false);
foreach (ValidationAttribute attribute in attributes)
ValidatePropertyAttribute(entity, property, attribute);
/// &summary&
/// 使用特性对属性进行验证
/// &/summary&
/// &param name="entity"&&/param&
/// &param name="property"&&/param&
/// &param name="attribute"&&/param&
private void ValidatePropertyAttribute(object entity, PropertyInfo property, ValidationAttribute attribute) {
if (entity != null && property != null && attribute != null) {
//找到该属性
//注明:每一个函数都应当具有独立性.
PropertyInfo currentProperty = entity.GetType().GetProperties().Where(p =& p.Name == property.Name).FirstOrDefault();
//判断当前特性是否有IsRequiredInstance字段,这是自定义的特性,用于验证同一个实例中两个不同共有属性的值
PropertyInfo[] pros = attribute.GetType().GetProperties();
if (pros.Where(it =& it.Name == "IsRequiredInstance" && it.PropertyType == typeof(bool)).FirstOrDefault() != null)
attribute.GetType().GetProperty("Instance").SetValue(attribute, entity, null);
if (currentProperty != null) {
var value = currentProperty.GetValue(entity, null);
if (!attribute.IsValid(value))
_modelState.Errors.Add(attribute.ErrorMessage);
BaseHandler:一般处理逻辑的基类。
/// &summary&
/// 一般处理逻辑的基类。
/// &/summary&
/// &typeparam name="T"&请求参数模型&/typeparam&
/// &typeparam name="R"&返回参数模型&/typeparam&
public abstract class BaseHandler&T, R& : ModelBinder&T& where T : class where R : class {
protected readonly IL
public BaseHandler() {
log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public BaseHandler(string typeName) {
if ((typeName ?? "").Trim() != "")
log = LogManager.GetLogger(typeName);
log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
/// &summary&
/// 处理接口API消息
/// &/summary&
/// &returns&&/returns&
public abstract R Process();
/// &summary&
/// 真正需要处理的接口逻辑
/// &/summary&
/// &param name="param"&客户端传过来的请求参数&/param&
/// &returns&&/returns&
protected abstract R DoWork(T param);
IndexHandler:一般业务接口的模板方法处理器。该接口是基础性接口,如果有其他业务需求,请自行另外自定义或继承该接口。
/// &summary&
/// 一般业务接口的模板方法处理器。
/// 该接口是基础性接口,如果有其他业务需求,请自行另外自定义或继承该接口。
/// &/summary&
/// &typeparam name="T"&&/typeparam&
public abstract class IndexHandler&T& : BaseHandler&T, BaseResponseResult& where T : class {
public IndexHandler() : base() { }
public IndexHandler(string typeName) : base(typeName) { }
/// &summary&
/// 对实体模型进行绑定和参数的特性验证
/// &/summary&
/// &returns&&/returns&
public override T Binder() {
//初始化模型
T rc = default(T);
//初始化ModelState
if (_modelState == null)
_modelState = new ModelState();
_modelState.Errors.Clear();
//获取数据
Stream stream = HttpContext.Current.Request.InputS
stream.Seek(<span style="color: #, SeekOrigin.Begin);
byte[] buffer = new byte[stream.Length];
int count = stream.Read(buffer, <span style="color: #, buffer.Length);
if (count & <span style="color: #) {
string requestParam = Encoding.UTF8.GetString(buffer);
//绑定数据
rc = new JavaScriptSerializer().Deserialize&T&(requestParam);
if (rc != null) {
//验证数据合法性
base.Valide(rc);
_modelState.Errors.Add("绑定数据失败!");
_modelState.Errors.Add("请求参数为空!");
catch (Exception ex) {
_modelState.Errors.Add("绑定数据出现错误!");
/// &summary&
/// 处理接口API消息
/// &/summary&
/// &returns&&/returns&
public override BaseResponseResult Process() {
BaseResponseResult rc = new BaseResponseResult(ErrorCode.OperationError);
//绑定请求参数
T requestParam = Binder();
//开启逻辑操作
if (_modelState.IsValid)
rc = DoWork(requestParam);
StringBuilder sbuilder = new StringBuilder();
foreach (var error in _modelState.Errors)
sbuilder.Append(error.ErrorMessage);
rc.SetResult(ErrorCode.InvalideParameter, sbuilder.ToString());
catch (Exception ex) {
rc.SetResult(ErrorCode.SystemError);
rc.returnData = null;
log.Error("Process", ex);
BaseResponseResult:返回结果。
/// &summary&
/// 返回结果
/// &/summary&
public class BaseResponseResult {
public BaseResponseResult() { }
public BaseResponseResult(int returnValue, string returnMsg) {
_code = returnV
_message = returnM
public BaseResponseResult(ErrorCode code, string returnMsg="") {
SetResult(code, returnMsg);
private int _code = <span style="color: #;
private string _message = "";
private string _contentType = "application/json";
/// &summary&
/// 错误码,0表示成功,其他表示失败
/// &/summary&
public virtual int returnValue { get { return _ } }
/// &summary&
/// 错误码,0表示成功,其他表示失败
/// &/summary&
public virtual string returnMsg { get { return _ } }
/// &summary&
/// 返回的数据,json格式
/// &/summary&
public virtual object returnData { get; set; }
/// &summary&
/// 设置返回状态码
/// &/summary&
/// &param name="code"&&/param&
public virtual void SetCode(int code) {
/// &summary&
/// 设置返回状态码
/// &/summary&
/// &param name="code"&&/param&
public virtual void SetCode(ErrorCode code) {
SetResult(code);
/// &summary&
/// 设置返回消息
/// &/summary&
/// &param name="message"&&/param&
public virtual void SetMessage(string message) {
_message =
/// &summary&
/// 设置返回状态码和消息
/// &/summary&
/// &param name="returnValue"&&/param&
/// &param name="returnMsg"&&/param&
public virtual void SetResult(int returnValue, string returnMsg) {
_code = returnV
_message = returnM
/// &summary&
/// &/summary&
/// &param name="code"&ErrorCode代码&/param&
/// &param name="returnMsg"&返回消息。如果此项不输入值,则自动设置默认值!&/param&
public virtual void SetResult(ErrorCode code, string returnMsg="") {
this._code = (int)
this._message = (returnMsg??"").Trim()!=""?returnMsg:ErrorMsg.ErrorMessage[code];
/// &summary&
/// 设置返回消息体
/// &/summary&
/// &param name="obj"&&/param&
public virtual void SetReturnData(params object[] obj) {
if (obj != null && obj.Length & <span style="color: #) {
this.returnData = obj.ToList();
public virtual void SetReturnData(object obj) {
this.returnData =
public virtual void SetContentType(string contentType) {
this._contentType = contentT
/// &summary&
/// 将当前结果转化为JSON字符串
/// &/summary&
/// &returns&&/returns&
public virtual string ToJson() {
return new JavaScriptSerializer().Serialize(this);
public virtual void Response(bool isEnd = true) {
HttpContext.Current.Response.ContentType = _contentT
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
HttpContext.Current.Response.Write(this.ToJson());
if (isEnd)
HttpContext.Current.Response.End();
ErrorCode:返回状态码枚举。
public enum ErrorCode {
/// &summary&
/// 操作错误
/// &/summary&
OperationError = -<span style="color: #,
/// &summary&
/// &/summary&
Success = <span style="color: #,
/// &summary&
/// &/summary&
Failed = <span style="color: #,
/// &summary&
/// 无数据
/// &/summary&
NoData=<span style="color: #,
/// &summary&
/// 不存在此页面
/// &/summary&
NotExistPage=<span style="color: #,
/// &summary&
/// 无权限
/// &/summary&
NoPermission=<span style="color: #,
/// &summary&
/// 未登录
/// &/summary&
NoLogin=<span style="color: #,
/// &summary&
/// 被禁止
/// &/summary&
Forbidden=<span style="color: #,
/// &summary&
/// 请求参数格式不符合要求
/// &/summary&
InvalideParameter = <span style="color: #,
/// &summary&
/// 无此接口
/// &/summary&
NoAction = <span style="color: #,
/// &summary&
/// 系统错误
/// &/summary&
SystemError = <span style="color: #0,
public class ErrorMsg {
public static Dictionary&ErrorCode, string& ErrorMessage = new Dictionary&ErrorCode, string& {
{ ErrorCode.OperationError,"服务器响应错误!"},
{ ErrorCode.Success,"成功!"},
{ ErrorCode.Failed, "失败!"},
{ ErrorCode.NoData, "查无数据!"},
{ ErrorCode.NotExistPage,"此页码不存在!"},
{ ErrorCode.InvalideParameter,"请求参数非法!"},
{ ErrorCode.NoAction,"无此接口!"},
{ ErrorCode.SystemError,"系统错误!"},
{ ErrorCode.NoPermission,"无权限操作此功能!" },
{ ErrorCode.NoLogin,"未登录!"},
{ ErrorCode.Forbidden,"操作被禁止!"},
接下来介绍使用方法:
IndexHandler_Base64:定义一个接收base64字符串参数的接口处理器。代码如下:
/// &summary&
/// 一般业务接口的模板方法处理器,适用于参数为base64字符串的请求
/// &/summary&
/// &typeparam name="T"&&/typeparam&
public abstract class IndexHandler_Base64&T& : IndexHandler&T& where T:class {
//当前接口是否需要登录后才能操作
protected bool _isLoginRequired = false;
/// &summary&
/// 实例化一个只接收base64字符串的接口操作
/// &/summary&
/// &param name="isLoginRequired"&当前接口是否需要登录。true:需要 false:不需要(默认)&/param&
public IndexHandler_Base64(bool isLoginRequired = false) : base() { _isLoginRequired = isLoginR }
/// &summary&
/// 实例化一个只接收base64字符串的接口操作
/// &/summary&
/// &param name="typeName"&发起日志记录的类名&/param&
/// &param name="isLoginRequired"&当前接口是否需要登录。true:需要 false:不需要(默认)&/param&
public IndexHandler_Base64(string typeName,bool isLoginRequired=false) : base(typeName) { _isLoginRequired = isLoginR }
/// &summary&
/// 对实体模型进行绑定和参数的特性验证
/// &/summary&
/// &returns&&/returns&
public override T Binder() {
//初始化模型
T rc = default(T);
//初始化ModelState
if (_modelState == null)
_modelState = new ModelState();
_modelState.Errors.Clear();
//获取数据
Stream stream = HttpContext.Current.Request.InputS
stream.Seek(<span style="color: #, SeekOrigin.Begin);
byte[] buffer = new byte[stream.Length];
int count = stream.Read(buffer, <span style="color: #, buffer.Length);
if (count & <span style="color: #) {
string requestParam = Encoding.UTF8.GetString(buffer);
requestParam = Encoding.UTF8.GetString(Convert.FromBase64String(requestParam));
//绑定数据
rc = new JavaScriptSerializer().Deserialize&T&(requestParam);
if (rc != null) {
//验证数据合法性
base.Valide(rc);
_modelState.Errors.Add("绑定数据失败!");
_modelState.Errors.Add("请求参数为空!");
catch (Exception ex) {
_modelState.Errors.Add("绑定数据出现错误!");
public override BaseResponseResult Process() {
//如果该接口需要登录后才能操作,则检查当前用户是否登录
if (_isLoginRequired) {
int userId = <span style="color: #;
userId = Login.GetSession("UserID");
if (userId &= <span style="color: #)
return new BaseResponseResult(ErrorCode.NoLogin);
return base.Process();
接下来定义一个Index.ashx文件,开始使用模板接口。
/// &summary&
/// index 的摘要说明
/// &/summary&
public class Index : IHttpHandler {
private readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
//当前登录的用户
public static int _thisUserId {
return Login.GetSession("UserID");
public void ProcessRequest(HttpContext context) {
BaseResponseResult rc = new BaseResponseResult(ErrorCode.OperationError, "获取数据失败!");
string action = GetAction();
switch (action) {
//获取 xxx列表
case "<span style="color: #01":
rc = new ListHandler().Process();
//获取 xxx信息
case "<span style="color: #02":
rc = new ItemHandler().Process();
rc.SetResult(ErrorCode.NoAction);
catch (Exception ex) {
log.Error("ProcessRequest", ex);
rc.SetResult(ErrorCode.SystemError);
rc.Response();
public bool IsReusable {
return false;
/// &summary&
/// 获取Action接口名称
/// &/summary&
/// &returns&&/returns&
private string GetAction() {
string rc = "";
rc = HttpContext.Current.Request["action"] ?? "";
if ((rc ?? "").Trim() == "") {
Stream stream = HttpContext.Current.Request.InputS
if (stream != null) {
byte[] buffer = new byte[stream.Length];
int count = stream.Read(buffer, <span style="color: #, buffer.Length);
if (count & <span style="color: #) {
string requestParam = Encoding.UTF8.GetString(buffer);
requestParam = Encoding.UTF8.GetString(Convert.FromBase64String(requestParam));
JsonData jd = JsonMapper.ToObject(requestParam);
if (jd != null && jd.Keys.Contains("action"))
rc = jd["action"].ToString();
catch (Exception ex) {
log.Error("GetAction", ex);
#region 接口处理区
#region 1001 获取 xxx列表
public class ListReqModel {
[Required(ErrorMessage = "请上送需要类型!")]
[Range(<span style="color: #,5, ErrorMessage = "type参数值有误!")]
public int type { get; set; }
/// &summary&
/// 页码索引,从0开始
/// &/summary&
[Required(ErrorMessage = "请上送页码索引!")]
[Min(<span style="color: #, ErrorMessage = "pageIndex参数值有误!")]
public int pageIndex { get; set; }
/// &summary&
/// 每页个数
/// &/summary&
[Required(ErrorMessage = "请上送每页的个数!")]
[Min(<span style="color: #, ErrorMessage = "pageSize参数值有误!")]
public int pageSize { get; set; }
public class ListHandler : IndexHandler_Base64&ListReqModel& {
public ListHandler() : base("ListHandler") { }
protected override BaseResponseResult DoWork(ListReqModel param) {
BaseResponseResult rc = new BaseResponseResult(ErrorCode.OperationError);
int totalCount = <span style="color: #;
ProjectBLL biz = new ProjectBLL();
DataTable table = biz.GetList(param.type ,Index._thisUserId, out totalCount, param.pageIndex, param.pageSize);
if (table != null && table.Rows.Count & <span style="color: #) {
rc.SetReturnData(new
totalCount = totalCount,
list = table.AsEnumerable().Select(it =& new
id = it["ID"].ToInt64(),
title = it["Title"].ToNormalString(),
frontCover = it["FrontCover"].ToNormalString()
}).ToList()
rc.SetResult(ErrorCode.Success, "成功!");
else if (totalCount & <span style="color: #)
rc.SetResult(ErrorCode.NotExistPage, "当前页码不存在!");
rc.SetResult(ErrorCode.NoData, "没有数据哟!");
#endregion
#region 1002 获取xxx信息
public class ItemReqModel {
[Required(ErrorMessage = "请上送项目标识!")]
[Min(<span style="color: #, ErrorMessage = "id参数值有误!")]
public long id { get; set; }
public class ItemHandler : IndexHandler_Base64&ItemReqModel& {
public ItemHandler() : base("ItemHandler") { }
protected override BaseResponseResult DoWork(ItemReqModel param) {
BaseResponseResult rc = new BaseResponseResult(ErrorCode.OperationError);return
#endregion#endregion
ajax的使用方式:
//接入说明:
//<span style="color: #、请使用POST方式上传;
//<span style="color: #、请将参数组装为Json字符串,如:{'action':'xxx','xx':'xx'};
//<span style="color: #、Json字符串组装好以后,将其变为Base64字符串后上传。
//上送数据案例如下所示:
type: "POST",
dataType: "json",
url: GetHost() + 'Index.ashx',
data: Base.encode('{"action":"1001","type":"' + type + '","pgIndex":' + pageIndex + ',"pgSize":' + pageSize + '}'),
contentType:"application/json",
success: function (data) {
//获取数据
if (data) {
//成功获取数据
if (data.returnValue == <span style="color: #) {
//处理数据
至此,完毕!以上的通用接口处理器采用了模板方法设计模式,尽量减少重复工作量。
说明:本篇文章为作者原创,如需转载,请说明来源及出处!
&posted on
阅读(...) 评论()}

我要回帖

更多关于 接口测试的测试要点 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信