导航:首页 > 源码编译 > cwebapi实例源码

cwebapi实例源码

发布时间:2023-04-14 14:14:04

‘壹’ 创建C#的wpf项目(C/S架构),不知道C/S架构中能不能用webapi,请高人解答,谢谢!

首先 ,你要明白浏览器也是客户端,只不过他提供的是一套通用的解释方式,具体执行程序放在了服务器上,服务器应用跟本地应用,本质上无差异,基本都是Sever+客户端处理,WPF是可以调用web api的 sever收到http请求可不管你是谁 是什么样的客户端发来的 只要是正确的http请求 就能响应,

‘贰’ 怎样操作WebAPI接口

先定义一个简单的webapi,简单到差不多直接用vs2010自动生成的webapi代码。
其中的TestModle是一个简单的class,如下
public class TestModle
{
public string a { get; set; }
public string b { get; set; }
public string c { get; set; }
}

前端页面放四个代表get,post,put,delete的按钮,在加一个div显示返回值

前端代码中加载jquery,在定义四个按钮的click事件

get和post,我习惯用$.get和$.post,当然也能用$.ajax.
get直接返回webapi get的return值,post的话我就不在后端做处理了直接返回传入的值,这里只做示范

put和delete,只能用$.ajax来处理。
put的话一般用于update某个id的数据信息

delete用于删除某个id的数据,如下图所示

点击每个按钮,可以在页面上看到相应的效果
本回答由提问者推荐
评论
1 1

xzozxzb | 汽车顾问向TA咨询
擅长: 汽车
其他回答

先定义一个简单的webapi,简单到差不多直接用vs2010自动生成的webapi代码。
其中的TestModle是一个简单的class,如下
public class TestModle
{
public string a { get; set; }
public string b { get; set; }
public string c { get; set; }
}

前端页面放四个代表get,post,put,delete的按钮,在加一个div显示返回值

前端代码中加载jquery,在定义四个按钮的click事件

get和post,我习惯用$.get和$.post,当然也能用$.ajax.
get直接返回webapi get的return值,post的话我就不在后端做处理了直接返回传入的值,这里只做示范

put和delete,只能用$.ajax来处理。
put的话一般用于update某个id的数据信息

delete用于删除某个id的数据,如下图所示

点击每个按钮,可以在页面上看到相应的效果

‘叁’ auth返回状态码异常

throw new AuthException("ssCode","登录错了");
返回:
{
"error" : "ssCode",
"error_description" : "登录错了"
}
文章知识点与官方知识档案匹配
Java技能树首页概览
86213 人正在系统学习中
打开CSDN,阅读体验更佳
springsecurity+oauth2+jwt实现单点吵备册登录demo
该资源是springsecurity+oauth2+jwt实现的单点登录demo,模式为授权码模式,实现自定义登录页面和自定义授权页面。应用数据存在内存中或者存在数据库中(附带数据库表结构),token存储分为数据库或者Redis。demo包含服务端和客户端,可直接运行测试。
Spring Security OAuth2 认证服务器自定义异常处理
认证服务器默认返回的数据格式如下: { "error": "unsupported_grant_type", "error_description": "Unsupported grant type: password1" } 上面的返回结果很不友好,而且前端代码也很难判断是什么错误,所以我们需要对返回的错误进行统一的异常处理 1.默认的异常处理器 默认情况是使用WebRespo...
继续访问
自定义spring security oauth /auth/token的返回内容格式
场景 在前后端分离的项目中,一般后端返回给前端的格式是一个固定的json格式。 在这个前提下,spring security oauth 生成access token的请求/auth/token的返回内容就需要自定义 原返回值 我们希望使用我们自己固定的json格式 需求 我们的BaseResponse类 public class BaseResponse { pri...
继续访问
Spring Security OAuth2模块/oauth/token授权接口自定义返回结果
spring security提供了默认的oauth登录授权升宏接口/oauth/token,该接口位于org.springframework.security.oauth2.provider.endpoint包中的TokenEndpoint类。 公司要实现自定义的登录授权接口,且返回值滚型也要实现私有结构,下面大概讲一下怎么改造这个类来实现要求的业务逻辑。 一、利用Spring AOP方式 二、自定义Controller接口实现 简单粗暴,直接把TokenEndpointer类注入到自定义Controller中;
继续访问
Spring Security Oauth2 自定义异常返回信息
开头引用 https://my.oschina.net/merryyou/blog/1819572 在使用Spring Security Oauth2登录和鉴权失败时,默认返回的异常信息如下 { "error": "unauthorized", "error_description": "Full authentication is required to access this r...
继续访问
oauth2.0源码分析之oauth/token申请令牌
本期介绍的是在oauth2.0中 , 通过调用oauth/token接口 , 框架是如何给我们申请到JWT令牌的 , 内部做了些什么事情 ? 在分析源码之前 , 我们首先需要知道的是我们需要具备哪些调试条件 , 不然会发现许多奇奇怪怪的错误 (比如通过/oauth/token时出现401) 1.一张oauth2.0的内置表(oauth_client_details) 注意:这里的密码需要用Bcript加密 , 因为源码内部是用Bcript解密的 2.两把钥匙: 一本是后缀为jks的私钥 另一本是后缀为k
继续访问
SpringSecurity+OAuth2认证/oauth/token登录报错There is no client authentication
报错信息: { "error": "unauthorized", "error_description": "There is no client authentication. Try adding an appropriate authentication filter." } 找到这个问题原因后,发现自己被自己蠢哭了。 在自己的核心配置类里,把这个/oauth/token加入到忽...
继续访问
spring security+Oauth2密码模式认证时,报401,Unauthorized的问题排查
第一种情况: 进行 /auth/token的post请求时,没有进行httpbasic认证。 什么是http Basic认证? http协议的一种认证方式,将客户端id和客户端密码按照“客户端ID:客户端密码”的格式拼接,并用base64编码,放在 header中请求服务端。例子如下: Authorization:Basic ASDLKFALDSFAJSLDFKLASD= ASDLKFALDSFAJSLDFKLASD= 就是 客户端ID:客户端密码 的64编码 springsecurity中的...
继续访问
最新发布 SpringBoot使用SpringSecurity,使用oauth2登录,使用自定义/uaa/oauth/token报错解决
SpringBoot使用SpringSecurity,使用oauth2登录,使用自定义/uaa/oauth/token报错解决
继续访问
asp.net WebAPI OWIN OAuth2.0授权自定义返回结果及错误或异常问题处理办法
asp.net WebAPI OWIN OAuth2.0授权自定义返回结果及错误或异常问题处理核心代码,详情: https://www.cnblogs.com/wgx0428/p/12315546.html
ASP.NET WebAPI Token JWT Bearer 认证失败和成功返回自定义数据 Json
asp.net WebAPI Token Oauth2.0授权自定义返回结果(包括登录正确返回,登录失败返回)。 详细参考:https://blog.csdn.net/u013546115/article/details/105580532
Spring Security OAuth2 token权限隔离实例解析
主要介绍了Spring Security OAuth2 token权限隔离实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
spring security oauth其中的/oauth/token做了哪些
项目场景: 问题描述: 提示:这里描述项目中遇到的问题: 例如:数据传输过程中数据不时出现丢失的情况,偶尔会丢失一部分数据 APP 中接收数据代码: 原因分析: 提示:这里填写问题的分析: 例如:Handler 发送消息有两种方式,分别是 Handler.obtainMessage()和 Handler.sendMessage(),其中 obtainMessage 方式当数据量过大时,由于 MessageQuene 大小也有限,所以当 message 处理不及时时,会造成先传的数据被覆盖,进而.
继续访问
Spring Security OAuth2 自定义 token Exception
https://raw.githubusercontent.com/longfeizheng/longfeizheng.github.io/master/images/spring-security-OAuth208.png 1. 前言 在使用Spring Security Oauth2登录和鉴权失败时,默认返回的异常信息如下 { "error": "unauthorized", "error_description": "Full authentication is required to
继续访问
前后端分离 token过期 返回状态码
1.首先配置Mvc配置文件类 @Configuration public class BackendConfiguration extends WebMvcConfigurationSupport { @Autowired private LoginInterceptor loginInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { regi
继续访问
SpringSecurityOAuth2(2)请求携带客户端信息校验,自定义异常返回,无权处理,token失效处理...
上文地址:SpringSecurityOAuth2(1)(password,authorization_code,refresh_token,client_credentials)获取token 上一篇博客写了一个至简的OAuth2的token认证服务器,只实现了4种获取token的方式 ,对...
继续访问
oauth2.0自定义token失效返回信息
oauth2.0自定义token失效返回信息 一、问题 由于spring security oauth2返回的失效信息对于客户端不太有好,在网上找了自定义的解决方案以便更优雅的展示返回信息。 重写框架里的方法,实现自定义。 二、配置类 Oauth2ResourceServer extends @Override public void configure( reso
继续访问
热门推荐 解决Spring Security OAuth在访问/oauth/token时候报401 authentication is required
先来张图片 我在用psotman 测试oauth授权码模式的出现了401的异常, 就是调用oauth/token. 我是想用code换token,但是发现报错了。这是为什么呢? 首先你要理解 /oauth/token 这个如果配置支持的,且url中有client_...
继续访问
spring security 和OAuth2 整合访问 localhost:8082/oauth/token 报401的问题,或者403的问题
@Bean public PasswordEncoder passwordEncoder() { /** * 采坑 * spring-boot2 之后废弃了MD5,使用BCryptPasswordEncoder()加密; * */ return new BCryptPasswordEncoder(); } 注意在security的配置内中,要使用BCryptPasswordEncoder 加密,..
继续访问
数据库课程设计
c语言文件读写操作代码
html+css+js网页设计

‘肆’ webapi同时支持get和post 怎么接受多个参数

这里给出一个实例,仅供参考:
[csharp] view plain
[AcceptVerbs("Get", "Post")] //用AcceptVerbs标识即可
public List<PUB_HqewIndexResult> GetSalesRankByHqewIndex()
{
List<PUB_HqewIndexResult> resultList = new List<PUB_HqewIndexResult>();
DMSParam dmsParam = new DMSParam();
List<PUB_Stock> stockList = new List<PUB_Stock>();
IResult stockResult = ExecuteDmsParam(dmsParam, new PUB_HqewIndex(), "PUB.PUB_HqewIndexBLL", "GetSalesRankByHqewIndex");
if (stockResult.Complete == DMSComplete.Succeed)
{
if (stockResult != null && stockResult.Result != null)
{
resultList = (List<PUB_HqewIndexResult>)stockResult.Result;
}
}
return resultList;
}

‘伍’ wpf 数据库是webapi的项目怎么改为本地调用执行

如果不想使用Web API方式,可以将最后两行的代码删除,即删除以下两行代码:
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "MyToDo.Api", Version = "态雀v1" });
});
这两行代码的作用是添加控帆塌早制器和Swagger文档生成衫世器,如果不需要使用Web API,就不需要这些东西了。
另外,如果不使用Web API,可以将启动类中的以下代码删除:
services.AddDbContext<MyToDoContext>(option =>
{
var connectionString = Configuration.GetConnectionString("ToDoConnection");
option.UseSqlite(connectionString);
}).AddUnitOfWork<MyToDoContext>()
.AddCustomRepository<ToDo, ToDoRepository>();
因为这些代码都是用来配置数据库上下文和依赖注入的,如果不使用Web API,就不需要这些东西了。

‘陆’ webapi怎么调用winform(CS)中的方法(cs是服务端必须先独立启动)

有解决方案:建立CS程序与WebApi服务器的点对点连接(通过Tcp/ip),然后WebApi发起请求搏漏简,CS程序返回请求结果。
详细一点:CS端开启tcp.ip的监听端口搜凳,webapi服务器连接这个端口,需要掌握网络编程技能。网络搜索C# 网络编程相关的源码。
若CS端没有开启外网IP,还需要穿透NAT(类似QQ聊天基裤,网络编程高级篇),这里有文章参考一下: C#实现UDP穿透NAT(UDP打洞)完整版(原)
www.csframework.com/archive/2/arc-2-20110713-1693.htm

‘柒’ VS:WebApi调试发生FileNotFoundException异常

visual studio安装web开发人员工具,然后项目引用里渗核右击,添加引用,浏览,打开丛薯掘

C:ProgramFiles(x86).Json6.0.6lib

打开自己版本的net版本的文件夹下的Newtonsoft.Json.dll添加。手判

‘捌’ 如何使 WebAPI 自动生成漂亮又实用在线API文档

1.1 SwaggerUI

SwaggerUI 是一个简单的Restful API 测试和文档工具。简单、漂亮、易用(官方demo)。通过读取JSON 配置显示API. 项目本身仅仅也只依赖一些 html,css.js静态文件. 你可以几乎放在任何Web容器上使用。

1.2 Swashbuckle

Swashbuckle 是.NET类库,可以将WebAPI所有开放的控制器方法生成对应SwaggerUI的JSON配置。再通过SwaggerUI 显示出来。类库中已经包含SwaggerUI 。所以不需要额外安装。

2.快速开始

创建项目 OnlineAPI来封装网络音乐服务(示例下载) ,通过API可以搜索、获取音乐的信息和播放连接。

我尽量删除一些我们demo中不会用到的一些文件,使其看上去比较简洁。

WebAPI 安装 Swashbuckle

Install-Package Swashbuckle

代码注释生成文档说明。
Swashbuckle 是通过生成的XML文件来读取注释的,生成 SwaggerUI,JSON 配置中的说明的。
安装时会在项目目录 App_Start 文件夹下生成一个 SwaggerConfig.cs 配置文件,用于配置 SwaggerUI 相关展示行为的。如图:

将配置文件大概99行注释去掉并修改为
c.IncludeXmlComments(GetXmlCommentsPath(thisAssembly.GetName().Name));

并在当前类中添加一个方法

/// <summary>
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
protected static string GetXmlCommentsPath(string name)
{
return string.Format(@"{0}\bin\{1}.XML", AppDomain.CurrentDomain.BaseDirectory, name);
}

紧接着你在此Web项目属性生成选卡中勾选 “XML 文档文件”,编译过程中生成类库的注释文件

添加网络音乐 3个API

访问 http://<youhost>/swagger/ui/index,最终显示效果

我们通过API 测试API 是否成功运行

3.添加自定义HTTP Header

在开发移动端 API时常常需要验证权限,验证参数放在Http请求头中是再好不过了。WebAPI配合过滤器验证权限即可

首先我们需要创建一个 IOperationFilter 接口的类。IOperationFilter
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Http.Description;
using System.Web.Http.Filters;
using Swashbuckle.Swagger;

namespace OnlineAPI.Utility
{
public class HttpHeaderFilter : IOperationFilter
{
public void Apply(Operation operation, SchemaRegistry
schemaRegistry, ApiDescription apiDescription)
{
if (operation.parameters == null) operation.parameters = new
List<Parameter>();
var filterPipeline =
apiDescription.ActionDescriptor.GetFilterPipeline();
//判断是否添加权限过滤器
var isAuthorized = filterPipeline.Select(filterInfo =>
filterInfo.Instance).Any(filter => filter is IAuthorizationFilter);
//判断是否允许匿名方法
var allowAnonymous =
apiDescription.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any();

if (isAuthorized && !allowAnonymous)
{
operation.parameters.Add(new Parameter
{
name = "access-key",
@in = "header",
description = "用户访问Key",
required = false,
type = "string"
});
}
}
}
}

在 SwaggerConfig.cs 的 EnableSwagger 配置匿名方法类添加一行注册代码
c.OperationFilter<HttpHeaderFilter>();

添加Web权限过滤器
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
using Newtonsoft.Json;

namespace OnlineAPI.Utility
{
/// <summary>
///
/// </summary>
public class AccessKeyAttribute : AuthorizeAttribute
{
/// <summary>
/// 权限验证
/// </summary>
/// <param name="actionContext"></param>
/// <returns></returns>
protected override bool IsAuthorized(HttpActionContext actionContext)
{
var request = actionContext.Request;
if (request.Headers.Contains("access-key"))
{
var accessKey = request.Headers.GetValues("access-key").SingleOrDefault();
//TODO 验证Key
return accessKey == "123456789";
}
return false;
}

/// <summary>
/// 处理未授权的请求
/// </summary>
/// <param name="actionContext"></param>
protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
{
var content = JsonConvert.SerializeObject(new {State = HttpStatusCode.Unauthorized});
actionContext.Response = new HttpResponseMessage
{
Content = new StringContent(content, Encoding.UTF8, "application/json"),
StatusCode = HttpStatusCode.Unauthorized
};
}
}
}

在你想要的ApiController 或者是 Action 添加过滤器
[AccessKey]

最终显示效果

4.显示上传文件参数

SwaggerUI 有上传文件的功能和添加自定义HTTP Header 做法类似,只是我们通过特殊的设置来标示API具有上传文件的功能
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http.Description;
using Swashbuckle.Swagger;

namespace OnlineAPI.Utility
{
/// <summary>
///
/// </summary>
public class UploadFilter : IOperationFilter
{

/// <summary>
/// 文件上传
/// </summary>
/// <param name="operation"></param>
/// <param name="schemaRegistry"></param>
/// <param name="apiDescription"></param>
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
if (!string.IsNullOrWhiteSpace(operation.summary) && operation.summary.Contains("upload"))
{
operation.consumes.Add("application/form-data");
operation.parameters.Add(new Parameter
{
name = "file",
@in = "formData",
required = true,
type = "file"
});
}
}
}
}

在 SwaggerConfig.cs 的 EnableSwagger 配置匿名方法类添加一行注册代码
c.OperationFilter<UploadFilter>();

API 文档展示效果

‘玖’ 用MVC WebApi写接口,网闸上了之后,方法访问不到,端口已经全部开放

VisualStudio为我们提供了专门用于创建ASP.NETWebAPI应用的项目模板,借助于此项目模板提供的向导,我们可以“一键式”创建一个完整的ASP.NETWebAPI项目。在项目创建过程中,VisualStudio会自动为我们添加必要的程序集引用和配置,甚至会为我们自动生成相关的代码,总之一句话:这种通过向导生成的项目在被创建之后其本身就是一个可执行的应用。对于IDE提供的这种旨在提高生产效率的自动化机制,我个人自然是推崇的,但是我更推荐读者朋友们去了解一下这些自动化机制具体为我们做了什么?做这些的目的何在?哪些是必需的,哪些又是不必要的?正是基于这样的目的,在接下来演示的实例中,我们将摒弃VisualStudio为我们提供的向导,完全在创建的空项目中编写我们的程序。这些空项目体现在如右图所示的解决方案结构中。如右图所示,整个解决方案一共包含6个项目,上面介绍的作为“联系人管理器”的单页Web应用对应着项目WebApp,下面的列表给出了包括它在内的所有项目的类型和扮演的角色。·Common:这是一个空的类库项目,仅仅定义了表示联系人的数据类型而已。之所以将数据类型定义在独立的项目中,只要是考虑到它会被多个项目(WebApi和ConsoleApp)所使用。WebApi:这是一个空的类库项目,表现为HttpController类型的WebAPI就定义在此项目中,它具有对Common的项目引用。WebHost:这是一个空的ASP.NETWeb应用,它实现了针对ASP.NETWebAPI的WebHost寄宿,该项目具有针对WebApi的项目引用。SelfHost:这是一个空的控制台应用,旨在模拟ASP.NETWebAPI的SelfHost寄宿指指模式,它同样具有针对WebApi的项目引用。WebApp:这是一个空的ASP.NETWeb应用,代表“联系人管理器”的网页就存在于该项目之中,至于具体的联系人管理功能,自然通过以Ajax的形式调用WebAPI来完成。ConsoleApp:这是一个空的控制台应用,我们用它来模拟如何利用客户端代理来实现对WebAPI的远程调用,它具有针对Common的项目引用。二、定义WebAPI在正式定义WebAPI之前,我们需要在项目Common中定义代表联系人的数据类型Contact。简单起见,我们仅仅为Contact定义了如下几个简单的属性,它们分别代表联系人的ID、姓名、联系电话、电子邮箱和联系地址。1:publicclassContact2:{3:publicstringId{get;set;}4:publicstringName{get;set;}5:publicstringPhoneNo{get;set;}6:publicstringEmailAddress{get;set;}7:publicstringAddress{get;set;}8:}表现为HttpController的WebAPI定义在WebApi项目之中,我们一般将ApiController作为继承的基类。ApiController定义在“System.Web.Http.dll”程序集中,我们可以在目录“%ProgramFiles%\MicrosoftASP.NET\ASP.NETWebStack5\Packages\”中找到这个程序集。具体来说,该程序集存在于子目录“Microsoft.AspNet.WebApi.Core.5.0.0\lib\net45”中。WebAPI体现在如下所示的ContactsController类型中。在该类型中,我们定义了Get、Post、Put和Delete这4个弊者Action方法,它们分别实现了针对联系人的查询、添加、修改和删除操作。Action方法Get具有一个表示联系人ID的可缺省参数,如果该参数存在则返回对应的联系人,否则返回整个联系人列表。由于ASP.NETWebAPI默认实现了Action方法与HTTP方法的映射,所以方法名也体现了它们各自所能处理租逗薯请求必须采用的HTTP方法。1:publicclassContactsController:ApiController2:{3:staticListcontacts;4:staticintcounter=2;5:6:staticContactsController()7:{8:contacts=newList();9:contacts.Add(newContact{Id="001",Name="张三",10:PhoneNo="0512-12345678",EmailAddress="[email protected]",11:Address="江苏省苏州市星湖街328号"});12:contacts.Add(newContact{Id="002",Name="李四",13:PhoneNo="0512-23456789",EmailAddress="[email protected]",14:Address="江苏省苏州市金鸡湖大道328号"});15:}16:17:publicIEnumerableGet(stringid=null)18:{19:returnfromcontactincontacts20:wherecontact.Id==id||string.IsNullOrEmpty(id)21:selectcontact;22:}23:24:publicvoidPost(Contactcontact)25:{26:Interlocked.Increment(refcounter);27:contact.Id=counter.ToString("D3");28:contacts.Add(contact);29:}30:31:publicvoidPut(Contactcontact)32:{33:contacts.Remove(contacts.First(c=>c.Id==contact.Id));34:contacts.Add(contact);35:}36:37:publicvoidDelete(stringid)38:{39:contacts.Remove(contacts.First(c=>c.Id==id));40:}41:}简单起见,我们利用一个静态字段(contacts)表示存储的联系人列表。当ContactsController类型被加载的时候,我们添加了两个ID分别为“001”和“002”的联系人记录。至于实现联系人CRUD操作的Action方法,我们也省略了必要的验证,对于本书后续的演示的实例,我们基本上也会采用这种“简写”的风格。

‘拾’ WebAPI 怎样获取相对路径 获取本地路径

其实这个方法就运漏禅是Controller实例下的一个属性(但不是apiController),因此我们实例化一个Controller就行了。
如下即可:

[csharp] view plain
System.Web.Mvc.Controller controller = new HomeController();
var curProjRootPath = controller.Server.MapPath("~/搜念"旁尘);

阅读全文

与cwebapi实例源码相关的资料

热点内容
android平滑滚动效果 浏览:841
什么是编译器指令 浏览:219
微控制器逻辑命令使用什么总线 浏览:885
程序员在学校里是学什么的 浏览:601
oraclejava数据类型 浏览:890
程序员考注册会计师 浏览:957
怎么使用access的命令按钮 浏览:899
有点钱app在哪里下载 浏览:832
博途v15解压后无法安装 浏览:205
什么是根服务器主机 浏览:438
安卓手游怎么申请退款 浏览:555
安卓系统如何分享网页 浏览:278
ad如何编译pcb工程 浏览:414
除了滴滴app哪里还能用滴滴 浏览:399
截图怎么保存文件夹然后压缩 浏览:8
幻影服务器怎么样 浏览:28
具体哪些广东公司招程序员 浏览:870
嵌入式编译器教程 浏览:307
ssl数据加密传输 浏览:87
51单片机定时器方式2 浏览:332