0

チュートリアルを使用して作成した、ローカルでホストされる Web API OData サービスを作成しました。ローカルでホストされ、コードファーストの方法で作成されたデータベースを利用します。システムには、サプライヤーと製品の 2 つのエンティティがあります。localhostXXXX/Products または /Suppliersit を使用してブラウザーから API にアクセスすると、フィードは次のように表示されます。

{
  "@odata.context":"http://localhost:64469/$metadata#Products","value":[
    {
      "Id":1,"Name":"Broken Age","Price":15.00,"Category":"Adventure","SupplierId":1
    },{
      "Id":2,"Name":"Final Fantasy IX","Price":10.00,"Category":"JRPG","SupplierId":2
    },{
      "Id":3,"Name":"Fallout 3","Price":15.00,"Category":"Action RPG","SupplierId":3
    }
  ]

ただし、PowerQuery 経由で Excel のフィードにアクセスしようとすると (他のソースから -> OData フィードから)、「リソースへのアクセスは禁止されています」というメッセージが表示されます。

これがなぜなのか誰にも理解できますか?また、どうすればそれを回避できますか?私は Web サービスで認証を行っていません。Web ブラウザーで動作するため、明らかにアクセス可能です。

誰でも提供できるあらゆる助けに大いに感謝します。

ソースは以下を参照してください。

コントローラー

public class SuppliersController : ODataController
    {
        ProductsContext db = new ProductsContext();

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }


        [EnableQuery]
        public IQueryable<Supplier> Get()
        {
            return db.Suppliers;
        }
        [EnableQuery]
        public SingleResult<Supplier> Get([FromODataUri] int key)
        {
            IQueryable<Supplier> result = db.Suppliers.Where(p => p.Id == key);
            return SingleResult.Create(result);
        }

        [EnableQuery]
        public IQueryable<Product> GetProducts([FromODataUri] int key)
        {
            return db.Suppliers.Where(m => m.Id.Equals(key)).SelectMany(m => m.Products);
        }
    }


public class ProductsController : ODataController
{
    ProductsContext db = new ProductsContext();
    private bool ProductExists(int key)
    {
        return db.Products.Any(p => p.Id == key);
    }
    protected override void Dispose(bool disposing)
    {
        db.Dispose();
        base.Dispose(disposing);
    }

    [EnableQuery]
    public IQueryable<Product> Get()
    {
        return db.Products;
    }
    [EnableQuery]
    public SingleResult<Product> Get([FromODataUri] int key)
    {
        IQueryable<Product> result = db.Products.Where(p => p.Id == key);
        return SingleResult.Create(result);
    }

    [EnableQuery]
    public SingleResult<Supplier> GetSupplier([FromODataUri] int key)
    {
        var result = db.Products.Where(m => m.Id == key).Select(m => m.Supplier);
        return SingleResult.Create(result);
    }
}

モデル:

public class Supplier
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public ICollection<Product> Products { get; set; }
    }



public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
        public string Category { get; set; }

        [ForeignKey("Supplier")]
        public int? SupplierId { get; set; }
        public virtual Supplier Supplier { get; set; }
    }

Web.Config

<connectionStrings>
    <add name="ProductsContext" connectionString="Data Source=(localdb)\v11.0; 
        Initial Catalog=ProductsContext; Integrated Security=True; MultipleActiveResultSets=True; 
        AttachDbFilename=|DataDirectory|ProductsContext.mdf"
      providerName="System.Data.SqlClient" />
  </connectionStrings>

WebApiConfig

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // New code:
            ODataModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntitySet<Product>("Products");
            builder.EntitySet<Supplier>("Suppliers");
            config.MapODataServiceRoute(
                routeName: "ODataRoute",
                routePrefix: null,
                model: builder.GetEdmModel());
        }
    }

Configuration.cs

internal sealed class Configuration : DbMigrationsConfiguration<ProductService.Models.ProductsContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
        ContextKey = "ProductService.Models.ProductsContext";
    }

    protected override void Seed(ProductService.Models.ProductsContext context)
    {
        context.Suppliers.AddOrUpdate(x => x.Id,
            new Supplier() {Id = 1, Name = "Double Fine" },
            new Supplier() { Id = 2, Name = "Square Enix" },
            new Supplier() { Id = 3, Name = "Bethesda" });

        context.Products.AddOrUpdate(x => x.Id,
            new Product() { Id = 1, SupplierId = 1, Name = "Broken Age", Price=15.00M, Category = "Adventure"},
            new Product() { Id = 2, SupplierId = 2, Name = "Final Fantasy IX", Price = 10.00M, Category = "JRPG" },
            new Product() { Id = 3, SupplierId = 3, Name = "Fallout 3", Price = 15.00M, Category = "Action RPG" });
    }
}

ProductServiceContext.cs

public class ProductsContext : DbContext
{
    public ProductsContext()
        : base("name=ProductsContext")
    {
    }
    public DbSet<Product> Products { get; set; }
    public DbSet<Supplier> Suppliers { get; set; }
}

アップデート

Curt Hagenlocher の質問によると、ブラウザーで localhost64469/$metadata にアクセスした場合の出力は次のとおりです。

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
<edmx:DataServices>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ProductService.Models">
<EntityType Name="Product">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.Int32" Nullable="false"/>
<Property Name="Name" Type="Edm.String"/>
<Property Name="Price" Type="Edm.Decimal" Nullable="false"/>
<Property Name="Category" Type="Edm.String"/>
<Property Name="SupplierId" Type="Edm.Int32"/>
<NavigationProperty Name="Supplier" Type="ProductService.Models.Supplier"/>
</EntityType>
<EntityType Name="Supplier">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.Int32" Nullable="false"/>
<Property Name="Name" Type="Edm.String"/>
<NavigationProperty Name="Products" Type="Collection(ProductService.Models.Product)"/>
</EntityType>
</Schema>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Default">
<EntityContainer Name="Container">
<EntitySet Name="Products" EntityType="ProductService.Models.Product">
<NavigationPropertyBinding Path="Supplier" Target="Suppliers"/>
</EntitySet>
<EntitySet Name="Suppliers" EntityType="ProductService.Models.Supplier">
<NavigationPropertyBinding Path="Products" Target="Products"/>
</EntitySet>
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
4

2 に答える 2

1

この問題は、私のバージョンの Excel 用 PowerQuery プラグインにありました。それは 1 つ古いバージョン (私が信じている 2.22 ではなく 2.21) であり、最新バージョンでは、私が使用していた OData のバージョンである OData v4 サポートが追加されました。

ご協力いただきありがとうございます。

于 2015-06-03T16:00:01.553 に答える
0

おそらく、PowerQuery によってサービスに送信された要求と、サービスがそれに対して何をするかを確認する必要があります。禁じられたエラーは、サービスがそれを返した場合にのみ PQ で報告されます。

于 2015-05-28T00:39:05.433 に答える