与OData的V4引发异常网页API上$选择 [英] Web Api with OData v4 throwing exception on $select

查看:305
本文介绍了与OData的V4引发异常网页API上$选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是最新版本的WebAPI和的OData的,一切都建立了工作的权利。唯一的问题是,当我尝试使用$选择。

I'm using the latest version of WebApi and OData and everything is set up to work right. The only problem is when I try to use $select .

它抛出波纹管的误差

  Object of type 'System.Linq.EnumerableQuery`1[System.Web.OData.Query.Expressions.SelectExpandBinder+SelectAll`1[WebApplication1.Controllers.Person]]' cannot be converted to type 'System.Collections.Generic.IEnumerable`1[WebApplication1.Controllers.Person]'.

我看了一下文件和他们的建议是使用 [可查询] 在控制器中的获取方法或在WebApiConfig使用 config.EnableQuerySupport 既不这些都是可用的选项。我目前使用 [EnableQuery]

I looked at the documentation and their suggestion is to use [Queryable] on top of the Get method in the controller or the in WebApiConfig to use config.EnableQuerySupport and neither of these are available options. I'm currently using [EnableQuery]

修改

OdataController:

OdataController:

    using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.OData;
using System.Xml.Serialization;

namespace WebApplication1.Controllers
{
    public class PeopleController : ODataController
    {
        // GET api/values
        [EnableQuery]
        public IQueryable<Person> Get()
        {
            return new Person[] { new Person()
            {
                Id = 1,
                FirstName = "Testing",
                LastName = "2"
            },  new Person()
            {
                Id = 2,
                FirstName = "TestTest",
                LastName = "3"
            } }.AsQueryable();
        }

        // GET api/values/5
        public Person Get(int id)
        {
            return new Person()
            {
                Id = 3,
                FirstName = "Test",
                LastName = "1"
            };
        }

        // POST api/values
        public void Post([FromBody]Person value)
        {
        }

        // PUT api/values/5
        public void Put(int id, [FromBody]Person value)
        {
        }

        // DELETE api/values/5
        public void Delete(int id)
        {
        }
    }

    public class Person
    {
        [Key]
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
}

WebApiConfig

WebApiConfig

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Web.OData;
using System.Web.OData.Builder;
using System.Web.OData.Extensions;
using System.Web.OData.Formatter;
using WebApplication1.Controllers;

namespace WebApplication1
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

            var odataFormatters = ODataMediaTypeFormatters.Create();
            config.Formatters.InsertRange(0, odataFormatters);

            ODataModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntitySet<Person>("People");
            config.AddODataQueryFilter();
            config.MapODataServiceRoute(
            routeName: "ODataRoute",
            routePrefix: "api",
            model: builder.GetEdmModel());

        }
    }
}

更新2

似乎只抛出一个错误检索XML格式的数据。 JSON似乎工作

seems to only throw an error retrieving the data in xml format. Json seems to work

推荐答案

找到了解决办法。它并不完美,但它的工作!

Found a solution. It isn't perfect but it does work!

也许是因为我已经花了它的研究几个小时,并试图将是有用的人。

Maybe it will be useful for someone because I've spent on it few hours of research and trying.

第1步创建自定义的XML格式:

Step #1 create custom xml formatter:

public class CustomXmlFormatter : MediaTypeFormatter
{
    private JsonMediaTypeFormatter jFormatter = null;
    public CustomXmlFormatter(JsonMediaTypeFormatter jFormatter)
    {
        SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("application/xml"));
        this.jFormatter = jFormatter;
    }

    public override bool CanReadType(Type type)
    {
        return false;
    }

    public override bool CanWriteType(Type type)
    {
        return true;
    }
    public override Task WriteToStreamAsync(Type type, object value, System.IO.Stream writeStream, System.Net.Http.HttpContent content, System.Net.TransportContext transportContext)
    {
        return Task.Factory.StartNew(() =>
        {
            using (MemoryStream ms = new MemoryStream())
            {
                var tsk = jFormatter.WriteToStreamAsync(type, value, ms, content, transportContext);
                tsk.Wait();
                ms.Flush();
                ms.Seek(0, SeekOrigin.Begin);

                var xDoc = XDocument.Load(JsonReaderWriterFactory.CreateJsonReader(ms, new XmlDictionaryReaderQuotas()));

                using (XmlWriter xw = XmlWriter.Create(writeStream))
                {
                    xDoc.WriteTo(xw);
                }

            }
        });
    }
}

第二步注册它的启动部分:

Step #2 register it in startup section:

        var formatters = ODataMediaTypeFormatters.Create();
        var jsonFormatter = config.Formatters.JsonFormatter;
        var customXmlFormatter = new CustomXmlFormatter(jsonFormatter);

        customXmlFormatter.AddQueryStringMapping("$format", "cxml", "application/xml");
        config.Formatters.Add(customXmlFormatter);

使用它作为
HTTP://url..../actionName $格式= CXML和放大器; $选择=的ObjectName,的ObjectId

use it as http://url..../actionName?$format=cxml&$select=ObjectName,ObjectId

这篇关于与OData的V4引发异常网页API上$选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆