Base solution for your next web application

Activities of "finallyfreeguy"

Abstract version of OrganizationUnit would be nice...

/// <summary>
    /// Represents an organization unit (OU).
    /// </summary>
    public abstract class OrganizationUnitBase<TSelf> : FullAuditedEntity<long>, IMayHaveTenant
    {
        /// <summary>
        /// Maximum length of the <see cref="DisplayName"/> property.
        /// </summary>
        public const int MaxDisplayNameLength = 128;

        /// <summary>
        /// Maximum depth of an UO hierarchy.
        /// </summary>
        public const int MaxDepth = 16;

        /// <summary>
        /// Length of a code unit between dots.
        /// </summary>
        public const int CodeUnitLength = 5;

        /// <summary>
        /// Maximum length of the <see cref="Code"/> property.
        /// </summary>
        public const int MaxCodeLength = MaxDepth * (CodeUnitLength + 1) - 1;

        /// <summary>
        /// TenantId of this entity.
        /// </summary>
        public virtual int? TenantId { get; set; }

        /// <summary>
        /// Parent <see cref="OrganizationUnitBase"/>.
        /// Null, if this OU is root.
        /// </summary>
        [ForeignKey("ParentId")]
        public virtual TSelf Parent { get; set; }

        /// <summary>
        /// Parent <see cref="OrganizationUnitBase"/> Id.
        /// Null, if this OU is root.
        /// </summary>
        public virtual long? ParentId { get; set; }

        /// <summary>
        /// Hierarchical Code of this organization unit.
        /// Example: "00001.00042.00005".
        /// This is a unique code for a Tenant.
        /// It's changeable if OU hierarch is changed.
        /// </summary>
        [Required]
        [StringLength(MaxDisplayNameLength)]
        public virtual string Code { get; set; }

        /// <summary>
        /// Display name of this role.
        /// </summary>
        [Required]
        [StringLength(MaxDisplayNameLength)]
        public virtual string DisplayName { get; set; }

        /// <summary>
        /// Children of this OU.
        /// </summary>
        public virtual ICollection<TSelf> Children { get; set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="OrganizationUnitBase"/> class.
        /// </summary>
        public OrganizationUnitBase()
        {

        }

        /// <summary>
        /// Initializes a new instance of the <see cref="OrganizationUnitBase"/> class.
        /// </summary>
        /// <param name="tenantId">Tenant's Id or null for host.</param>
        /// <param name="displayName">Display name.</param>
        /// <param name="parentId">Parent's Id or null if OU is a root.</param>
        public OrganizationUnitBase(int? tenantId, string displayName, long? parentId = null)
        {
            TenantId = tenantId;
            DisplayName = displayName;
            ParentId = parentId;
        }

        /// <summary>
        /// Creates code for given numbers.
        /// Example: if numbers are 4,2 then returns "00004.00002";
        /// </summary>
        /// <param name="numbers">Numbers</param>
        public static string CreateCode(params int[] numbers)
        {
            if (numbers.IsNullOrEmpty())
            {
                return null;
            }

            return numbers.Select(number => number.ToString(new string('0', CodeUnitLength))).JoinAsString(".");
        }

        /// <summary>
        /// Appends a child code to a parent code. 
        /// Example: if parentCode = "00001", childCode = "00042" then returns "00001.00042".
        /// </summary>
        /// <param name="parentCode">Parent code. Can be null or empty if parent is a root.</param>
        /// <param name="childCode">Child code.</param>
        public static string AppendCode(string parentCode, string childCode)
        {
            if (childCode.IsNullOrEmpty())
            {
                throw new ArgumentNullException("childCode", "childCode can not be null or empty.");
            }

            if (parentCode.IsNullOrEmpty())
            {
                return childCode;
            }

            return parentCode + "." + childCode;
        }

        /// <summary>
        /// Gets relative code to the parent.
        /// Example: if code = "00019.00055.00001" and parentCode = "00019" then returns "00055.00001".
        /// </summary>
        /// <param name="code">The code.</param>
        /// <param name="parentCode">The parent code.</param>
        public static string GetRelativeCode(string code, string parentCode)
        {
            if (code.IsNullOrEmpty())
            {
                throw new ArgumentNullException("code", "code can not be null or empty.");
            }

            if (parentCode.IsNullOrEmpty())
            {
                return code;
            }

            if (code.Length == parentCode.Length)
            {
                return null;
            }

            return code.Substring(parentCode.Length + 1);
        }

        /// <summary>
        /// Calculates next code for given code.
        /// Example: if code = "00019.00055.00001" returns "00019.00055.00002".
        /// </summary>
        /// <param name="code">The code.</param>
        public static string CalculateNextCode(string code)
        {
            if (code.IsNullOrEmpty())
            {
                throw new ArgumentNullException("code", "code can not be null or empty.");
            }

            var parentCode = GetParentCode(code);
            var lastUnitCode = GetLastUnitCode(code);

            return AppendCode(parentCode, CreateCode(Convert.ToInt32(lastUnitCode) + 1));
        }

        /// <summary>
        /// Gets the last unit code.
        /// Example: if code = "00019.00055.00001" returns "00001".
        /// </summary>
        /// <param name="code">The code.</param>
        public static string GetLastUnitCode(string code)
        {
            if (code.IsNullOrEmpty())
            {
                throw new ArgumentNullException("code", "code can not be null or empty.");
            }

            var splittedCode = code.Split('.');
            return splittedCode[splittedCode.Length - 1];
        }

        /// <summary>
        /// Gets parent code.
        /// Example: if code = "00019.00055.00001" returns "00019.00055".
        /// </summary>
        /// <param name="code">The code.</param>
        public static string GetParentCode(string code)
        {
            if (code.IsNullOrEmpty())
            {
                throw new ArgumentNullException("code", "code can not be null or empty.");
            }

            var splittedCode = code.Split('.');
            if (splittedCode.Length == 1)
            {
                return null;
            }

            return splittedCode.Take(splittedCode.Length - 1).JoinAsString(".");
        }
    }

We can use it in many entities like ProductCategory, CustomerCategory, UserCategory...

public class ProductOrganization : OrganizationUnitBase<ProductOrganization>
    {
        public ProductOrganization()
        {
        }

        public ProductOrganization(int? tenantId, string displayName, long? parentId = null)
            : base(tenantId, displayName, parentId)
        {

        }
    }

In EF tph or tpt have advantages and disadvantages therefore I dont want to use table hierarchy if I dont have a good reason. For learning purpose could you explain why abstract entities leads framework more complex?

I need to host WebAPI and Dynamic WebAPI controllers in standalone windows form application. Is there any sample or document to do this?

Good starting point... [https://github.com/aspnetboilerplate/aspnetboilerplate/issues/561])

I have an authorization problem with application service. I can successfully get result from application service but if I use AbpAuthorize attribute with the same service it returns unAuthorizedRequest true.

I'm using Content-Type and Authorization (Bearer) headers that explained in [http://www.aspnetboilerplate.com/Pages/Documents/Zero/Startup-Template#token-based-authentication]) document.

Returned json :

{
  "success": false,
  "result": null,
  "error": {
    "code": 0,
    "message": "No user logged in!",
    "details": null,
    "validationErrors": null
  },
  "unAuthorizedRequest": true
}

Meanwhile Tenant/GetTenants service returns the result without any problem but my application service is unauthorized. Edit : Ahh sorry. GetTenants is an anonymous function.

Any advice?

Try data.result instead of data.workTypes in success event.

From AbpAuditLogs...

Abp.Authorization.AbpAuthorizationException: Kullanıcı girişi yapılmamış!
   konum: Abp.Authorization.AuthorizeAttributeHelper.<AuthorizeAsync>d__13.MoveNext() D:\Halil\GitHub\aspnetboilerplate\src\Abp\Authorization\AuthorizeAttributeHelper.cs içinde: satır 29
--- Özel durumun oluşturulduğu önceki konumdan başlayan yığın izlemesinin sonu ---
   konum: System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   konum: System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   konum: Nito.AsyncEx.AsyncContext.<>c__DisplayClass3.<Run>b__1(Task t)
   konum: System.Threading.Tasks.ContinuationTaskFromTask.InnerInvoke()
   konum: System.Threading.Tasks.Task.Execute()
--- Özel durumun oluşturulduğu önceki konumdan başlayan yığın izlemesinin sonu ---
   konum: System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   konum: System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   konum: Nito.AsyncEx.AsyncContext.Run(Func`1 action)
   konum: Abp.Authorization.AuthorizeAttributeHelper.Authorize(IEnumerable`1 authorizeAttributes) D:\Halil\GitHub\aspnetboilerplate\src\Abp\Authorization\AuthorizeAttributeHelper.cs içinde: satır 45
   konum: Abp.Authorization.Interceptors.AuthorizationInterceptor.Authorize(IEnumerable`1 authorizeAttributes) D:\Halil\GitHub\aspnetboilerplate\src\Abp\Authorization\Interceptors\AuthorizationInterceptor.cs içinde: satır 86
   konum: Abp.Authorization.Interceptors.AuthorizationInterceptor.Intercept(IInvocation invocation) D:\Halil\GitHub\aspnetboilerplate\src\Abp\Authorization\Interceptors\AuthorizationInterceptor.cs içinde: satır 43
   konum: Castle.DynamicProxy.AbstractInvocation.Proceed()
   konum: Abp.Domain.Uow.UnitOfWorkInterceptor.PerformSyncUow(IInvocation invocation, UnitOfWorkOptions options) D:\Halil\GitHub\aspnetboilerplate\src\Abp\Domain\Uow\UnitOfWorkInterceptor.cs içinde: satır 53
   konum: Abp.Domain.U...

AuthorizeAttributeHelper class throws an exception in AuthorizeAsync method. Line number is 29.

if (!AbpSession.UserId.HasValue)
            {
                throw new AbpAuthorizationException(LocalizationManager.GetString(AbpConsts.LocalizationSourceName, "CurrentUserDidNotLoginToTheApplication"));
            }

AbpSession.UserId has no value! I dont know why...

I think its not possible to use session in self hosted environment...

[http://stackoverflow.com/questions/11347807/httpselfhostserver-and-httpcontext-current])

Showing 1 to 10 of 12 entries