From ecd94c7b03210bc4f657883edf16ec5236cc8282 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Thu, 28 May 2026 11:39:47 +0330 Subject: [PATCH] kast ... --- .../XBaseProvidedHasTagControllerBase.cs | 805 ++++++++++++++++++ Controllers/XTagProvidedControllerBase.cs | 323 +++++++ Interfaces/IXBaseProvidedHasTagController.cs | 12 + 3 files changed, 1140 insertions(+) create mode 100644 Controllers/XBaseProvidedHasTagControllerBase.cs create mode 100644 Controllers/XTagProvidedControllerBase.cs create mode 100644 Interfaces/IXBaseProvidedHasTagController.cs diff --git a/Controllers/XBaseProvidedHasTagControllerBase.cs b/Controllers/XBaseProvidedHasTagControllerBase.cs new file mode 100644 index 0000000..48b90f6 --- /dev/null +++ b/Controllers/XBaseProvidedHasTagControllerBase.cs @@ -0,0 +1,805 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.Extensions.Logging; +using xCommons.Configurations; +using xCommons.Extensions; +using xCommons.Providers; +using xExceptions.Constants; +using xIdentityService.Controllers; +using xIdentityService.Interfaces; +using xModels.Base; +using xModels.Dtos; +using xPushService.Base; +using xPushService.Interfaces; +using xTagService.Interfaces; + +namespace xTagService.Controllers +{ + [AllowAnonymous] + public abstract class XBaseProvidedHasTagControllerBase : XBaseIdentityApiV1Controller, IXBaseProvidedHasTagController + where TEntity : XBaseEntity + where TDto : XBaseEntityDto + where THub : XBaseDtoHub + { + private readonly IXBaseProvided provider; + private readonly IXTagProvided tagProvided; + private readonly Func, IOrderedQueryable> defaultOrderBuilder; + private readonly Func, IIncludableQueryable> defaultIncludeBuilder; + + protected XBaseProvidedHasTagControllerBase( + ILogger> logger, + XAppConfiguration appConfiguration, + IXIdentityProvider identityProvider, + XValidationProvider validationProvider, + IXBaseProvided provider, + IXTagProvided tagProvided, + Func, IOrderedQueryable> defaultOrderBuilder = null, + Func, IIncludableQueryable> defaultIncludeBuilder = null + ) : base( + logger, + appConfiguration, + identityProvider, + validationProvider + ) + { + this.provider = provider; + this.tagProvided = tagProvided; + this.defaultOrderBuilder = defaultOrderBuilder; + this.defaultIncludeBuilder = defaultIncludeBuilder; + } + + // + #region Provided ... + // + #region Retrieve ... + /// + /// Get Specified Item by ID ... + /// + /// + /// + /// + /// + [HttpGet("{id}")] + public virtual async Task> Get( + [FromRoute] TKey id, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + ValidationProvider.NotNull(id); + + // + var result = await provider.Get( + id: id, + includeBuilder: !useDefaultIncludes + ? null + : defaultIncludeBuilder, + cancellationToken: cancellationToken + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Get All Exists Items ... + /// + /// + /// + /// + /// + [HttpGet("")] + public virtual async Task>> GetAll( + [FromQuery] bool useDefaultOrders = false, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + + // + var result = await provider.GetAll( + orderBuilder: !useDefaultOrders + ? null + : defaultOrderBuilder, + includeBuilder: !useDefaultIncludes + ? null + : defaultIncludeBuilder, + cancellationToken: cancellationToken + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Find an item by providing a Conditional Expression ... + /// + /// + /// + /// + /// + [HttpGet("Find/One")] + public virtual async Task> FindOne( + [FromRoute] string query, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotEmpty(query) + .ValidateGroupAsync(); + + // + var result = await provider.FindOne( + includeBuilder: !useDefaultIncludes + ? null + : defaultIncludeBuilder, + cancellationToken: cancellationToken, + predicate: x => x.PropValuesContains(query) + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Find a collection of Items by proving a Query Search ... + /// + /// + /// + /// + /// + /// + [HttpGet("Find/Many")] + public virtual async Task>> FindMany( + [FromRoute] string query, + [FromQuery] bool useDefaultOrders = false, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotEmpty(query) + .ValidateGroupAsync(); + + // + var result = await provider.FindMany( + orderBuilder: !useDefaultOrders + ? null + : defaultOrderBuilder, + includeBuilder: !useDefaultIncludes + ? null + : defaultIncludeBuilder, + cancellationToken: cancellationToken, + predicate: x => x.PropValuesContains(query) + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Retrieve Items based on XQuery Pagination structure ... + /// + /// + /// + /// + /// + /// + [HttpGet("Query")] + public virtual async Task>> Query( + [FromQuery] XQuery query, + [FromQuery] bool useDefaultOrders = false, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(query) + .ValidateGroupAsync(); + + // + var result = await provider.Query( + query: query, + predicate: null, + orderBuilder: !useDefaultOrders + ? null + : defaultOrderBuilder, + includeBuilder: !useDefaultIncludes + ? null + : defaultIncludeBuilder, + cancellationToken: cancellationToken + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Retrieve Owned Items based on XQuery Pagination structure ... + /// + /// + /// + /// + /// + /// + [HttpGet("Query/Owned")] + public virtual async Task>> QueryOwned( + [FromQuery] XQuery query, + [FromQuery] bool useDefaultOrders = false, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(query) + .ValidateGroupAsync(); + + // + var userInfo = await GetUserInfo(); + + // + var result = await provider.QueryOwned( + query: query, + predicate: null, + userInfo: userInfo, + orderBuilder: !useDefaultOrders + ? null + : defaultOrderBuilder, + includeBuilder: !useDefaultIncludes + ? null + : defaultIncludeBuilder, + cancellationToken: cancellationToken + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + #endregion + + // + #region Add/Update/Remove ... + /// + /// Add an item ... + /// + /// + /// + /// + [HttpPost("")] + public virtual async Task> Add( + [FromBody] TDto item, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(item) + .ValidateGroupAsync(); + + // + var userInfo = await GetUserInfo(); + var connectionId = GetConnectionId(); + + // + var result = await provider.Add( + item: item, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Update an item values ... + /// + /// + /// + /// + /// + [HttpPut("{id}")] + public virtual async Task> Update( + [FromRoute] TKey id, + [FromBody] TDto item, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(id) + .AddNotNull(item) + .ValidateGroupAsync(); + + // + var userInfo = await GetUserInfo(); + var connectionId = GetConnectionId(); + + // + var result = await provider.Update( + id: id, + item: item, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Remove an Item ... + /// + /// + /// + /// + [HttpDelete("{id}")] + public virtual async Task> Remove( + [FromRoute] TKey id, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(id) + .ValidateGroupAsync(); + + // + var userInfo = await GetUserInfo(); + var connectionId = GetConnectionId(); + + // + var result = await provider.Remove( + id: id, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + #endregion + #endregion + + // + #region Tag ... + /// + /// Attach Tag to Specified Item ... + /// + /// + /// + /// + /// + [HttpPost("{id}/tags/attach")] + public virtual async Task AttachTag( + [FromRoute] TKey id, + [FromBody] XBaseValueContainer tag, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate Args ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(id) + .AddNotNull(tag) + .AddNotEmpty(tag.Value) + .ValidateGroupAsync(); + + // + var userInfo = await GetUserInfo(); + var connectionId = GetConnectionId(); + + // + // Get Result ... + await tagProvided + .AttachTag( + id: id, + tag: tag.Value, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + + // + return Ok(); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Detach Tag of Specified Item ... + /// + /// + /// + /// + /// + [HttpPost("{id}/tags/detach")] + public virtual async Task DetachTag( + [FromRoute] TKey id, + [FromBody] XBaseValueContainer tag, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate Args ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(id) + .AddNotNull(tag) + .AddNotEmpty(tag.Value) + .ValidateGroupAsync(); + + // + var userInfo = await GetUserInfo(); + var connectionId = GetConnectionId(); + + // + // Get Result ... + await tagProvided + .DetachTag( + id: id, + tag: tag.Value, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + + // + return Ok(); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Attach Tags to Specified Item ... + /// + /// + /// + /// + /// + [HttpPost("{id}/tags/attachs")] + public virtual async Task AttachTags( + [FromRoute] TKey id, + [FromBody] XBaseRangeRequest tags, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate Args ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(id) + .AddNotNull(tags) + .AddNotZeroChilds(tags.Items) + .ValidateGroupAsync(); + + // + var userInfo = await GetUserInfo(); + var connectionId = GetConnectionId(); + + // + // Get Result ... + await tagProvided + .AttachTags( + id: id, + tags: tags.Items, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + + // + return Ok(); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Detach Tags of Specified Item ... + /// + /// + /// + /// + /// + [HttpPost("{id}/tags/detachs")] + public virtual async Task DetachTags( + [FromRoute] TKey id, + [FromBody] XBaseRangeRequest tags = null, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate Args ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(id) + .ValidateGroupAsync(); + + // + var userInfo = await GetUserInfo(); + var connectionId = GetConnectionId(); + + // + // Get Result ... + if (!tags.IsNull()) + { + // + await tagProvided + .DetachTags( + id: id, + tags: tags.Items, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + } + else + { + // + await tagProvided + .DetachTags( + id: id, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + } + + // + return Ok(); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Get Specified Item Tags ... + /// + /// + /// + /// + [HttpGet("{id}/tags")] + public virtual async Task>> GetTags( + [FromRoute] TKey id, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate Args ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(id) + .ValidateGroupAsync(); + + // + // Get Result ... + var result = await tagProvided.GetTags( + id: id, + cancellationToken: cancellationToken + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + #endregion + } +} \ No newline at end of file diff --git a/Controllers/XTagProvidedControllerBase.cs b/Controllers/XTagProvidedControllerBase.cs new file mode 100644 index 0000000..bf85028 --- /dev/null +++ b/Controllers/XTagProvidedControllerBase.cs @@ -0,0 +1,323 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using xCommons.Configurations; +using xCommons.Extensions; +using xCommons.Providers; +using xExceptions.Constants; +using xIdentityService.Controllers; +using xIdentityService.Interfaces; +using xModels.Base; +using xPushService.Base; +using xTagService.Interfaces; + +namespace xTagService.Controllers +{ + public abstract class XTagProvidedControllerBase : XBaseIdentityApiV1Controller, IXTagProvidedController + where TEntity : XBaseEntity + where TDto : XBaseEntityDto + where THub : XBaseDtoHub + { + private readonly IXTagProvided tagProvided; + + protected XTagProvidedControllerBase( + ILogger> logger, + XAppConfiguration appConfiguration, + XValidationProvider validationProvider, + IXIdentityProvider identityProvider, + IXTagProvided tagProvided + ) : base( + logger, + appConfiguration, + identityProvider, + validationProvider + ) + { + this.tagProvided = tagProvided; + } + + /// + /// Attach Tag to Specified Item ... + /// + /// + /// + /// + /// + [HttpPost("{id}/tags/attach")] + public virtual async Task AttachTag( + [FromRoute] TKey id, + [FromBody] XBaseValueContainer tag, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate Args ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(id) + .AddNotNull(tag) + .AddNotEmpty(tag.Value) + .ValidateGroupAsync(); + + // + var userInfo = await GetUserInfo(); + var connectionId = GetConnectionId(); + + // + // Get Result ... + await tagProvided + .AttachTag( + id: id, + tag: tag.Value, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + + // + return Ok(); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Detach Tag of Specified Item ... + /// + /// + /// + /// + /// + [HttpPost("{id}/tags/detach")] + public virtual async Task DetachTag( + [FromRoute] TKey id, + [FromBody] XBaseValueContainer tag, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate Args ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(id) + .AddNotNull(tag) + .AddNotEmpty(tag.Value) + .ValidateGroupAsync(); + + // + var userInfo = await GetUserInfo(); + var connectionId = GetConnectionId(); + + // + // Get Result ... + await tagProvided + .DetachTag( + id: id, + tag: tag.Value, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + + // + return Ok(); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Attach Tags to Specified Item ... + /// + /// + /// + /// + /// + [HttpPost("{id}/tags/attachs")] + public virtual async Task AttachTags( + [FromRoute] TKey id, + [FromBody] XBaseRangeRequest tags, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate Args ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(id) + .AddNotNull(tags) + .AddNotZeroChilds(tags.Items) + .ValidateGroupAsync(); + + // + var userInfo = await GetUserInfo(); + var connectionId = GetConnectionId(); + + // + // Get Result ... + await tagProvided + .AttachTags( + id: id, + tags: tags.Items, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + + // + return Ok(); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Detach Tags of Specified Item ... + /// + /// + /// + /// + /// + [HttpPost("{id}/tags/detachs")] + public virtual async Task DetachTags( + [FromRoute] TKey id, + [FromBody] XBaseRangeRequest tags = null, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate Args ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(id) + .ValidateGroupAsync(); + + // + var userInfo = await GetUserInfo(); + var connectionId = GetConnectionId(); + + // + // Get Result ... + if (!tags.IsNull()) + { + // + await tagProvided + .DetachTags( + id: id, + tags: tags.Items, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + } + else + { + // + await tagProvided + .DetachTags( + id: id, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + } + + // + return Ok(); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Get Specified Item Tags ... + /// + /// + /// + /// + [HttpGet("{id}/tags")] + public virtual async Task>> GetTags( + [FromRoute] TKey id, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate Args ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(id) + .ValidateGroupAsync(); + + // + // Get Result ... + var result = await tagProvided.GetTags( + id: id, + cancellationToken: cancellationToken + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + } +} \ No newline at end of file diff --git a/Interfaces/IXBaseProvidedHasTagController.cs b/Interfaces/IXBaseProvidedHasTagController.cs new file mode 100644 index 0000000..38be346 --- /dev/null +++ b/Interfaces/IXBaseProvidedHasTagController.cs @@ -0,0 +1,12 @@ +using xModels.Base; +using xPushService.Base; +using xPushService.Interfaces; + +namespace xTagService.Interfaces +{ + public interface IXBaseProvidedHasTagController : IXBaseProvidedController, IXTagProvidedController + where TEntity : XBaseEntity + where TDto : XBaseEntityDto + where THub : XBaseDtoHub + { } +} \ No newline at end of file