且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用asp.net网页API 2 ODATA和微风CORS

更新时间:2023-02-15 19:53:00

  VAR CORS =新EnableCorsAttribute(
    HTTP://本地主机:7122 /,
    *,
    *,
    DataServiceVersion,MaxDataServiceVersion
);
config.EnableCors(CORS);

尝试添加 DataServiceVersion MaxDataServiceVersion 你的 EnableCorsAttribute
这为我工作。我发现它here.

I have problem consuming my OData with Breeze. My api is hosted on another server, and I'm using asp.net web api 2.0 (which comes with VS 2013 preview). I know web api is properly configured for CORS, because I've tested it without breeze, and it worked fine.

Here is web api 2.0 code which enables CORS:

var cors = new EnableCorsAttribute("http://localhost:7122/", "*", "*");
config.EnableCors(cors);

Here is my IEdmModel

private static IEdmModel CreateModel()
{
    var modelBuilder = new ODataConventionModelBuilder {Namespace = "Test.Domain.Model"};
    modelBuilder.EntitySet<MuscleGroup>("MuscleGroup");
    modelBuilder.EntitySet<Exercise>("Exercises");
    modelBuilder.EntitySet<ExerciseCategory>("ExerciseCategories");
    modelBuilder.EntitySet<Muscle>("Muscle");

    return modelBuilder.GetEdmModel();
}

Here is controller:

[EnableCors(origins: "http://localhost:7122", headers: "*", methods: "*")] //this enables CORS for controller 
public class MuscleGroupController : EntitySetController<MuscleGroup, int>
{
    private readonly DatabaseContext _databaseContext = new DatabaseContext();

    [Queryable]
    public override IQueryable<MuscleGroup> Get()
    {
        return _databaseContext.MuscleGroups;
    }

    protected override MuscleGroup GetEntityByKey(int key)
    {
        return _databaseContext.MuscleGroups.Find(key);
    }
}

Here is how I consume OData using breeze:

app.adminMuscleGroup.dataService = ( function(breeze, logger) {

    breeze.config.initializeAdapterInstances({ dataService: "OData" });

    var servicename = "http://localhost:23758/odata/";

    var manager = new breeze.EntityManager(servicename);

    manager.enableSaveQueuing(true);

    var dataService = {
        getAll: getAll,
    };

    return dataService;

    function getAll() {
        var query = breeze.EntityQuery.from("MuscleGroup").orderBy("Name");

        return manager.executeQuery(query);
    }

And here is error I get:

Failed to load resource: the server responded with a status of 400 (Bad Request) http://localhost:23758/odata/$metadata
Failed to load resource: Origin http://localhost:7122 is not allowed by Access-Control-Allow-Origin. http://localhost:23758/odata/$metadata
XMLHttpRequest cannot load http://localhost:23758/odata/$metadata. Origin http://localhost:7122 is not allowed by Access-Control-Allow-Origin. MuscleGroup:1
[Q] Unhandled rejection reasons (should be empty): 
Array[0]
 q.js:891
Error: Metadata query failed for: http://localhost:23758/odata/$metadata;  Logger.js:52

What I don't get is why url for query is: http://localhost:23758/odata/$metadata instead of http://localhost:23758/odata/$metadata#MuscleGroup

I know this answer explains how to use breeze with CORS, but I believe this was prior web api 2 and that I don't need to write class for CORS handling as I can do it now with:

var cors = new EnableCorsAttribute("http://localhost:7122/", "*", "*"); 

Long story short, my api handles CORS well (I've tested it) but for some reason it doesn't work with breeze.

EDIT

I've deleted this line [EnableCors(origins: "http://localhost:7122", headers: "*", methods: "*")] from controller, and just enabled CROS globbaly, but now I get this error:

[Q] Unhandled rejection reasons (should be empty): 
Array[0]
 q.js:891
Error: Metadata query failed for http://localhost:23758/odata/$metadata; Unable to process returned metadata: Cannot read property 'end' of null Logger.js:52

And I don't know what this property end is, as it isn't defined in my entities

var cors = new EnableCorsAttribute(
    "http://localhost:7122/",
    "*",
    "*",
    "DataServiceVersion, MaxDataServiceVersion"
);
config.EnableCors(cors);

Try adding DataServiceVersion and MaxDataServiceVersion to your EnableCorsAttribute. This worked for me. I found it here.