ASP.NET WebAPI Get使用复杂型别

来源:互联网 发布:淘宝店铺头像图片 编辑:程序博客网 时间:2024/06/07 05:05

在谈如何在Get下使用复杂型别之前,先来看个东西,下面的程序代码是ApiController的范本程序代码

 

view sourceprint?
01.public class ValuesController : ApiController
02.{
03.// GET api/<controller>
04.public IEnumerable<string> Get()
05.{
06.return new string[] { "value1""value2" };
07.}
08. 
09.// GET api/<controller>/5
10.public string Get(int id)
11.{
12.return "value";
13.}
14. 
15.// POST api/<controller>
16.public void Post([FromBody]string value)
17.{
18.}
19. 
20.// PUT api/<controller>/5
21.public void Put(int id, [FromBody]string value)
22.{
23.}
24. 
25.// DELETE api/<controller>/5
26.public void Delete(int id)
27.{
28.}
29.}

可以注意到在Post & Put的方法参数有个关键词[FromBody],而Get & Delete则没有,事实上没有加[FromBody]则默认为[FromUri],[FromBody]表示由请求文件本体中取得数据,就像一般窗体Post Submit一样,取得数据的来源是由请求本体中取得,而[FromUri]则表示由URI中取得资料,就像在网址列中的所夹带的参数,除此之外预设对于复杂型别也是由[FromBody]取得资料。

有了以上初步的认知之后,我们来看一下,在ApiController的模板程序代码里,Get方法很单纯只有一个参数的传入且为简单的int型别,所以我们可以用Http : // … / api / Values / 1 这样的请求执行Get(int id)方法,但事实上并非每个设计都只有需要一个简单型别参数就能搞定,有时我们可能需要2个或以上的参数才能决定我们要取得的特定一笔数据,这时您可以这样做

路由设定改为接受二个参数,分别为{p1} & {p2}

 

view sourceprint?
1.RouteTable.Routes.MapHttpRoute(
2.name: "DefaultApi",
3.routeTemplate: "webapi/{controller}/{p1}/{p2}",
4.defaults: new { id = System.Web.Http.RouteParameter.Optional }
5.);

而ApiController里的Get方法则调整为

 

view sourceprint?
1.public string Get(String p1, String p2)
2.{
3.return p1 + "/" + p2;
4.}

执行结果如下

 


 

虽然这样可以解决我们需要有多个参数的需求,不过当参数一多的话,设计上就不是那么的方便,因此如果我们想要让Get方法可以接受一个复杂型别的参数时,如下程序代码,EmpQueryParameter是一个我们自订的型别,具有二个属性,而Get方法的参数改为接受这个自订型别 www.it165.net

 

view sourceprint?
01.public class EmpQueryParameter
02.{
03.public String FirstName { getset; }
04.public String LastName { getset; }
05.}
06. 
07. 
08. 
09.public string Get(EmpQueryParameter parameter)
10.{
11.return parameter.FirstName + "/" + parameter.LastName;
12.}

接着我们把路由的设定改为如下的设定

 

view sourceprint?
01.void Application_Start(object sender, EventArgs e)
02.{
03.// 应用程序启动时执行的程序代码
04.BundleConfig.RegisterBundles(BundleTable.Bundles);
05.AuthConfig.RegisterOpenAuth();
06. 
07.RouteTable.Routes.MapHttpRoute(
08.name: "DefaultApi",
09.routeTemplate: "webapi/{controller}",
10.defaults: new { id = System.Web.Http.RouteParameter.Optional }
11.);
12.}

然后直接执行,由于我们的参数是一个复杂型别,因此我们试着在网址列输入Http : // … / webapi / values ?firstname=ian&lastname=chen 的请求,结果你会发现出现错误 "并未将对象参考设定为对象的执行个体。"

 


 

为什么会引发这个错误呢?在本文一开始笔者即提到了预设对于复杂型别是由[FromBody]取得数据,所以我们的请求虽然在网址列夹带了上?firstname=ian&lastname=chen 了,但它并不会被取得,因此就会出现这个例外错误,此时我们只要把Get方法稍加修饰一下,在参数前面指定[FromUri] 关键词

 

view sourceprint?
1.public string Get([FromUri] EmpQueryParameter parameter)
2.{
3.return parameter.FirstName + "/" + parameter.LastName;
4.}

接着再执行一次,就可以看到顺利取得参数值

 


 

在多参数需求下,使用复杂型别的好处在于,我们可以不需要因受限在路由的设定,而必须要很清楚的记得参数位置顺序,并且也不用因为不特定的参数数量而导致路由规划复杂化,如同上面的范例,即使我们把请求参数改为?lastname=chen&firstname=ian,顺序相反时,对于结果也不会产生异常,在Mapping上是以参数名称对应型别的属性名称,此外即使我们传了一个不存在型别里的属性名称参数值,也不会引发错误,该参数只会被忽略掉。因此在设计上会更佳方便及具有弹性。

若本文对您有所帮助,欢迎转贴,但请在加注【转贴】及来源出处,并在附上本篇的超级链接,感恩您的配合啰。

0 0
原创粉丝点击