1

Breeze を使用して OData サービスを使用する際に問題が発生しました。このガイドに従って Web API OData サービスをセットアップしました。Fiddlerからは期待どおりに機能しますが、breeze で使用しようとすると失敗し、エラー メッセージが表示されます。 「OK」の:

[Q] Unhandled rejection reasons (should be empty):Error: OK

フィドラーを使用すると、メタデータを照会してから、正しく返されたエンティティを照会しますが、ここで何が問題になる可能性がありますか?

breeze.config.initializeAdapterInstances({ dataService: "OData" });
var manager = new breeze.EntityManager(serverAddress);

var query = new breeze.EntityQuery.from("Laboratories");

manager.executeQuery(query).then(function (data) {
    ko.applyBindings(data);
}).fail(function (e) {
    alert(e);
});

ASP.NET Web API CORS サポートのナイトリー ビルドを使用して CORS を有効にしました。すべて正常に動作し、フィドラーでエンティティが返されたことを確認できるため、エンティティを取得できます。次に、代わりに失敗することを約束します。

アップデート:

新しく作成されたプロジェクトからの @Ward テストに対応して、次のことを行いました。

プロジェクト1

Web API プロジェクトを作成しました。

Nuget からの Microsoft ASP.MET Web API Cross-Origin Resource Sharing (CORS) リファレンスを追加しました。

次のコントローラーを追加しました。

namespace CORSBreezeTest1.Controllers
{
    public class ValuesController : EntitySetController<Value, int>
    {
        ValuesDbContext _context = new ValuesDbContext();

        [Queryable]
        public override IQueryable<Value> Get()
        {
            return _context.Values;
        }

        protected override Value GetEntityByKey(int key)
        {
            return _context.Values.Find(key);
        }

        protected override Value CreateEntity(Value entity)
        {
            Value value = _context.Values.Find(entity.Id);
            if (value != null)
            {
                throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Conflict));
            }
            _context.Values.Add(entity);
            _context.SaveChanges();
            return entity;
        }

        protected override int GetKey(Value entity)
        {
            return entity.Id;
        }

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

そして、次の Code First データベース:

namespace CORSBreezeTest1
{
    public class ValuesDbContext : DbContext
    {
        public ValuesDbContext()
            : base("DefaultConnection")
        {

        }

        public DbSet<Value> Values { get; set; }
    }

    public class Value
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        public string Name { get; set; }

        public int Quantity { get; set; }
    }
}

に次の行を追加しましたWebApiConfig.cs

public static void Register(HttpConfiguration config)
{

 // Default code left out here ...

 config.Routes.MapODataRoute("Values", "odata", GetEdmModel());
 config.EnableQuerySupport();
 config.EnableCors(new EnableCorsAttribute("*", "*", "*"));

}

private static IEdmModel GetEdmModel()
{
    ODataModelBuilder builder = new ODataConventionModelBuilder();
    builder.Namespace = "CORSBreezeTest1";
    builder.EntitySet<Value>("Values");
    return builder.GetEdmModel();
}

プロジェクト 2 次に、別の Web API プロジェクトを作成しました。

Breeze for ASP.NET Web API プロジェクト Nuget パッケージを追加

datajs Nuget パッケージを追加しました。

次のコード行を に追加しましたIndex.cshtml

<p data-bind="visible: !results">Fetching data ... </p>
<ul data-bind="foreach: results, visible: results" style="display: none">
    <li>
        <span data-bind="text: Name"></span>
        <span data-bind="text: Quantity"></span>
    </li>
</ul>


@section Scripts {
    <script src="~/Scripts/knockout-2.2.0.debug.js"></script>
    <script src="~/Scripts/q.js"></script>
    <script src="~/Scripts/datajs-1.1.0.js"></script>
    <script src="~/Scripts/breeze.min.js"></script>
    <script type="text/javascript">
        $(function () {
            breeze.config.initializeAdapterInstances({ dataService: "OData" });
            var manager = new breeze.EntityManager("http://serverAddress/odata")
            var query = new breeze.EntityQuery.from("Values");
            manager.executeQuery(query).then(function (data) {
                ko.applyBindings(data);
            }).fail(function (e) {
                alert(e);
            });
        });
    </script>
}

両方のウェブサイトがローカルホスト上にあるため、そのままテストされ、機能しました。

PROJECT 1 を Web サーバーに公開して、テストで実際に異なるオリジンが表示されるようにし、テストします。

ここに画像の説明を入力

そして、これはナゲットが見たものです:

ここに画像の説明を入力

最初のリクエスト ヘッダーは OPTIONS です

OPTIONS /odata/Values HTTP/1.1

2 番目の要求ヘッダーは GET です

GET /odata/Values HTTP/1.1

そして、failコードを次のように変更すると:

fail(function (e) {
 ko.applyBindings(e.body.value);
});

そして、私のノックアウトコードは次のとおりです。

<p data-bind="visible: !$data">Fetching data ... </p>
<ul data-bind="foreach: $data, visible: $data" style="display: none">
    <li>
        <span data-bind="text: Name"></span>
        <span data-bind="text: Quantity"></span>
    </li>
</ul>

出来上がり!次のデータが得られました。

ここに画像の説明を入力

そして、これはコンソールが見たものです:

SEC7118: XMLHttpRequest for http://serverAddress/odata/$metadata required Cross Origin Resource Sharing (CORS). 
localhost:53317
SEC7119: XMLHttpRequest for http://serverAddress/odata/$metadata required CORS preflight. 
localhost:53317
SEC7118: XMLHttpRequest for http://serverAddress/odata/Values required Cross Origin Resource Sharing (CORS). 
localhost:53317
SEC7119: XMLHttpRequest for http://serverAddress/odata/Values required CORS preflight. 
localhost:53317
[Q] Unhandled rejection reasons (should be empty):Error: OK 

を使用したプロジェクト 1 & 2BreezeControllerAttribute

別のテストで、Breeze Nuget の例に従って新しいコントローラーを追加し、Breeze for ASP.NET Web API プロジェクト Nuget パッケージを追加して、次のコントローラーを追加する場合:

namespace CORSBreezeTest1.Controllers
{
    [BreezeController]
    public class BreezeValuesController : ApiController
    {
        readonly EFContextProvider<ValuesDbContext> _context =
            new EFContextProvider<ValuesDbContext>();

        [HttpGet]
        public string Metadata()
        {
            return _context.Metadata();
        }

        [HttpGet]
        public IQueryable<Value> Values()
        {
            return _context.Context.Values;
        }

        [HttpPost]
        public SaveResult SaveChanges(JObject saveBundle)
        {
            return _context.SaveChanges(saveBundle);
        }

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

次に、クライアントを次のように変更します。

//breeze.config.initializeAdapterInstances({ dataService: "OData" });
var manager = new breeze.EntityManager("http://serverAddress/breeze/BreezeValues")

次に、リクエストが変更されます。

ここに画像の説明を入力

そして、すべてが機能します...一部がEntitySetControllerリクエストを異なる方法で処理するものなのか、dataService.

4

3 に答える 3

0

enableCors を構成してDataServiceVersion、この追加パラメーターを追加するだけです。MaxDataServiceVersion

config.EnableCors(new EnableCorsAttribute("*", "*", "*", "DataServiceVersion, MaxDataServiceVersion"));
于 2014-05-31T17:58:37.717 に答える