壮士断腕(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传参的更多相关文章

  1. 为Asp.net WebApi 添加跨域支持

    Nuget安装包:microsoft.aspnet.webapi.cors 原文地址:https://www.asp.net/web-api/overview/security/enabling-cr ...

  2. (摘录)ASP.NET提供文件下载函数(支持大文件、续传、速度限制、资源占用小)

    // 输出硬盘文件,提供下载 // 输入参数 _Request: Page.Request对象, _Response: Page.Response对象, _fileName: 下载文件名, _full ...

  3. ASP .NET CORE 根据环境变量支持多个 appsettings.json

    0.背景 在开发项目的过程当中,生产环境与调试环境的配置肯定是不一样的.拿个最简单的例子来说,比如连接字符串这种东西,调试环境肯定是不能连接生产数据库的.在之前的话,这种情况只能说是你 COPY 两个 ...

  4. ASP.NET Core 根据环境变量支持多个 appsettings.json配置文件 (开发和生产)

    新建一个项目,web根目录会出现一个 appsettings.json  配置文件, 此时添加--新建项,输入  appsettings.Development.json 再新增一个,appsetti ...

  5. asp.net webapi 给字段赋初始值DefaultValue 解决前端传空字符串后台接受不是“”而是NULL

    /// <summary> /// 存储ID /// </summary> public Guid SaveID { get; set; } /// <summary&g ...

  6. asp.net 通过ajax方式调用webmethod方法使用自定义类传参及获取返回参数

    实体类    public class User    {        public int Id { get; set; }        public string Name { get; se ...

  7. 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 ...

  8. ASP.NET WebApi技术从入门到实战演练

    一.课程介绍 曾经有一位不知名的讲师说过这么一句名言: 一门RPC技术不会,那么千万万门RPC技术将都不会!在今天移动互联网的时代,作为攻城师的我们,谁不想着只写一套API就可以让我们的Web, An ...

  9. [转]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 ...

随机推荐

  1. 实现echarts内外圈联动

    //控制都是通过控制series中data的name,那么将内外圈需要同事控制的部分设置为一样的名字,就可以实现内外圈联动. //但是在name相同时,会使默认分配颜色时相同,使颜色不好看,这里就需要 ...

  2. 洛谷3962 [TJOI2013]数字根

    题目描述 一个数字的数字根定义为:这个数字每一位的数字加起来求和,反复这个过程直到和小于10.例如,64357的数字跟为7,因为6+4+3+5+7=25,2+5=7个区间的数字根定义为这个区间所有数字 ...

  3. mesg---设置当前终端的写权限

    mesg命令用于设置当前终端的写权限,即是否让其他用户向本终端发信息.将mesg设置y时,其他用户可利用write命令将信息直接显示在您的屏幕上. 语法 mesg(参数) 参数 y/n:y表示运行向当 ...

  4. KM HDU 3718

    #include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> ...

  5. LiquiBase注释

    LiquiBase的注释 <createTable tableName="Role_" remarks="角色表">             < ...

  6. UVa 11085 - Back to the 8-Queens

    题目:给你一个棋盘上的八个皇后.每行一个.如今让他们互相不攻击,每一个皇后仅仅能竖着移动, 一次能够移动到本列的不论什么位置,问最少移动几步.能满足要求. 分析:搜索,八皇后.由于八皇后仅仅有92组解 ...

  7. ant安装配置问题:ANT_HOME is set incorrectly or ant could not be located. Please set ANT_HOME.

    项目用到ant 1.去官网下载:http://ant.apache.org/bindownload.cgi 2.解压至安装C盘 3.设置ANT_HOME.PATh.CLASSPATH ANT_HOME ...

  8. 基于express+redis高速实现实时在线用户数统计

    作者:zhanhailiang 日期:2014-11-09 本文将介绍怎样基于express+redis高速实现实时在线用户数统计. 1. 在github.com上创建项目uv-tj.将其同步到本地: ...

  9. IComparable接口实现自定义类型的排序

    IComparable接口实现自定义类型的排序   CompareTo(Object) 方法的实现必须返回有三个值之一 如下表中所示. 返回值 参数比较 大于0 x>y 等于0 x=y 小于0 ...

  10. bind DNS搭建笔记

    设置默认网关 偶尔会出现问题 route add default gw 192.168.0.1 .vim /etc/sysctl.conf 这里是重点 配置路由转发,路由开启等都要用到. # Cont ...