OData可以通过形如http://localhost/Products?$orderby=Name这样的QueryString传递查询条件、排序等。你可以在任何Web API Controller中启用OData查询条件,并且不需要让Controller设置为OData的终结点(EndPoint),以便支持过滤、排序。

启用查询选项前,你应该看下这篇文档——OData安全指导.

启用OData查询选项

Web API支持下列的查询选项:

选项 说明
$expand 展开关联的内嵌实体
$filter 通过等式过滤查询条件(请注意:查询时区分大小写的)
$inlinecount 告诉服务器需要返回的记录数(服务器分页)。
$orderby 排序
$select 要选择的属性字段
$skip 跳过N条记录
$top 只返回最开始的N条记录

要使用OData查询条件,需要显示的启用。可以对整个Web应用程序进行配置,或者只指定特定的Controller或者Action。

全局配置,可以在global.ascx中修改,这样任意一个返回类型为IQueryable的方法都会被匹配。

 
   1:  public static class WebApiConfig
   2:      {
   3:          public static void Register(HttpConfiguration config)
   4:          {
   5:              config.Routes.MapHttpRoute(
   6:                  name: "DefaultApi",
   7:                  routeTemplate: "api/{controller}/{id}",
   8:                  defaults: new { id = RouteParameter.Optional }
   9:              );
  10:             
  11:             config.Formatters.JsonFormatter.AddQueryStringMapping("$format", "json", "application/json"); 
  12:   
  13:             config.Formatters.XmlFormatter.AddQueryStringMapping("$format", "xml", "application/xml");
  14:   
  15:              config.EnableQuerySupport();
  16:          }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

如果不需要这么处理,可以在方法或者Controller上标识。

   1:  public class ProductsController : ApiController
   2:  {
   3:      [Queryable]
   4:      IQueryable<Product> Get() {}
   5:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

查询范例

客户端驱动的分页

对于一个大数据集,客户端每次希望返回10条记录,在点击“Next”时获取下一页。请求的URI如下:

http://localhost/Products?$top=10&$skip=20

过滤

查询选项就是通过等式进行匹配,可以包含逻辑和算术操作符,String和时间函数。

返回Category为Toys的产品 http://localhost/Products?$filter=Category eq 'Toys'
返回所有价格小于10的产品列表 http://localhost/Products?$filter=Price lt 10
返回价格在5到15之间的所有产品列表 http://localhost/Products?$filter=Price ge 5 and Price le 15
返回名称中包含zz的产品列表 http://localhost/Products?$filter=substringof('zz',Name)
返回2005年以后发布的产品列表 http://localhost/Products?$filter=year(ReleaseDate) gt 2005

排序

对数据进行排序。

按价格排序 http://localhost/Products?$orderby=Price
按价格降序排列 http://localhost/Products?$orderby=Price desc
先按照category排序,然后根据价格降序排列 http://localhost/odata/Products?$orderby=Category,Price desc

服务器端驱动分页

有时候为了对API接口进行访问,可以主动在服务器端进行分页限制。要启用服务器端分页,在Queryable属性中添加参数PageSize。

   1:  [Queryable(PageSize=10)]
   2:  public IQueryable<Product> Get() 
   3:  {
   4:      return products.AsQueryable();
   5:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

经过上述设置以后,返回的消息体中应该类似于下面。其中包含了nextpage的链接,客户端可以通过该链接获取下一页。

   1:  {
   2:    "odata.metadata":"http://localhost/$metadata#Products",
   3:    "value":[
   4:      { "ID":1,"Name":"Hat","Price":"15","Category":"Apparel" },
   5:      { "ID":2,"Name":"Socks","Price":"5","Category":"Apparel" },
   6:      // Others not shown
   7:    ],
   8:    "odata.nextLink":"http://localhost/Products?$skip=10"
   9:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

如果希望得到数据库的总记录数,那么应该包含$inlinecount条件,类似于这样http://localhost/Products?$inlinecount=allpages

   1:  {
   2:    "odata.metadata":"http://localhost/$metadata#Products",
   3:    "odata.count":"50",
   4:    "value":[
   5:      { "ID":1,"Name":"Hat","Price":"15","Category":"Apparel" },
   6:      { "ID":2,"Name":"Socks","Price":"5","Category":"Apparel" },
   7:      // Others not shown
   8:    ]
   9:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

下一页链接和总记录数都需要使用OData格式。对于不是此种格式,则需要将查询结果包装在一个PageResult<T>对象中。因此需要多增加一些代码。

   1:  public PageResult<Product> Get(ODataQueryOptions<Product> options)
   2:  {
   3:      ODataQuerySettings settings = new ODataQuerySettings()
   4:      {
   5:          PageSize = 5
   6:      };
   7:   
   8:      IQueryable results = options.ApplyTo(_products.AsQueryable(), settings);
   9:   
  10:      return new PageResult<Product>(
  11:          results as IEnumerable<Product>, 
  12:          Request.GetNextPageLink(), 
  13:          Request.GetInlineCount());
  14:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

返回结果应该如下:

   1:  {
   2:    "Items": [
   3:      { "ID":1,"Name":"Hat","Price":"15","Category":"Apparel" },
   4:      { "ID":2,"Name":"Socks","Price":"5","Category":"Apparel" },
   5:   
   6:      // Others not shown
   7:      
   8:    ],
   9:    "NextPageLink": "http://localhost/api/values?$inlinecount=allpages&$skip=10",
  10:    "Count": 50
  11:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

限制查询条件

查询选项给予客户端对于服务器端查询的掌控入口,在一些条件下,处于安全和性能的理由,我们希望对可用的选项进行限制,此时需要利用Queryable属性进行处理。如果只允许使用skip和top,选项设置如下:

   1:  [Queryable(AllowedQueryOptions= AllowedQueryOptions.Skip | AllowedQueryOptions.Top)]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

如果要对排序字段进行限制(如非排序字段),应该如下:

   1:  [Queryable(AllowedOrderByProperties="Id")] //英文逗号分隔

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

在过滤条件中,只允许使用eq操作符,格式是这样:

   1:  [Queryable(AllowedLogicalOperators=AllowedLogicalOperators.Equal)]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

不允许启用算术操作符,则应该如下:

   1:  [Queryable(AllowedArithmeticOperators=AllowedArithmeticOperators.None)]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

同样,这种限制还可以对全局网站应用程序启用。

   1:  var queryAttribute = new QueryableAttribute()
   2:  {
   3:      AllowedQueryOptions = AllowedQueryOptions.Top | AllowedQueryOptions.Skip,
   4:      MaxTop = 100
   5:  };
   6:                  
   7:  config.EnableQuerySupport(queryAttribute);

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

直接调用查询选项

如果不使用Queryable标签,你还可以直接在Controller中调用查询选项。

   1:  public IQueryable<Product> Get(ODataQueryOptions opts)
   2:  {
   3:      var settings = new ODataValidationSettings()
   4:      {
   5:          // Initialize settings as needed.
   6:          AllowedFunctions = AllowedFunctions.AllMathFunctions
   7:      };
   8:   
   9:      opts.Validate(settings);
  10:   
  11:      IQueryable results = opts.ApplyTo(products.AsQueryable());
  12:      return results as IQueryable<Product>;
  13:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Web API通过URI查询条件来操作ODataQueryOptions,将一个IQueryable对象传递给ApplyTo方法,该方法返回另一个IQueryable。

对于复杂的应用场景,如果没有IQueryable查询,可以检查ODataQueryOptions并且将查询选项转换为另一种形式(例如RaghuRam Nadiminti的文章《将OData查询转换为HQL》)。

查询验证

Queryable属性在执行查询前会进行验证,实际上通过QueryableAttribute.ValidateQuery进行,你也可以对此进行自定义(可以参见OData安全指导)。

   1:  public class MyOrderByValidator : OrderByQueryValidator
   2:  {
   3:      // Disallow the 'desc' parameter for $orderby option.
   4:      public override void Validate(OrderByQueryOption orderByOption,
   5:                                      ODataValidationSettings validationSettings)
   6:      {
   7:          if (orderByOption.OrderByNodes.Any(
   8:                  node => node.Direction == OrderByDirection.Descending))
   9:          {
  10:              throw new ODataException("The 'desc' option is not supported.");
  11:          }
  12:          base.Validate(orderByOption, validationSettings);
  13:      }
  14:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

还有一种方法,也可以对Queryable属性进行扩展。

   1:  public class MyQueryableAttribute : QueryableAttribute
   2:  {
   3:      public override void ValidateQuery(HttpRequestMessage request, 
   4:          ODataQueryOptions queryOptions)
   5:      {
   6:          if (queryOptions.OrderBy != null)
   7:          {
   8:              queryOptions.OrderBy.Validator = new MyOrderByValidator();
   9:          }
  10:          base.ValidateQuery(request, queryOptions);
  11:      }
  12:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

然后再global.ascx中或者controller、action上使用。

   1:  // Globally:
   2:  config.EnableQuerySupport(new MyQueryableAttribute());
   3:   
   4:  // Per controller:
   5:  public class ValuesController : ApiController
   6:  {
   7:      [MyQueryable]
   8:      public IQueryable<Product> Get()
   9:      {
  10:          return products.AsQueryable();
  11:      }
  12:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

如果直接使用了ODataQueryOptions,可以这样处理。

   1:  public IQueryable<Product> Get(ODataQueryOptions opts)
   2:  {
   3:      if (opts.OrderBy != null)
   4:      {
   5:          opts.OrderBy.Validator = new MyOrderByValidator();
   6:      }
   7:   
   8:      var settings = new ODataValidationSettings()
   9:      {
  10:          // Initialize settings as needed.
  11:          AllowedFunctions = AllowedFunctions.AllMathFunctions
  12:      };
  13:   
  14:      // Validate
  15:      opts.Validate(settings);
  16:   
  17:      IQueryable results = opts.ApplyTo(products.AsQueryable());
  18:      return results as IQueryable<Product>;
  19:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

来源:http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options

作者:Mike Wasson(微软科技作家)

[翻译]在ASP.NET Web API中通过OData支持查询和分页的更多相关文章

  1. ASP.NET Web API中使用OData

    在ASP.NET Web API中使用OData 一.什么是ODataOData是一个开放的数据协议(Open Data Protocol)在ASP.NET Web API中,对于CRUD(creat ...

  2. 利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理

    在Asp.net Web API中,对业务数据的分页查询处理是一个非常常见的接口,我们需要在查询条件对象中,定义好相应业务的查询参数,排序信息,请求记录数和每页大小信息等内容,根据这些查询信息,我们在 ...

  3. 在ASP.NET Web API中使用OData

    http://www.alixixi.com/program/a/2015063094986.shtml 一.什么是ODataOData是一个开放的数据协议(Open Data Protocol)在A ...

  4. 在ASP.NET Web API中使用OData的Action和Function

    本篇体验OData的Action和Function功能.上下文信息参考"ASP.NET Web API基于OData的增删改查,以及处理实体间关系".在本文之前,我存在的疑惑包括: ...

  5. 在ASP.NET Web API中使用OData的Containment

    通常情况下,一个OData的EDM(Entity Data Model)在配置的时候定义了,才可以被查询或执行各种操作.比如如下: builder.EntitySet<SomeModel> ...

  6. 在ASP.NET Web API中使用OData的单例模式

    从OData v4开始增加了对单例模式的支持,我们不用每次根据主键等来获取某个EDM,就像在C#中使用单例模式一样.实现方式大致需要两步: 1.在需要实现单例模式的导航属性上加上[Singleton] ...

  7. 【ASP.NET Web API教程】6.2 ASP.NET Web API中的JSON和XML序列化

    谨以此文感谢关注此系列文章的园友!前段时间本以为此系列文章已没多少人关注,而不打算继续下去了.因为文章贴出来之后,看的人似乎不多,也很少有人对这些文章发表评论,而且几乎无人给予“推荐”.但前几天有人询 ...

  8. 【翻译】ASP.NET Web API是什么?

    原文 [翻译]ASP.NET Web API是什么? 说明:随微软ASP.NET MVC 4一起发布的还有一个框架,叫做ASP.NET Web API.目前国内关注这项技术的人似乎还很少,这方面的文章 ...

  9. ASP.NET Web API中的Controller

    虽然通过Visual Studio向导在ASP.NET Web API项目中创建的 Controller类型默认派生与抽象类型ApiController,但是ASP.NET Web API框架本身只要 ...

随机推荐

  1. Spring MVC坑汇总+Stackoverflow巧解答

    1.http://stackoverflow.com/questions/25598406/spring-annotaion-autowired-inside-methods Q: Autowire ...

  2. 如何取得jvm实例的cpu占用(转)

    时间 2014-08-29 17:11:34 田加国的博客 原文  http://www.tianjiaguo.com/programming-language/java-language/如何取得j ...

  3. Mysql报错......\xE6\x80\xBB\xE7\x9B\x91' for column...

    Mysql添加表中字符报错:Incorrect string value: '\xE6\x80\xBB\xE7\x9B\x91' for column 'postName' at row 1 原因:字 ...

  4. jenkins部署前端node项目实例

    Jenkins 分发文件用到rsync命令   在 /etc/passwd中 修改 jenkins 为 /bin/bash jenkins:x:494:494:Jenkins Automation S ...

  5. php fpm安装curl后,nginx出现connect() to unix:/var/run/php5-fpm.sock failed (13: Permission denied)的错误

    这里选择直接apt-get安装,因为比起自己编译简单多了,不需要自己配置什么 #sudo apt-get install curl libcurl3 libcurl3-dev php5-curl 安装 ...

  6. ParameterizedThreadStart,ThreadStart的使用,线程Thread传参数

    Thread threadWithParam = new Thread(new ParameterizedThreadStart(new ThreadTest().ShowMsg));//thread ...

  7. ES6中的export,import ,export default

    ES6模块主要有两个功能:export和importexport用于对外输出本模块(一个文件可以理解为一个模块)变量的接口import用于在一个模块中加载另一个含有export接口的模块.也就是说使用 ...

  8. mysql操作索引的sql语句

    创建索引 一:唯一索引alter table table_name add unique index_name(column_list); 例如:alter table users_game_task ...

  9. EF检索中文失败的解决办法

    1. MYSQL: 保证所有的的列都是UTF8格式. 2. VS2010: 在data server建立连接时,选择advance,将chracterset设成utf8,这样在VS2010里查看和更改 ...

  10. Struts2请求流程图

    ServletContext中的内容: <s:property value="#attr['countries']['cn']"/> <br> Sessio ...