Есть ли какие-либо примеры AngularJS + ASP.NET-WebApi + OData + Breeze.js + Typescript или кто-то пытался объединить их?
Я пытаюсь объединить эти технологии, но ничего хорошего не получается, так как метаданные структуры сущностей не используются breeze.js, даже во всех конфигурациях, где настройка, это немного сложная ситуация, примеров в буквальном смысле нет, поэтому это мой пример кода, который не работает должным образом, но, возможно, кто-то найдет мою ошибку и в конечном итоге поможет решить эту загадку или найдет ее в качестве отправной точки.
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 );
}
});
}
}
}
И это 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 is no resourceName for this query
или жеEntityKey must be set
, или жеOther stupid errors
которые действительно не должны появляться, потому что это машинописный текст, который не допускает несоответствия типов, но сама конфигурация неверна.
И это абстрактный контроллер
[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
}
И, наконец, это конфигурация ASP.NET webApi.
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());
}
}
}
Для целей тестирования у меня есть эта рабочая служба OData наhttp://twine.azurewebsites.net/odata/Tag
, (в настоящее время CORS не имеет ограничений, не стесняйтесь) последнюю сущность можно изменить на другое имя в зависимости от конфигурации webApiBuild
метод. Пожалуйста, не стесняйтесь спрашивать любую другую информацию. Если кому-то нужен весь источник, я готов опубликовать его на github.
Забудьте об особом, проблема в методеGet
ODataService. Я не могу связать метаданные с сервера на ветер, метод Все работает отлично. Но запросfetchByEntityKey
выдает ошибки как описано выше