oDataproteries的数据获取器

时间:2015-07-08 22:15:46

标签: c# asp.net-web-api odata

我有一个带有DynamicProperties(开放式)的类,我通过oData公开它。根据我的理解,如果用户查询其中一个dynamicproperties请求转到getDynamicProperty方法(或者还有其他更好的方法吗?)。

  1. 如何获取用户尝试访问的属性?目前我正在使用oDatauriParser解析uri。这是正确的方法吗?还有其他更好的方法吗?

  2. 当我返回时,我无法返回属性的值,因为它在字典中存储为类型对象。目前我将它作为一个字符串返回。但是我想让它返回它的实际类型或任何其他可以保留其实际类型的方法,我该怎么做?

    public class BooksController : ODataController
    {           
       public IHttpActionResult getDynamicProperty([FromODataUri]string key)  
       {
    
         try
         {
            ODataUriParser uriParser = new ODataUriParser(WebApiConfig.GetEdmModel(), new Uri(Request.RequestUri.PathAndQuery, UriKind.Relative));
            OpenPropertySegment propertySegment = uriParser.ParsePath().LastSegment as OpenPropertySegment;
            if(propertySegment == null || string.IsNullOrEmpty(propertySegment.PropertyName))
            {
                return NotFound();
            }
            string property = propertySegment.PropertyName;
            Book book = getBook(key);
            return Ok(book.DynamicProperties[property].ToString());
         }
         catch(Exception)
         {
            return NotFound();
         }
       }
    }
    
    public class Book
    {
       public string ISBN { get; set; }
       public string Title { get; set; }
       public Press Press { get; set; }
       public Dictionary<string, object> DynamicProperties { get; set; }
    }
    

1 个答案:

答案 0 :(得分:0)

对于#1,我认为你不应该这样做。从Web API OData v5.6

开始,有两种方法可用于查询动态属性
  1. 会议路由
  2. 应该可以在BooksController中定义名为“GetDynamicProperty”的方法。例如:

    public IHttpActionResult GetDynamicProperty([FromODataUri] string key, [FromODataUri] string dynamicProperty)
    {
     ...
    }
    

    其中,参数名称应命名为dynamicProperty

    1. 属性路由
    2. 它应该可以在任何具有ODataRoute属性的控制器中定义随机方法。例如:

      [HttpGet]
      [ODataRoute("Books({key})/Press/{pName:dynamicproperty}")]
      public IHttpActionResult XxxxDynamicPropertyXxxx([FromODataUri] string key, [FromODataUri] string pName)
      {
      ...
      }
      

      动态属性的模板应为“{anyName:dynamicproperty}

      对于#2,请在控制器中添加以下方法,

      private IHttpActionResult Ok(object content, Type type)
      {
          var resultType = typeof(OkNegotiatedContentResult<>).MakeGenericType(type);
          return Activator.CreateInstance(resultType, content, this) as IHttpActionResult;
      }
      

      并在您的HTTP响应方法中调用它。例如:

      [HttpGet]
      [ODataRoute("Books({key})/Press/{pName:dynamicproperty}")]
      public IHttpActionResult XxxxDynamicPropertyXxxx([FromODataUri] string key, [FromODataUri] string pName)
      {
          Book book = _books.FirstOrDefault(e => e.ISBN == key);
          if (book == null)
          {
              return NotFound();
          }
      
          object value;
          if (!book.Press.DynamicProperties.TryGetValue(pName, out value))
          {
             return NotFound();
          }
      
           return Ok(value, value.GetType());
      }
      

      测试:

      如果我使用http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/use-open-types-in-odata-v4

      中的“图书”示例

      我查询

      http://localhost/odata/Books('978-0-7356-7942-9')/Authors   
      

      我可以得到结果:

      {
        "@odata.context":"http://localhost/odata/$metadata#Collection(Edm.String)","va
      lue":[
          "Leonard G. Lobel","Eric D. Boyd"
        ]
      }
      

      同时,我查询:

      http://localhost/odata/Books('978-0-7356-7942-9')/Press/Address
      

      我可以得到结果:

      {
        "@odata.context":"http://localhost/odata/$metadata#Books('978-0-7356-7942-9')/
      Press/Address","City":"Redmond","Street":"One Microsoft Way"
      }
      

      希望它可以帮到你。感谢。