HttpApplication 事件
命名空间: System.Web 程序集: System.Web(位于 System.Web.dll) 事件 名称 说明 · AcquireRequestState 当 ASP.NET 获取与当前的请求相关联的当前状态 (例如,会话状态)。 · AuthenticateRequest 当安全模块已建立的用户标识时出现。 · AuthorizeRequest 安全模块已验证用户身份验证时发生。 · BeginRequest 作为执行的 HTTP 管道链中的第一个事件发生,当 ASP.NET 的请求做出响应。 · Disposed 释放应用程序时发生。 · EndRequest 作为执行的 HTTP 管道链中的最后一个事件发生,当 ASP.NET 的请求做出响应。 · Error 当引发未处理的异常时发生。 · LogRequest ASP.NET 执行当前请求的任何日志记录之前发生。 · MapRequestHandler 此 API 支持 产品 基础结构,不应从代码直接使用。 在选择该处理程序对请求作出响应时发生。 · PostAcquireRequestState 获取与当前的请求相关联的请求状态 (例如,会话状态) 时发生。 · PostAuthenticateRequest 当安全模块已建立的用户标识时出现。 · PostAuthorizeRequest 当前请求的用户已被授权时发生。 · PostLogRequest 当 ASP.NET 已完成处理的事件处理程序时发生 LogRequest 事件。 · PostMapRequestHandler 当 ASP.NET 已映射到相应的事件处理程序的当前请求时出现。 · PostReleaseRequestState 当 ASP.NET 已完成执行所有请求事件处理程序和存储数据的请求状态时发生。 · PostRequestHandlerExecute 当 ASP.NET 事件处理程序 (例如,一个页面或 XML Web 服务) 完成执行时发生。 · PostResolveRequestCache ASP.NET […]
View Details严重: Error configuring application listener of class org.springframework.web.context.ContextLoaderList
最近在用idea部署war文件的时候,总是出现了部署失败的错误,刚开始并没有在意,但是现在次数越来越多了,不得不在意了,然后就在百度上搜,然后就有了各种说法 1,错误的信息是:
|
1 |
One or more listeners failed to start. Full details will be found in the appropriate container log file |
根据错误信息,说是一个listener加载失败了,失败原因请看容器log文件,我的idea配置的tomcat是自己的本地的tomcat,然后进本地的目录一瞅,木有,那么这个日志放在哪里了?然后就开始找这个日志文件在哪里。开始百度。。。 经历过种种百度,然后最后得出的结果是在这里
|
1 |
C:\Users\Administrator\.IntelliJIdea14\system\tomcat\未命名_zngkpt\logs |
好了,第一步完成,找到了日志文件,那么日志文件里面的错误信息是什么呢?首先,有下面几个日志信息 根据时间来看,那就看catalina和localhost这两个吧,最后在locaohost的log文件里找到了这样的一句话:
|
1 2 3 |
三月 02, 2017 1:18:40 下午 org.apache.catalina.core.StandardContext listenerStart 严重: Error configuring application listener of class org.springframework.web.context.ContextLoaderListener java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener |
意思就是说contextloaderlistener这个class没有加载成功,说是配置的问题,然后继续百度,有一下几种情况 1,listener的配置要放在servlet前面,我看我的配置文件,的确是这样的, 2,就是tomcat缓存问题,把project的tomcat去掉后重新部署上去,我试了试,不行 3,说是没有spring的包,我想着一会好,一会不好的,如果真的是spring包的话,那应该就一直不好,所以排除了,(结果这里出现问题了) 4,重新安装tomcat,这个方法我没有试,不知道效果如何 突然,在论坛里看有人说看看你的tomcat服务器里的项目的web-info\lib下有没有这个包,然后我一查,果然没有spring的包。好的,这里问题算是找到了。就是因为这个没有包才导致的。 这个就提醒我了,不管项目上是不是加载了依赖包,如果部署到服务器上没有依赖的那个包,那就是白搭,肯定会出问题的。 最终我的web-inf\lib里面的目录结果如下 然后开启debug,成功。 上面五种方法起个参考作用,主要是第五种,用事实来说话。我的项目是idea分模块的,具体的怎样加到Lib里可以百度。 解决问题的过程是令人痛苦的,解决后感觉原来是这样啊。 from:http://www.cnblogs.com/ningheshutong/p/6490167.html
View Details解决Perhaps you are running on a JRE rather than a JDK?问题
Maven-No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK? [INFO] Scanning for projects… [INFO] [INFO] ———————————————————————— [INFO] Building helloworld 0.0.1-SNAPSHOT [INFO] ———————————————————————— [INFO] [INFO] — maven-clean-plugin:2.5:clean (default-clean) @ helloworld — [INFO] Deleting H:\mavenok\helloworld\target [INFO] [INFO] — maven-resources-plugin:2.6:resources (default-resources) @ helloworld — [INFO] Using ‘UTF-8‘ encoding to copy filtered resources. [INFO] skip non existing resourceDirectory H:\mavenok\helloworld\src\main\resources [INFO] [INFO] — maven-compiler-plugin:3.1:compile (default-compile) @ helloworld — [INFO] Changes detected – recompiling the module! [INFO] Compiling 1 source file to H:\mavenok\helloworld\target\classes [INFO] ————————————————————- […]
View Detailspom.xml出现web.xml is missing and is set to true解决方案
提示信息应该能看懂。也就是缺少了web.xml文件,<failOnMissingWebXml>被设置成true了。 搜索了一下,Stack Overflow上的答案解决了问题,分享一下。 目前被顶次数最多的回答原文如下: This is a maven error. It says that it is expecting a web.xml file in your project because it is a web application, as indicated by <packaging>war</packaging>. However, for recent web applications a web.xml file is totally optional. Maven needs to catch up to this convention. Add this to your maven pom.xml to let maven catch up and you don’t need to add a useless web.xml to your project: 大意是说这是一个Maven错误,在最近的web应用开发中web.xml文件已经变得可有可无了。不过Maven还没有跟上这一变化,我们只要在pom.xml文件中手动添加如下配置:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
<span class="tag"><build></span> <span class="tag"><plugins></span> <span class="tag"><plugin></span> <span class="tag"><groupId></span><span class="pln">org.apache.maven.plugins</span><span class="tag"></groupId></span> <span class="tag"><artifactId></span><span class="pln">maven-war-plugin</span><span class="tag"></artifactId></span> <span class="tag"><version></span><span class="pln">2.6</span><span class="tag"></version></span> <span class="tag"><configuration></span> <span class="tag"><failOnMissingWebXml></span><span class="pln">false</span><span class="tag"></failOnMissingWebXml></span> <span class="tag"></configuration></span> <span class="tag"></plugin></span> <span class="tag"></plugins></span> <span class="tag"></build></span> |
“告知”maven即可。这样做的好处是我们不必在项目生中成一个无用的web.xml文件。在更新版本(具体从哪一个版本开始我也不知道~~)的maven中已经不存在web.xml文件缺失的问题,我们只需要处理<failOnMissingWebXml>被设置成tue的问题即可。也就是在pom.xml中添加如下配置即可。
|
1 2 3 |
<span class="tag"><properties></span> <span class="tag"><failOnMissingWebXml></span><span class="pln">false</span><span class="tag"></failOnMissingWebXml></span> <span class="tag"></properties></span> |
其他方案:(生成web.xml——>部署运行时文件路径) you can do it also like this: Right click on Deployment Descriptor in Project Explorer. Select Generate Deployment Descriptor […]
View DetailsSpringBoot
Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。 特点 1. 创建独立的Spring应用程序 2. 嵌入的Tomcat,无需部署WAR文件 3. 简化Maven配置 4. 自动配置Spring 5. 提供生产就绪型功能,如指标,健康检查和外部配置 6. 绝对没有代码生成和对XML没有要求配置
View Details我的KT库之—--认识KT
什么是KT库? KT它是一个免费的、开源的(采用LGPL开源协议)函数库。它是Kingthy的个人开发库,它也可以算是一个小的开发框架包。 KT里包含有什么? KT.Core KT库的核心函数存放地方 KT.Core.Data 目前只有一个CSVTextReader对象,用于处理CSV格式的文本数据 KT.Core.Extensions 存放各种类型数据的相关扩展方法 KT.Core.Net 存放处理与网络有关的对象 KT.Core.Net.Mail 存放处理与电子邮件相关的数据对象 KT.Core.ObjectPool 存放与对象池相关的数据对象 KT.Framework KT库的简易开发框架 KT.Framework.Database 存放的是与数据库有关的已封装的数据对象 KT.Framework.Web 存放的是基于VTemplate模板引擎的Web框架封装 KT的使用环境是什么? 运行环境:.NET 4.0 开发环境:VS2010 我在哪里可以下载获取到最新的KT代码? KT目前采用托管于CodePlex开源网站,所以你可以从以下网址获取最新版本的KT库 项目地址:http://kt.codeplex.com/ from:http://www.cnblogs.com/kingthy/archive/2011/08/08/2130973.html
View DetailsGroovy
Groovy是一种基于JVM(Java虚拟机)的敏捷开发语言,它结合了Python、Ruby和Smalltalk的许多强大的特性,Groovy 代码能够与 Java 代码很好地结合,也能用于扩展现有代码。由于其运行在 JVM 上的特性,Groovy 可以使用其他 Java 语言编写的库。 Groovy 是 用于Java虚拟机的一种敏捷的动态语言,它是一种成熟的面向对象编程语言,既可以用于面向对象编程,又可以用作纯粹的脚本语言。使用该种语言不必编写过多的代码,同时又具有闭包和动态语言中的其他特性。 Groovy是JVM的一个替代语言(替代是指可以用 Groovy 在Java平台上进行 Java 编程),使用方式基本与使用 Java代码的方式相同,该语言特别适合与Spring的动态语言支持一起使用,设计时充分考虑了Java集成,这使 Groovy 与 Java 代码的互操作很容易。(注意:不是指Groovy替代java,而是指Groovy和java很好的结合编程。
View DetailsC#进阶系列——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、基础类型参数
|
1 2 3 4 5 |
[HttpGet] public string GetAllChargingData(int id, string name) { return "ChargingData" + id; } |
|
1 2 3 4 5 6 7 8 9 10 |
$.ajax({ type: "get", url: "http://localhost:27221/api/Charging/GetAllChargingData", data: { id: 1, name: "Jim", bir: "1988-09-11"}, success: function (data, status) { if (status == "success") { $("#div_test").html(data); } } }); |
参数截图效果 这是get请求最基础的参数传递方式,没什么特别好说的。 2、实体作为参数 如果我们在get请求时想将实体对象做参数直接传递到后台,是否可行呢?我们来看看。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public class TB_CHARGING { /// <summary> /// 主键Id /// </summary> public string ID { get; set; } /// <summary> /// 充电设备名称 /// </summary> public string NAME { get; set; } /// <summary> /// 充电设备描述 /// </summary> public string DES { get; set; } /// <summary> /// 创建时间 /// </summary> public DateTime CREATETIME { get; set; } } |
|
1 2 3 4 5 |
[HttpGet] public string GetByModel(TB_CHARGING oData) { return "ChargingData" + oData.ID; } |
|
1 2 3 4 5 6 7 8 9 10 11 |
$.ajax({ type: "get", url: "http://localhost:27221/api/Charging/GetByModel", contentType: "application/json", data: { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }, success: function (data, status) { if (status == "success") { $("#div_test").html(data); } } }); |
测试结果 由上图可知,在get请求时,我们直接将json对象当做实体传递后台,后台是接收不到的。这是为什么呢?我们来看看对应的http请求 原来,get请求的时候,默认是将参数全部放到了url里面直接以string的形式传递的,后台自然接不到了。 原因分析:还记得有面试题问过get和post请求的区别吗?其中有一个区别就是get请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),而post请求则是放在http协议包的包体中。 根据园友们的提议,Get请求的时候可以在参数里面加上[FromUri]即可直接得到对象。还是贴上代码:
|
1 2 3 4 5 6 7 |
var postdata = { ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }; $.ajax({ type: "get", url: "http://localhost:27221/api/Charging/GetAllChargingData", data: postdata, success: function (data, status) { } }); |
|
1 2 3 4 5 |
[HttpGet] public string GetAllChargingData([FromUri]TB_CHARGING obj) { return "ChargingData" + obj.ID; } |
得到结果: 如果你不想使用[FromUri]这些在参数里面加特性的这种“怪异”写法,也可以采用先序列化,再在后台反序列的方式。
|
1 2 3 4 5 6 7 8 9 10 11 |
$.ajax({ type: "get", url: "http://localhost:27221/api/Charging/GetByModel", contentType: "application/json", data: { strQuery: JSON.stringify({ ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }) }, success: function (data, status) { if (status == "success") { $("#div_test").html(data); } } }); |
|
1 2 3 4 5 6 |
[HttpGet] public string GetByModel(string strQuery) { TB_CHARGING oData = Newtonsoft.Json.JsonConvert.DeserializeObject<TB_CHARGING>(strQuery); return "ChargingData" + oData.ID; } |
这样在后台得到我们序列化过的对象,再通过反序列化就能得到对象。 在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开头
|
1 2 3 4 5 6 7 8 9 10 11 |
$.ajax({ type: "get", url: "http://localhost:27221/api/Charging/GetByModel", contentType: "application/json", data: { strQuery: JSON.stringify({ ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }) }, success: function (data, status) { if (status == "success") { $("#div_test").html(data); } } }); |
|
1 2 3 4 5 6 |
[HttpGet] public string GetByModel(string strQuery) { TB_CHARGING oData = Newtonsoft.Json.JsonConvert.DeserializeObject<TB_CHARGING>(strQuery); return "ChargingData" + oData.ID; } |
这是标准写法,后台加[HttpGet],参数正常得到: 为了对比,我将[HttpGet]去掉,然后再调用
|
1 2 3 4 5 6 |
//[HttpGet] public string GetByModel(string strQuery) { TB_CHARGING oData = Newtonsoft.Json.JsonConvert.DeserializeObject<TB_CHARGING>(strQuery); return "ChargingData" + oData.ID; } |
貌似没有任何问题!有人就想,那是否所有的get请求都可以省略掉[HttpGet]这个标注呢。我们试试便知。 (2)WebApi的方法名称不以get开头 我们把之前的方法名由GetByModel改成FindByModel,这个再正常不过了,很多人查询就不想用Get开头,还有直接用Query开头的。这个有什么关系吗?有没有关系,我们以事实说话。
|
1 2 3 4 5 6 7 8 9 10 11 |
$.ajax({ type: "get", url: "http://localhost:27221/api/Charging/FindByModel", contentType: "application/json", data: { strQuery: JSON.stringify({ ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" }) }, success: function (data, status) { if (status == "success") { $("#div_test").html(data); } } }); |
|
1 2 3 4 5 6 |
[HttpGet] public string FindByModel(string strQuery) { TB_CHARGING oData = Newtonsoft.Json.JsonConvert.DeserializeObject<TB_CHARGING>(strQuery); return "ChargingData" + oData.ID; } |
貌似又可行,没有任何问题啊。根据上面的推论,我们去掉[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)错误的写法
|
1 2 3 4 5 6 7 8 9 10 |
$.ajax({ type: "post", url: "http://localhost:27221/api/Charging/SaveData", data: { NAME: "Jim" }, success: function (data, status) { if (status == "success") { $("#div_test").html(data); } } }); |
|
1 2 3 4 5 |
[HttpPost] public bool SaveData(string NAME) { return true; } |
这是一种看上去非常正确的写法,可是实际情况是: (2)正确的用法
|
1 2 3 4 5 6 |
$.ajax({ type: "post", url: "http://localhost:27221/api/Charging/SaveData", data: { "": "Jim" }, success: function (data, status) {} }); |
[…]
View DetailsASP.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默认提供的路由。下面我们就简单讲解此中路由的用法。 默认模板路由 模板路由使用前需要定义路由模板。如下面默认的路由模板:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
using System; using System.Collections.Generic; using System.Linq; using System.Web.Http; namespace Supernova.Webapi { public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API 配置和服务 // Web API 路由 config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } } } |
此模板路由是新建项目默认生成的,在App_Start文件夹下。 我们可以看到此模板的URL格式是api/{controller}/{id}。api代表在资源前面要带上api目录,controller代表请求资源的控制器名称。id代表一条资源的id,id 是可选的。这种默认的模板是不带action的,所以它是以请求方式来区分资源的,我们必须在action上添加请求方式特性加以区分。 1.我们添加一个测试控制器api。
|
1 2 3 4 5 6 7 |
public class TestController : ApiController { public object Get1() { return "d1"; } } |
用fiddldr调试如下: 2.我们添加两个方法如下:
|
1 2 3 4 5 6 7 8 9 10 11 |
public class TestController : ApiController { public object Get1() { return "d1"; } public object Get2() { return "d2"; } } |
我们再用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()"} 我们将代码改为如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
public class TestController : ApiController { public object Get1() { return "d1"; } [HttpPost] public object Get2() { return "d2"; } } |
调试返回Get1的信息。 从上面两个测试我们可以得出如下结论: action的默认请求方式是HttpGet。 当多个action的 请求方式一样的话,在默认路由模板下(没有action),将会匹配多个操作。 基于上面两点结论,默认路由模板无法满足针对一种资源一种请求方式的多种操作(比如修改操作,可能针对不同的字段进行修改)。 定制模板路由 我们重新定制模板路由,如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
using System; using System.Collections.Generic; using System.Linq; using System.Web.Http; namespace Supernova.Webapi { public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API 配置和服务 // Web API 路由 config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional } ); } } } |
从上面我们可以看出,在默认路由的基础上,我们队路由模板增加了一级action。 测试api如下:
|
1 2 3 4 5 6 7 8 9 10 11 |
public class TestController : ApiController { public object Get1() { return "d1"; } public object Get2() { return "d2"; } } |
我们再通过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如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class TestController : ApiController { [Route("demo")] [HttpGet] public object Get1() { return "d1"; } [Route("demo/get")] [HttpGet] public object Get2() { return "d2"; } } |
[…]
View Detailsc# 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\"}。服务端会自动映射到对象。 提交代码如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
HttpWebRequest wReq = (HttpWebRequest)WebRequest.Create("http://localhost:37831/api/Values"); wReq.Method = "Post"; //wReq.ContentType = "application/json"; //wReq.ContentType = "application/x-www-form-urlencoded"; wReq.ContentType = "application/json"; //byte[] data = Encoding.Default.GetBytes(HttpUtility.UrlEncode("key=rfwreewr2332322232&261=3&261=4")); byte[] data = Encoding.Default.GetBytes("{\"id\":\"test1\",\"name\":\"value\"}"); wReq.ContentLength = data.Length; Stream reqStream = wReq.GetRequestStream(); reqStream.Write(data, 0, data.Length); reqStream.Close(); using (StreamReader sr = new StreamReader(wReq.GetResponse().GetResponseStream())) { string result = sr.ReadToEnd(); } |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// POST api/values //public string Post() //{ // FileInfo fi = new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "log.txt"); // StreamWriter sw = fi.CreateText(); // StreamReader sr = new StreamReader(HttpContext.Current.Request.InputStream); // sw.WriteLine("1:" + sr.ReadToEnd()+"--"+ HttpContext.Current.Request.Form[0]); // sw.Flush(); // sw.Close(); // return "{\"test\":\"1\"}"; //} // POST api/values public HttpResponseMessage PostStudent(Student student) { FileInfo fi = new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "log.txt"); StreamWriter sw = fi.AppendText(); sw.WriteLine("2:" + student.id); sw.Flush(); sw.Close(); HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent("{\"test\":\"2\"}", Encoding.GetEncoding("UTF-8"), "application/json") }; return result; } |
这篇文章里有的方法也不错:http://www.cnblogs.com/rohelm/p/3207430.html from:http://blog.csdn.net/wyqlxy/article/details/49303345
View Details