Are there examples of AngularJS + ASP.NET-WebApi + OData + Breeze.js + Typescript or is someone trying to combine these

I try to combine these technologies, but nothing good comes, because entity structure metadata is not consumed by breeze.js, even all configurations where setup is a bit complicated situation, there are literally no examples of that, so this is my example code that doesn't It works properly, but for some reason, maybe someone will find my mistake and ultimately help to solve this riddle or find it a starting point.

OdataService.ts

'use strict'; module twine.components { class MetadataStoreOptions implements breeze.MetadataStoreOptions{ namingConvention:breeze.NamingConvention = breeze.NamingConvention.defaultInstance; } class Manager implements breeze.EntityManagerOptions { metadataStore: breeze.MetadataStore; constructor( public dataService: breeze.DataService) { } } class DataServiceOptions implements breeze.DataServiceOptions { serviceName = 'http://twine.azurewebsites.net/odata'; hasServerMetadata = true; } export class ODataService { options: Manager; manager: breeze.EntityManager; metadataStore: breeze.MetadataStore; storeOptions: MetadataStoreOptions; static $inject: string[] = ['$http', '$rootScope']; cache: twine.Model.IEntity[]; constructor(private $http: ng.IHttpService, private $rootScope: ng.IRootScopeService){ this.storeOptions = new MetadataStoreOptions(); this.metadataStore = new breeze.MetadataStore(this.storeOptions); this.options = new Manager( new breeze.DataService( new DataServiceOptions() )); this.options.metadataStore = this.metadataStore; this.manager = new breeze.EntityManager( this.options ); breeze.config.initializeAdapterInstance('dataService', 'webApiOData', true); //this.manager.fetchMetadata((meta) => { // this.metadataStore.importMetadata(meta); //}); } All( query:breeze.EntityQuery, successCallback: Function, failCallback?: Function ): void { this.manager.executeQuery( query ) .then( ( data: breeze.QueryResult ) => { successCallback( data ); this.$rootScope.$apply(); }) .catch( ( reason: any ) => { if ( failCallback ) { failCallback( reason ); } }); } Get( key:number, successCallback: Function, failCallback?: Function ): void { //this.manager.fetchMetadata(); //var entityType = this.manager.metadataStore.getEntityType('Tag'); //var entityKey = new breeze.EntityKey(entityType, key); this.manager.fetchEntityByKey( 'Tag', key ) .then( ( data: breeze.EntityByKeyResult ) => { successCallback( data ); this.$rootScope.$apply(); }) .catch( ( reason: any ) => { if ( failCallback ) { failCallback( reason ); } }); } } } 

And this is tagController.ts

 'use strict'; module twine.routes { interface ITagsScope extends ng.IScope { vm: TagsCtrl; } interface ITagsCtrl extends twine.components.ITwineRoute{ tags:any[]; getTags: () => void; tag: any[]; getTag: (id:number) => void; } export class TagsCtrl implements ITagsCtrl{ /* @ngInject */ static controllerId: string = 'TagsController'; static controllerAsId: string = 'tagsCtrl'; static $inject: string[] = ["$scope", "ODataService", '$route']; entityQueryName: string = 'Tag'; query: breeze.EntityQuery; tags:any; tag: any; constructor (private $scope: ITagsScope, private ODataService: twine.components.ODataService, $route: ng.route.IRouteService) { this.query = new breeze.EntityQuery(this.entityQueryName); if($route.current && $route.current.params.id){ this.getTag($route.current.params.id); } else { this.getTags(); } } getTags() { this.ODataService.All(this.query , (data) => { this.tags = data.results[0].value; }, (error) => { console.log('error', error); }); } getTag(id:number){ this.ODataService.Get(id , (data) => { this.tag = data.results[0].value; }, (error) => { console.log('error', error); }); } } } 

There are many errors in different configurations, sometimes it is There is no resourceName for this query or EntityKey must be set , or Other stupid errors , which really should not appear, because it is typescript that does not allow type mismatches, but the configuration itself is incorrect.

And this is an abstract controller

 [EnableCors(origins: "*", headers: "*", methods: "*")] public abstract class EntityController<T> : ODataController where T: Entity { protected ODataRepository<T> repo = new ODataRepository<T>(); private static ODataValidationSettings _validationSettings = new ODataValidationSettings(); public EntityController() { } // GET: odata/Entity [EnableQuery] public IQueryable<T> Get(ODataQueryOptions<T> queryOptions) { try { queryOptions.Validate(_validationSettings); } catch (ODataException ex) { Trace.WriteLine(ex.Message); return null; } return repo.All(); } // GET: odata/Entity(5) [EnableQuery] public SingleResult<T> Get([FromODataUri] long key, ODataQueryOptions<T> queryOptions) { try { queryOptions.Validate(_validationSettings); } catch (ODataException ex) { Trace.WriteLine(ex.Message); return null; } return SingleResult.Create(repo.All().Where(x=>x._id == key)); } //ommitted } 

And finally, this is the ASP.NET webApi configuration

 public static class WebApiConfig { public static void Register(HttpConfiguration config) { //    -API config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html")); //  -API config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); //CORS var cors = new EnableCorsAttribute( "*", "*", "*", "DataServiceVersion, MaxDataServiceVersion" ); config.EnableCors(cors); //  Odata //config.EnableQuerySupport(); config.AddODataQueryFilter(); Builder<Account>(config); Builder<Branch>(config); Builder<Bucket>(config); Builder<Ingredient>(config); Builder<Like>(config); Builder<Meetup>(config); Builder<Shot>(config); Builder<Skill>(config); Builder<Tag>(config); Builder<Team>(config); } private static void Builder<T>(HttpConfiguration config) where T: class { var entityType = Activator.CreateInstance<T>().GetType(); if (entityType != null) { var builder = new ODataConventionModelBuilder(); builder.EntitySet<T>(entityType.Name); config.Routes.MapODataServiceRoute("odata_" + entityType.Name, "odata", builder.GetEdmModel()); } } } 

For testing purposes, I have this working support for the OData service at http://twine.azurewebsites.net/odata/Tag (there are currently no restrictions from CORS, feel free to), the last object can be changed to a different name based on the configuration method webApi Build . Please feel free to ask for any other information. If someone needs a whole source, I am ready to publish it on github

Update

Forget about stretching, the problem is in the Get ODataService method. I can’t bind metadata from the server to the breeze, the Everything method works fine. But the fetchByEntityKey request throws the errors described above

+6
source share
3 answers

evc, please see the following article in AngularJs applications / projects. You will find examples of projects that you can actually follow and learn with using AngularJs, Breeze, Asp.net Web api. You are right, there is a lot of material, but not so effective. Hope it helps. http://www.learn-angularjs-apps-projects.com/

+3
source

Check out the Breeze samples, especially the WEB Api OData and Breeze . This is a sample tutorial for angularjs + webapi + odata + breeze, no typescript (but not javascript just typescript :). For your WEB Api controllers, you definitely need to install this nuget package:

 PM> Install-Package Breeze.Server.WebApi2 

This will allow you to create a wind-driven api controller and easily view the odata metada breeze using Breeze.Server.ContextProviderClass.

+3
source

You can also check out the excellent but paid tuition from Pluralsight. It spans SPA from scratch using JavaScript, Angular, and Breeze.

http://www.pluralsight.com/courses/build-apps-angular-breeze

+2
source

Source: https://habr.com/ru/post/983814/


All Articles