C#进阶系列——WebApi 接口参数不再困惑:传参详解

阅读目录 一、get请求 1、基础类型参数 2、实体作为参数 3、数组作为参数 4、“怪异”的get请求 二、post请求 1、基础类型参数 2、实体作为参数 3、数组作为参数 4、后台发送请求参数的传递 三、put请求 1、基础类型参数 2、实体作为参数 3、数组作为参数 四、delete请求 五、总结   正文 前言:还记得刚使用WebApi那会儿,被它的传参机制折腾了好久,查阅了半天资料。如今,使用WebApi也有段时间了,今天就记录下API接口传参的一些方式方法,算是一个笔记,也希望能帮初学者少走弯路。本篇针对初初使用WebApi的同学们,比较基础,有兴趣的且看看。 WebApi系列文章 C#进阶系列——WebApi接口测试工具:WebApiTestClient C#进阶系列——WebApi 跨域问题解决方案:CORS C#进阶系列——WebApi身份认证解决方案:Basic基础认证 C#进阶系列——WebApi接口传参不再困惑:传参详解 C#进阶系列——WebApi接口返回值不困惑:返回值类型详解 C#进阶系列——WebApi异常处理解决方案 C#进阶系列——WebApi区域Area使用小结 本篇打算通过get、post、put、delete四种请求方式分别谈谈基础类型(包括int/string/datetime等)、实体、数组等类型的参数如何传递。 一、get请求 对于取数据,我们使用最多的应该就是get请求了吧。下面通过几个示例看看我们的get请求参数传递。 1、基础类型参数

参数截图效果 这是get请求最基础的参数传递方式,没什么特别好说的。 2、实体作为参数 如果我们在get请求时想将实体对象做参数直接传递到后台,是否可行呢?我们来看看。

测试结果 由上图可知,在get请求时,我们直接将json对象当做实体传递后台,后台是接收不到的。这是为什么呢?我们来看看对应的http请求 原来,get请求的时候,默认是将参数全部放到了url里面直接以string的形式传递的,后台自然接不到了。 原因分析:还记得有面试题问过get和post请求的区别吗?其中有一个区别就是get请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),而post请求则是放在http协议包的包体中。 根据园友们的提议,Get请求的时候可以在参数里面加上[FromUri]即可直接得到对象。还是贴上代码:

得到结果: 如果你不想使用[FromUri]这些在参数里面加特性的这种“怪异”写法,也可以采用先序列化,再在后台反序列的方式。

这样在后台得到我们序列化过的对象,再通过反序列化就能得到对象。 在url里面我们可以看到它自动给对象加了一个编码: 至于还有园友们提到http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api的model binder这种方式,博主看了下,觉得略复杂。有兴趣的也可以试试。至于用哪一种方式传递对象,园友们可以自行选择。 3、数组作为参数 一般get请求不建议将数组作为参数,因为我们知道get请求传递参数的大小是有限制的,最大1024字节,数组里面内容较多时,将其作为参数传递可能会发生参数超限丢失的情况。 4、“怪异”的get请求 为什么会说get请求“怪异”呢?我们先来看看下面的两种写法对比。 (1)WebApi的方法名称以get开头

这是标准写法,后台加[HttpGet],参数正常得到: 为了对比,我将[HttpGet]去掉,然后再调用

貌似没有任何问题!有人就想,那是否所有的get请求都可以省略掉[HttpGet]这个标注呢。我们试试便知。 (2)WebApi的方法名称不以get开头 我们把之前的方法名由GetByModel改成FindByModel,这个再正常不过了,很多人查询就不想用Get开头,还有直接用Query开头的。这个有什么关系吗?有没有关系,我们以事实说话。

貌似又可行,没有任何问题啊。根据上面的推论,我们去掉[HttpGet]也是可行的,好,我们注释掉[HttpGet],运行起来试试。 结果是不进断点,有些人不信,我们在浏览器里面看看http请求: 呵呵,这就奇怪了,就改了个方法名,至于这样么?还真至于! 博主的理解是:方法名以Get开头,WebApi会自动默认这个请求就是get请求,而如果你以其他名称开头而又不标注方法的请求方式,那么这个时候服务器虽然找到了这个方法,但是由于请求方式不确定,所以直接返回给你405——方法不被允许的错误。 最后结论:所有的WebApi方法最好是加上请求的方式([HttpGet]/[HttpPost]/[HttpPut]/[HttpDelete]),不要偷懒,这样既能防止类似的错误,也有利于方法的维护,别人一看就知道这个方法是什么请求。 这也就是为什么很多人在园子里面问道为什么方法名不加[HttpGet]就调用不到的原因! 二、post请求 在WebApi的RESETful风格里面,API服务的增删改查,分别对应着http的post/delete/put/get请求。我们下面就来说说post请求参数的传递方式。 1、基础类型参数 post请求的基础类型的参数和get请求有点不一样,我们知道get请求的参数是通过url来传递的,而post请求则是通过http的请求体中传过来的,WebApi的post请求也需要从http的请求体里面去取参数。 (1)错误的写法

这是一种看上去非常正确的写法,可是实际情况是: (2)正确的用法

[…]

龙生   15 Oct 2017
View Details

ASP.NET WebApi 路由配置

一、路由介绍 ASP.NET Web API路由是整个API的入口。我们访问某个资源就是通过路由映射找到对应资源的URL。通过URL来获取资源的。 对于ASP.NET Web API内部实现来讲,我们的请求最终将定位到一个具体的Action上。所以说,ASP.NET Web API路由就是把客户端请求映射到对应的Action上的过程。   二、两种路由模式 2.1 模板路由 模板路由是ASP.NET Web API默认提供的路由。下面我们就简单讲解此中路由的用法。 默认模板路由 模板路由使用前需要定义路由模板。如下面默认的路由模板:

此模板路由是新建项目默认生成的,在App_Start文件夹下。 我们可以看到此模板的URL格式是api/{controller}/{id}。api代表在资源前面要带上api目录,controller代表请求资源的控制器名称。id代表一条资源的id,id 是可选的。这种默认的模板是不带action的,所以它是以请求方式来区分资源的,我们必须在action上添加请求方式特性加以区分。 1.我们添加一个测试控制器api。  

用fiddldr调试如下: 2.我们添加两个方法如下:  

  我们再用fiddler调试如下: 错误信息是: {"Message":"出现错误。","ExceptionMessage":"找到了与该请求匹配的多个操作: \r\n类型 Supernova.Webapi.Controllers.TestController 的 Get1\r\n类型 Supernova.Webapi.Controllers.TestController 的 Get2","ExceptionType":"System.InvalidOperationException","StackTrace":"   在 System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext)\r\n   在 System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)\r\n   在 System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"} 我们将代码改为如下:  

调试返回Get1的信息。 从上面两个测试我们可以得出如下结论: action的默认请求方式是HttpGet。 当多个action的 请求方式一样的话,在默认路由模板下(没有action),将会匹配多个操作。 基于上面两点结论,默认路由模板无法满足针对一种资源一种请求方式的多种操作(比如修改操作,可能针对不同的字段进行修改)。 定制模板路由 我们重新定制模板路由,如下:  

从上面我们可以看出,在默认路由的基础上,我们队路由模板增加了一级action。 测试api如下:  

我们再通过http://192.168.0.230/api/test访问,返回404,如图: 我们通过http://192.168.0.230/api/test/Get1访问,结果正确,如图: 我们通过http://192.168.0.230/api/test/Get2访问,结果正确,如图:   通过定制路由模板我们可以得出如下结论: 通过在路由模板中增加action目录,对资源的定位直接作用到action上。 多个HttpGet方法可以共存于一个controller中。 基于上面两点结论,通过修改路由模板可以满足针对一种资源一种请求方式的多种操作。   2.2 特性路由 特性路由是通过给action打attribute的方式定义路由规则。 有时候我们会有这样的需求,我们请求的一个资源带有子资源。比如文章评论这样有关联关系的资源。我们希望通过如下URL获得某篇文章下的所有评论:api/book/id/comments。而仅仅凭借模板路由很难实现这种路由模式。这时候我们就需要特性路由来解决这个问题了。ASP.NET Web API为我们准备了Route特性,该特性可以直接打到Action上,使用非常灵活、直观。 下面我将先简单的介绍特性路由的使用方法。 我们重新定义api如下:

[…]

龙生   15 Oct 2017
View Details

c# webapi POST 参数解决方法

HttpWebRequest POST请求webapi:如果参数是简单类型,比如字符串(注意,拼接的字符串要HttpUtility.UrlEncode才行,否则服务端会丢失特殊字符&后面的数据) 要点:如下代码统一设置为:ContentType = "application/x-www-form-urlencoded"; 服务端代码1:URL格式为 POSTapi/Values public string Post([FromBody] string value) 则客户端Post的数据:拼接的字符串必须以 =开头,否则服务端无法取得value。例如:=rfwreewr2332322232 或者 {":value} 服务端代码2:URL格式为 POST api/Values?value={value} public string Post(string value) 则客户端Post的数据:需要url里拼接出KeyValue这样的数据 服务端代码3:URL格式为 POST api/Values public string Post() 则客户端Post的数据:无要求。例如:key=rfwreewr2332322232。 服务端:可以用HttpContext.Current.Request.InputStream或者HttpContext.Current.Request.Form[0]都可以获取 如果post的参数类型比较复杂,则需要自定义类 要点:如下代码统一设置为:ContentType = "application/json"; 服务端代码1:URL格式为 POST api/Values public string Post([FromBody] Model value)或者 public string Post(Model value) 则客户端Post的数据:{\"id\":\"test1\",\"name\":\"value\"}。服务端会自动映射到对象。 提交代码如下:

这篇文章里有的方法也不错:http://www.cnblogs.com/rohelm/p/3207430.html   from:http://blog.csdn.net/wyqlxy/article/details/49303345

龙生   15 Oct 2017
View Details

WebApi实现验证授权Token,WebApi生成文档等

from:http://blog.csdn.net/smartsmile2012/article/details/52936011

龙生   14 Oct 2017
View Details

在 Asp.NET MVC 中使用 SignalR 实现推送功能

一,简介 Signal 是微软支持的一个运行在 Dot NET 平台上的 html websocket 框架。它出现的主要目的是实现服务器主动推送(Push)消息到客户端页面,这样客户端就不必重新发送请求或使用轮询技术来获取消息。 可访问其官方网站:https://github.com/SignalR/ 获取更多资讯。 二,实现机制 SignalR 的实现机制与 .NET WCF 或 Remoting 是相似的,都是使用远程代理来实现。在具体使用上,有两种不同目的的接口:PersistentConnection 和 Hubs,其中 PersistentConnection 是实现了长时间的 Javascript 轮询(类似于 Comet),Hub 是用来解决实时信息交换问题,它是利用 Javascript 动态载入执行方法实现的。SignalR 将整个连接,信息交换过程封装得非常漂亮,客户端与服务器端全部使用 JSON 来交换数据。   下面就 Hubs 接口的使用来讲讲整个流程: 1,在服务器端定义对应的 hub class; 2,在客户端定义 hub class 所对应的 proxy 类; 3,在客户端与服务器端建立连接(connection); 4,然后客户端就可以调用 proxy 对象的方法来调用服务器端的方法,也就是发送 request 给服务器端; 5,服务器端接收到 request 之后,可以针对某个/组客户端或所有客户端(广播)发送消息。   三,Hub 示例教程 1,工具准备 SignalR 运行在 .NET 4.5 平台上,所以需要安装 .NET 4.5。为了方便演示,本示例使用 ASP.NET MVC 在 Win 7 系统来实现。这需要安装 ASP.NET MVC 3 或 ASP.NET MVC 4。   2,建立工程 打开 VS2010/VS2012 新建名为 SignalRTutorial 的 ASP.NET MVC 3 Web Application 工程,选择 Internet Application 模板, Razor […]

龙生   13 Oct 2017
View Details

SignalR

ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程。实时 Web 功能是指这样一种功能:当所连接的客户端变得可用时服务器代码可以立即向其推送内容,而不是让服务器等待客户端请求新的数据。 ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信。什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端可以互相通知消息及调用方法,当然这是实时操作的。 WebSockets是HTML5提供的新的API,可以在Web网页与服务器端间建立Socket连接,当WebSockets可用时(即浏览器支持Html5)SignalR使用WebSockets,当不支持时SignalR将使用其它技术来保证达到相同效果。 SignalR当然也提供了非常简单易用的高阶API,使服务器端可以单个或批量调用客户端上的JavaScript函数,并且非常 方便地进行连接管理,例如客户端连接到服务器端,或断开连接,客户端分组,以及客户端授权,使用SignalR都非常 容易实现。 SignalR 将与客户端进行实时通信带给了ASP .NET 。当然这样既好用,而且也有足够的扩展性。以前用户需要刷新页面或使用Ajax轮询才能实现的实时显示数据,现在只要使用SignalR,就可以简单实现了。 最重要的是您无需重新建立项目,使用现有ASP .NET项目即可无缝使用SignalR。

龙生   13 Oct 2017
View Details

Web API 入门指南 – 闲话安全

Web API入门指南有些朋友回复问了些安全方面的问题,安全方面可以写的东西实在太多了,这里尽量围绕着Web API的安全性来展开,介绍一些安全的基本概念,常见安全隐患、相关的防御技巧以及Web API提供的安全机制。 目录 Web API 安全概览 安全隐患 1. 注入(Injection) 2. 无效认证和Session管理方式(Broken Authentication and Session Management) 3. 跨站脚本(Cross-Site Scripting (XSS)) 4. 直接引用非安全对象(Insecure Direct Object References) 5. 错误的安全配置(Security Misconfiguration) 6. 暴露敏感数据(Sensitive Data Exposure) 7. 功能级权限控制缺失(Missing Function Level Access Control) 8. 伪造跨站请求(Cross-Site Request Forgery) 9. 使用已知安全隐患组件(Using Components with Known Vulnerabilities) 10. 未验证跳转(Unvalidated Redirects and Forwards) Web API安全机制 认证与授权(Authentication and Authorization) 伪造跨站请求(Cross-Site Request Forgery Attacks) 安全链接(SSL) 跨域请求(Cross-Origin Requests) Web API 安全概览 先引用下wikipedia信息安全的定义:即保护信息免受未经授权的进入、使用、披露、破坏、修改、检视、记录及销毁,从而保证数据的机密性(Confidentiality)、完整性(Integrity)和可靠性(Availability)。 机密性和完整性都很好理解,可靠性作为信息安全的一个重要原则这里特别解释一下,即访问信息的时候保证可以访问的到,有一种攻击方式叫DOS/DDOS,即拒绝服务攻击,专门破坏网站的可用性。 Information security, sometimes shortened to InfoSec, is the practice of defending information from unauthorized access, use, disclosure, disruption, modification, perusal, […]

龙生   13 Oct 2017
View Details

Web API 强势入门指南

Web API是一个比较宽泛的概念。这里我们提到Web API特指ASP.NET Web API。 这篇文章中我们主要介绍Web API的主要功能以及与其他同类型框架的对比,最后通过一些相对复杂的实例展示如何通过Web API构建http服务,同时也展示了Visual Studio构建.net项目的各种强大。 目录 什么是 Web API 为什么要用 Web API 功能简介 Web API vs MVC Web API vs WCF Web API 实战 (Web API + MongoDB + knockoutjs) 涉及技术 服务URI Pattern 准备工作 代码实现 什么是 Web API 官方定义如下,强调两个关键点,即可以对接各种客户端(浏览器,移动设备),构建http服务的框架。 ASP.NET Web API is a framework that makes it easy to build HTTP services that reach a broad range of clients, including browsers and mobile devices. ASP.NET Web API is an ideal platform for building RESTful applications on the .NET Framework. Web API在ASP.NET完整框架中地位如下图,与SignalR一起同为构建Service的框架。Web API负责构建http常规服务,而SignalR主要负责的是构建实时服务,例如股票,聊天室,在线游戏等实时性要求比较高的服务。   为什么要用 Web API Web API最重要的是可以构建面向各种客户端的服务。另外与WCF REST […]

龙生   13 Oct 2017
View Details

ASP.NET Web API教程(六) 安全与身份认证

在实际的项目应用中,很多时候都需要保证数据的安全和可靠,如何来保证数据的安全呢?做法有很多,最常见的就是进行身份验证。验证通过,根据验证过的身份给与对应访问权限。同在Web Api中如何实现身份认证呢?接下来的内容就详细的分享 Web API身份认证。   首先扩展自定义身份验证 添加类 CustomAuthorizeAttribute.cs 该类继承自System.Web.Http.AuthorizeAttribute(身份认证类)通过重写其身份认证核心方法来达到 web API 身份认证的效果。 完整代码: public class CustomAuthorizeAttribute : System.Web.Http.AuthorizeAttribute { public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext) { //判断用户是否登录 if(!HttpContext.Current.User.Identity.IsAuthenticated) HandleUnauthorizedRequest(actionContext); } protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext) { var challengeMessage = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized); challengeMessage.Headers.Add("WWW-Authenticate", "Basic"); throw new System.Web.Http.HttpResponseException(challengeMessage); } } 增加身份认证(必须登录后才能进行查询等操作)在Controller上加上属性,可以直接通过VS快捷键感应出来 完整代码 PS:写在controller类上是表示这个controller的每个action都受身份认证,如果想为某一个action制定 可以直接写在action上,就不要写在类上了。 接下来编写登录方法 public ActionResult Login() { return View(); } [HttpPost] public ActionResult Login(FormCollection fol) { ///此处为了演示简化登录过程 ///可以在此处扩展验证用户名或者密码是否正确 System.Web.Security.FormsAuthentication.SetAuthCookie(fol["username"], false); return Redirect("/HTMLPage5.htm"); } 有了后台的方法,就剩下最后的前段页面了 通过在Login的方法中右键可以快速生成页面(vs给我们带来的提高效率的工具,就不多做介绍了)   在生成的Login.cshtml中编写以下登录代码 @using (Html.BeginForm()) { <fieldset> <label>账号:</label><input type="text" name="username" /><br /> <label>密码:</label><input type="text" name="password" /><br /> <input type="submit" value="登录" /> </fieldset> } 这个时候还需要有两个小地方做配置. 第一个就是web.config 配置form认证 <authentication mode="Forms"> <forms loginUrl="~/home/Login" timeout="2880" /> </authentication> 第二个就是修改HTMLPage5.html的js(HTMLPage5.html可以直接复制HTMLPage4.html) 将这段获取数据的代码修改为带验证身份进行跳转的 原JS $.get('/api/userInfo', function (data) { // 从API中 // 得到返回的数据,更新 Knockout 模型并且绑定到页面UI模板中 viewModel.userinfos(data); }); 修改后的js $.ajax({ url: '/api/userinfo', type: 'GET', contentType: 'application/json; charset=utf-8', statusCode: { 200 /*Created*/: function (data) { viewModel.userinfos(data) }, 401: function (jqXHR, textStatus, errorThrown) { window.location.href = '/home/login'; } } }); Ok 到此,代码就已近编写完成了,来进行测试 测试第一步直接访问 /api/userinfo […]

龙生   13 Oct 2017
View Details
1 218 219 220 432