ASP.NET WebAPI RC 竟然不支持最常用的json传参
壮士断腕(WCF Web API),为的是 ASP.NET Web API 的横空出世,再加上它的开放(开源),于是对之产生了一点点痴情,并写下了HttpClient + ASP.NET Web API, WCF之外的另一个选择。那时,ASP.NET Web API 还处于 beta 阶段,俗话说女大十八变,自然对 ASP.NET Web API RC 产生了憧憬。。。
ASP.NET Web API RC 闪亮登场之后,还未一睹庐山真面目,就有人陆陆续续反馈之前博文中的示例代码在 ASP.NET Web API RC 版中无法正常运行。其间,我们有一个使用了 ASP.NET Web API 的项目升级至 ASP.NET Web API RC 之后也遇到了同样的问题,通过 HttpClien 将 json 格式的数据 post 给服务器之后,服务端控制器中对应的 Action 却收不到数据,错误信息为:"The parameters dictionary contains a null entry for parameter 'startId' of non-nullable type 'System.Int32' for method..."。
开始以为是 HttpClient 的问题,之前的代码是通过 Json.NET 将需要传递的数据序列化为 json 字符串的,代码如下:

var requestJson = JsonConvert.SerializeObject(new { startId = 1, itemcount = 3 });
HttpContent httpContent = new StringContent(requestJson);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var httpClient = new HttpClient();
var responseJson = httpClient.PostAsync("http://localhost:9000/api/demo/sitelist", httpContent)
.Result.Content.ReadAsStringAsync().Result;

而 ASP.NET Web API RC 的改进之一是内置对 Json.NET 的支持,所以 post json 格式的数据更简单了,上面的代码可以改为:
var responseJson = new HttpClient().PostAsJsonAsync("http://test.cnblogs.cc/api/demo/sitelist",
new { startId = 1, itemcount = 3 }).Result.Content.ReadAsStringAsync().Result;
但是 HttpClient 的代码更改之后,问题依然存在,用 Fiddler 查看了一下 post 过去的数据,原汁原味正宗的 json 数据,看来问题出在服务器端。
这时,有人反馈通过 jQuery 的 $.ajax 提交 json 数据,服务端也收不到。不用想了,问题肯定出在服务端。看看示例程序的服务端代码:

public class DemoController : ApiController
{
public IList<Site> SiteList(int startId, int itemcount)
{
...
return result;
}
}

问题应该出在 RC 版本中,ASP.NET Web API 将接收到的 post 数据传统给 Action 的处理方式发生了改变。首先可以肯定的是,ASP.NET Web API RC 不可能不支持 json 参数。难道要为此定义一个类(比如这里叫SiteListQuery),将目前的参数都作为类的属性,代码如下:

public class DemoController : ApiController
{
public IList<Site> SiteList(SiteListQuery query)
{
...
return result;
}
} public class SiteListQuery
{
public int startId { get; set; } public int itemcount { get; set; }
}

如果真是这样,就需要定义很多这样的参数类,而且即使只有一个参数,也要定义一个类。如果真是这样,我宁愿不用 ASP.NET Web API。
当时想到这里,就没有进一步去试验,心想既然不支持常用的 json 传参方式,那就暂时不用 ASP.NET Web API RC,等正式版出来再看。
今天一位同事证实了的确需要定义一个专门的参数类,才能支持 json 传参。
当同事告诉我之后,那种爱恨交加的不是滋味的感觉就迸发出来了。怎么能这样设计,即使这样设计有它的道理,也不能放弃对通常使用方式的兼容啊。良好的兼容性是微软的发家之本,怎么在这里就被无视呢?查看 ASP.NET Web API 的源代码,这部分也没有完整的测试代码。ASP.NET 也许是微软的无心插柳,但现在柳成萌了,何不借势发展为森林呢?舍不得丢下桌面,怎能开创未来?将 ASP.NET Web Stack 开源,究竟是因为它无关紧要,还是因为真正想通过社区的力量让它发展得更好?在这样的关键时期,微软是在拿自己的劣势追赶别人的优势,还是在拿自己的优势超越别人?
痴情的不是 ASP.NET Web API,而是用更优雅的技术更好的解决实际问题;
意外的不是这个有点糟糕的设计,而且没有真正从开发者的角度去考虑。
(注:一气呵成,一吐为快,也是一种写博客的方式,写的不妥之处望见谅)
ASP.NET WebAPI RC 竟然不支持最常用的json传参的更多相关文章
- 为Asp.net WebApi 添加跨域支持
Nuget安装包:microsoft.aspnet.webapi.cors 原文地址:https://www.asp.net/web-api/overview/security/enabling-cr ...
- (摘录)ASP.NET提供文件下载函数(支持大文件、续传、速度限制、资源占用小)
// 输出硬盘文件,提供下载 // 输入参数 _Request: Page.Request对象, _Response: Page.Response对象, _fileName: 下载文件名, _full ...
- ASP .NET CORE 根据环境变量支持多个 appsettings.json
0.背景 在开发项目的过程当中,生产环境与调试环境的配置肯定是不一样的.拿个最简单的例子来说,比如连接字符串这种东西,调试环境肯定是不能连接生产数据库的.在之前的话,这种情况只能说是你 COPY 两个 ...
- ASP.NET Core 根据环境变量支持多个 appsettings.json配置文件 (开发和生产)
新建一个项目,web根目录会出现一个 appsettings.json 配置文件, 此时添加--新建项,输入 appsettings.Development.json 再新增一个,appsetti ...
- asp.net webapi 给字段赋初始值DefaultValue 解决前端传空字符串后台接受不是“”而是NULL
/// <summary> /// 存储ID /// </summary> public Guid SaveID { get; set; } /// <summary&g ...
- asp.net 通过ajax方式调用webmethod方法使用自定义类传参及获取返回参数
实体类 public class User { public int Id { get; set; } public string Name { get; se ...
- OData – the best way to REST–实例讲解ASP.NET WebAPI OData (V4) Service & Client
一.概念介绍 1.1,什么是OData? 还是看OData官网的简单说明: An open protocol to allow the creation and consumption of quer ...
- ASP.NET WebApi技术从入门到实战演练
一.课程介绍 曾经有一位不知名的讲师说过这么一句名言: 一门RPC技术不会,那么千万万门RPC技术将都不会!在今天移动互联网的时代,作为攻城师的我们,谁不想着只写一套API就可以让我们的Web, An ...
- [转]OData – the best way to REST–实例讲解ASP.NET WebAPI OData (V4) Service & Client
本文转自:http://www.cnblogs.com/bluedoctor/p/4384659.html 一.概念介绍 1.1,什么是OData? 还是看OData官网的简单说明: An open ...
随机推荐
- PHP DES-ECB加密对接Java解密
最近公司有个业务,需要对接第三方接口,但是参数是需要加密的,对方也只提供了一个java的demo,在网上到处搜索,没有找到直接就能用的方法,后来还是跟公司的Android工程师对接出来的,在这里记录一 ...
- Unity经验之谈
1.全屏与非全屏之间的切换 if (Input.GetMouseButtonDown(1)) { Screen.fullScreen = !Screen.fullScreen; } 2.Camera适 ...
- [Angular] *ngIf syntx
<div class="profile"> <img [src]="user.img" width="50px"> ...
- !HDU 2602 Bone Collector--DP--(裸01背包)
题意:这题就是一个纯粹的裸01背包 分析:WA了好几次.01背包实现的一些细节没搞懂 1.为什么dp[i][j]赋初值为0而不是value[i].由于第i个石头可能不放! 2.在进行状态转移之前要dp ...
- HDU 4572 Bottles Arrangement
具体的证明:点击打开链接 我的想法: 要想保证题目所说 构造最小行的和,仅仅能是这样的情况 ..... m-3 m-2 m-1 m | m m-1 m-2 m-3 ...
- ALTERA器件中复位电路实现之-异步复位同步化
所谓异步复位同步化,就是我们通常说的异步复位同步撤除. 为了避免纯粹的同步复位和纯粹异步复位的问题,可以使用一种叫做同步化的异步复位,我们称其为第三类复位.这种复位完全结合了异步复位和同步复位的优势, ...
- Mysql Workbench初体验
可以画图,建立表关系. 分类整理数据表. 可以直接导出sql语句. 可以导出png图片. 可以连接mysql数据库. 基本满足了各项需求. 这次初体验只是基本的功能,这个软件对于mysql还是很牛的.
- apicloud,aliyunlive,测试成功
1.推流 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...
- spring配置 quartz-config.xml
<!-- 配置调度程序quartz ,其中配置JobDetail有两种方式--> <!-- 使用MethodInvokingJobDetailFactoryBean,任务类可以不实现 ...
- sqlserver自定义函数(标量值函数,表值函数)
用户自定义的函数有两类:表值函数.标量值函数. 表值函数:返回值是数据表的函数 调用方式 select b.* from tableA a accross apply Fun_BiaoZhiFun ...