<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:a10="http://www.w3.org/2005/Atom" version="2.0">
  <channel xmlns:media="http://search.yahoo.com/mrss/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <title>ABP.IO Stories</title>
    <link>https://abp.io/community/articles</link>
    <description>A hub for ABP Framework, .NET, and software development. Access articles, tutorials, news, and contribute to the ABP community.</description>
    <lastBuildDate>Thu, 12 Nov 2026 01:25:49 Z</lastBuildDate>
    <generator>Community - ABP.IO</generator>
    <image>
      <url>https://abp.io/assets/favicon.ico/favicon-32x32.png</url>
      <title>ABP.IO Stories</title>
      <link>https://abp.io/community/articles</link>
    </image>
    <a10:link rel="self" type="application/rss+xml" title="self" href="https://abp.io/community/rss?member=onurpicakci" />
    <item>
      <guid isPermaLink="true">https://abp.io/community/posts/identityuser-relationship-and-extending-it-xtv79mpx</guid>
      <link>https://abp.io/community/posts/identityuser-relationship-and-extending-it-xtv79mpx</link>
      <a10:author>
        <a10:name>onurpicakci</a10:name>
        <a10:uri>https://abp.io/community/members/onurpicakci</a10:uri>
      </a10:author>
      <category>identity</category>
      <category>identity-user</category>
      <title>IdentityUser Relationship and Extending It</title>
      <description>In this article, I will talk about the relationships of IdentityUser in every web application that can be created with the ABP framework.</description>
      <pubDate>Tue, 21 Mar 2023 08:57:25 Z</pubDate>
      <a10:updated>2026-11-11T06:59:07Z</a10:updated>
      <content:encoded><![CDATA[<h1>Introduction</h1>
<p>In this article, I will talk about the relationships of IdentityUser in every web application that can be created with the ABP framework. When you read this article, you will learn how to extend the user entity in the applications you develop using the ABP framework with a primitive type, extending the user by associating the user with another entity (User-many-to-one-X).</p>
<h2>Creating the Solution</h2>
<blockquote>
<p>For the source code of the application: https://github.com/onurpicakci/Abp-Identity-Relationship</p>
</blockquote>
<p>In this article we will use EF Core as the database provider and MVC as the user interface framework. But Angular, Blazor Server and Blazor WebAssembly also work. ABP Framework offers starter templates to get started faster. We can create a new starter template using the ABP CLI:</p>
<pre><code class="language-bash">abp new IdentityRelationship
</code></pre>
<p>After the project is created, you can run the <code>IdentityRelationship.DbMigrator</code> project to create the database and seed the initial data. You can then run the <code>IdentityRelationship.Web</code> project to see our application run.</p>
<blockquote>
<p>The default admin username is <strong>admin</strong> and the password is <strong>1q2w3E*</strong></p>
</blockquote>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-03-20-%20IdentityUser-Relationships/images/solution-image.png" alt="solution-image" /></p>
<h2>Module Entity Extensions</h2>
<p>The module entity extension system is a high level extension system that allows you to define new properties for existing entities of the depended modules. It automatically adds properties to the entity, database, HTTP API and the user interface in a single point.</p>
<h3>Extending the User Entity With a Primitive Type</h3>
<p>Open the <code>IdentityRelationshipModuleExtensionConfigurator</code> class inside the <code>Domain.Shared</code> project of your solution and change the <code>ConfigureExtraProperties</code> method as shown below to add an <code>IdentificationNumber</code> property to the <code>IdentityUser</code> entity of the <a href="https://docs.abp.io/en/abp/latest/Modules/Identity">Identity Module</a>.</p>
<pre><code class="language-csharp">public static void ConfigureExtraProperties()
{
    OneTimeRunner.Run(() =&gt;
    {
        ObjectExtensionManager.Instance.Modules()
            .ConfigureIdentity(identity =&gt;
            {
                identity.ConfigureUser(user =&gt;
                {
                    user.AddOrUpdateProperty&lt;string&gt;( //property type: string
                        &quot;IdentificationNumber&quot;, //property name
                        property =&gt;
                        {
                            //validation rules
                            property.Attributes.Add(string.Empty);
                            property.Attributes.Add(
                                new StringLengthAttribute(64) {
                                    MinimumLength = 4
                                }
                            );

                            //...other configurations for this property
                        }
                    );
                });
            });
    });
}
</code></pre>
<blockquote>
<p>This method is called inside the IdentityRelationshipDomainSharedModule at the beginning of the application. OneTimeRunner is a utility class that guarantees to execute this code only one time per application, since multiple calls are unnecessary.</p>
</blockquote>
<p>If you want to localize, open the <code>IdentityRelationship.Domain.Shared</code> project and create a new localization in your <code>/Localization/IdentityRelationship/en.json</code> file.</p>
<pre><code class="language-json"> &quot;IdentificationNumber&quot;: &quot;Identification Number&quot;
</code></pre>
<p>Once you define a property, it appears in the create and update forms of the related entity:</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-03-20-%20IdentityUser-Relationships/images/identification-number.png" alt="identification-number" /></p>
<p>New properties also appear in the data table of the related page:</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-03-20-%20IdentityUser-Relationships/images/users-page.png" alt="users-page" /></p>
<h2>Navigation Properties / Foreign Keys</h2>
<p>It is supported to add an extension property to an entity that is the Id of another entity (foreign key).</p>
<h3>Example: Let's associate a department in the database with a user</h3>
<p>First, create a <code>Departments</code> folder in the <code>IdentityRelationship.Domain</code> project and add the <code>Department</code> class inside:</p>
<pre><code class="language-csharp">using System;
using Volo.Abp.Domain.Entities;

namespace IdentityRelationship.Departments;

public class Department : AggregateRoot&lt;Guid&gt;
{
    public string Name { get; set; }
}
</code></pre>
<p>EF Core requires that you relate the entities with your <code>DbContext</code>. The easiest way to do so is adding a DbSet property to the <code>IdentityRelationshipDbContext</code> class in the <code>IdentityRelationship.EntityFrameworkCore</code> project, as shown below:</p>
<pre><code class="language-csharp">    public DbSet&lt;Department&gt; Departments { get; set; }
</code></pre>
<p>Then in the <code>IdentityRelationship.EntityFrameworkCore</code> project of your solution, open the <code>/EntityFrameworkCore/IdentityRelationshipEfCoreEntityExtensionMappings</code> class and update your code:</p>
<pre><code class="language-csharp">public static class IdentityRelationshipEfCoreEntityExtensionMappings
{
    private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();

    public static void Configure()
    {
        IdentityRelationshipGlobalFeatureConfigurator.Configure();
        IdentityRelationshipModuleExtensionConfigurator.Configure();

        OneTimeRunner.Run(() =&gt;
        {
            ObjectExtensionManager.Instance
                .MapEfCoreProperty&lt;IdentityUser, Guid&gt;(
                    &quot;DepartmentId&quot;,
                    (entityBuilder, propertyBuilder) =&gt; { propertyBuilder.HasMaxLength(128); }
                );
                
        });
    }
}
</code></pre>
<p>This class can be used to map these extra properties to table fields in the database. Please read <a href="https://docs.abp.io/en/abp/latest/Customizing-Application-Modules-Extending-Entities?_ga=2.21022651.140118448.1679289046-1173891759.1672473062">this</a> document to improve your understanding of what we are doing.</p>
<p>We need to create a new migration to see the changes in the database. Open your <code>EntityFrameworkCore</code> project in the terminal and run the following command (this depends on the IDE you are using).</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-03-20-%20IdentityUser-Relationships/images/open-terminal.png" alt="terminal-image" /></p>
<pre><code class="language-bash">dotnet ef migrations add Create_Department_Entity
</code></pre>
<p>Finally, run the <code>IdentityRelationship.DbMigrator</code> project to update the database.</p>
<p>When you look at your database, you can see that the <code>Department</code> table has been added and <code>DepartmentId</code> has been added to your <code>AbpUsers</code> table.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-03-20-%20IdentityUser-Relationships/images/database-tables.png" alt="database-tables" /></p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-03-20-%20IdentityUser-Relationships/images/users-table.png" alt="users-table" /></p>
<blockquote>
<p>It's good to have some initial data in the database before running the application. This section introduces the <a href="https://docs.abp.io/en/abp/latest/Data-Seeding">Data Seeding</a> system of the ABP framework. You can skip this section if you don't want to create the data seeding, but it is suggested to follow along and learn this useful ABP Framework feature.</p>
</blockquote>
<p>Create a class deriving from the <code>IDataSeedContributor</code> in the <code>IdentityRelationship.Domain</code> project by copying the following code:</p>
<pre><code class="language-csharp">using System;
using System.Threading.Tasks;
using IdentityRelationship.Departments;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;

namespace IdentityRelationship;

public class IdentityRelationshipDataSeederContributor
    : IDataSeedContributor, ITransientDependency
{
    private readonly IRepository&lt;Department, Guid&gt; _departmentRepository;

    public IdentityRelationshipDataSeederContributor(IRepository&lt;Department, Guid&gt; departmentRepository)
    {
        _departmentRepository = departmentRepository;
    }

    public async Task SeedAsync(DataSeedContext context)
    {
        if (await _departmentRepository.GetCountAsync() &lt;= 0)
        {
            await _departmentRepository.InsertAsync(
                new Department
                {
                    Name = &quot;Human Resources&quot;
                },
                autoSave: true
            );

            await _departmentRepository.InsertAsync(
                new Department
                {
                    Name = &quot;Production&quot;
                },
                autoSave: true
            );
        }
    }
}
</code></pre>
<ul>
<li>This code simply uses the <code>IRepository&lt;Department, Guid&gt;</code> (the default <a href="https://docs.abp.io/en/abp/latest/Repositories">repository</a>) to insert two books to the database in case there weren't any books in it.</li>
</ul>
<p>Run the <code>IdentityRelationship.DbMigrator</code> application to update the database:</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-03-20-%20IdentityUser-Relationships/images/run-dbmigrator.png" alt="run-dbmigrator" /></p>
<p>Again, open the <code>IdentityRelationshipModuleExtensionConfigurator</code> class in the Domain.Shared project and add the following code:</p>
<pre><code class="language-csharp">
user.AddOrUpdateProperty&lt;Guid&gt;(
    &quot;DepartmentId&quot;,
    property =&gt;
    {
        property.UI.Lookup.Url = &quot;/api/app/department&quot;;
        property.UI.Lookup.DisplayPropertyName = &quot;name&quot;;
    }
);
</code></pre>
<p>The <code>UI.Lookup.Url</code> option takes a URL to get the list of departments to select on the edit/create forms. This endpoint can be a typical controller, an auto API controller or any type of endpoint that returns a proper JSON response.</p>
<p>To localize, open the <code>IdentityRelationship.Domain.Shared</code> project and add it to your <code>/Localization/IdentityRelationship/en.json</code> file:</p>
<pre><code class="language-json">&quot;DepartmentId&quot;: &quot;Department&quot;
</code></pre>
<p>Create a <code>Departments</code> folder in the <code>IdentityRelationship.Application.Contracts</code> project of your solution and add the <code>DepartmentDto</code> class in it</p>
<pre><code class="language-csharp">using System;
using Volo.Abp.Application.Dtos;
namespace IdentityRelationship.Departments;

public class DepartmentDto : EntityDto&lt;Guid&gt;

{
    public string Name { get; set; }
}
</code></pre>
<p>Now let's create an <code>IDepartmentAppService</code> interface in the <code>Departments</code> folder</p>
<pre><code class="language-csharp">using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;

namespace IdentityRelationship.Departments;

public interface IDepartmentAppService : IApplicationService
{
    public Task&lt;ListResultDto&lt;DepartmentDto&gt;&gt; GetAsync();
}
</code></pre>
<p>Time to implement the <code>IDepartmentAppService</code> interface. Create a <code>Departments</code> folder in your <code>IdentityRelationship.Application</code> project and add the <code>DepartmentAppService</code> class inside.</p>
<pre><code class="language-csharp">using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using IdentityRelationship.Departments;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;

namespace IdentityRelationship.Department;

public class DepartmentAppService : IdentityRelationshipAppService, IDepartmentAppService
{
    private readonly IRepository&lt;Departments.Department, Guid&gt; _departmentRepository;

    public DepartmentAppService(IRepository&lt;Departments.Department, Guid&gt; departmentRepository)
    {
        _departmentRepository = departmentRepository;
    }

    public async Task&lt;ListResultDto&lt;DepartmentDto&gt;&gt; GetAsync()
    {
        var departments = await _departmentRepository.GetListAsync();
        return new ListResultDto&lt;DepartmentDto&gt;(
            ObjectMapper.Map&lt;List&lt;Departments.Department&gt;, List&lt;DepartmentDto&gt;&gt;(departments));
    }
}
</code></pre>
<p><code>DepartmentAppService </code>is using the <code>ObjectMapper</code> to convert the <code>Department</code> objects to <code>DepartmentDto</code> objects. So, we need to define this mapping in the AutoMapper configuration.</p>
<p>Open the <code>IdentityRelationshipApplicationAutoMapperProfile</code> class inside the <code>IdentityRelationship.Application</code> project and add the following line to the constructor:</p>
<pre><code class="language-csharp">using AutoMapper;
using IdentityRelationship.Departments;

namespace IdentityRelationship;

public class IdentityRelationshipApplicationAutoMapperProfile : Profile
{
    public IdentityRelationshipApplicationAutoMapperProfile()
    {
        CreateMap&lt;Departments.Department, DepartmentDto&gt;();
    }
}
</code></pre>
<p>Run your <code>IdentityRelationship.Web</code> project and add a department to one of your users.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-03-20-%20IdentityUser-Relationships/images/user-department.png" alt="user-department-image" /></p>
<p>And it shows the department name on the data table:</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-03-20-%20IdentityUser-Relationships/images/users-page-department.png" alt="users-page-department-image" /></p>
<h2>Conclusion</h2>
<p>In this article I talked about the use of the IdentityUser relationship and how to extend it. Thank you for reading the article, I hope it was useful. See you soon!</p>
<h2>References</h2>
<ul>
<li>https://docs.abp.io/en/abp/latest/Module-Entity-Extensions</li>
<li>https://learn.microsoft.com/en-us/ef/core/modeling/relationships</li>
<li>https://community.abp.io/posts/how-to-add-custom-properties-to-the-user-entity-rixchoha</li>
</ul>
]]></content:encoded>
      <media:thumbnail url="https://abp.io/api/posts/cover-picture-source/3a0a1590-0cd7-288f-338b-29b87396275a" />
      <media:content url="https://abp.io/api/posts/cover-picture-source/3a0a1590-0cd7-288f-338b-29b87396275a" medium="image" />
    </item>
    <item>
      <guid isPermaLink="true">https://abp.io/community/posts/how-to-contribute-to-abp-framework-46dvzzvj</guid>
      <link>https://abp.io/community/posts/how-to-contribute-to-abp-framework-46dvzzvj</link>
      <a10:author>
        <a10:name>onurpicakci</a10:name>
        <a10:uri>https://abp.io/community/members/onurpicakci</a10:uri>
      </a10:author>
      <category>contribution-guide</category>
      <title>How to Contribute to ABP Framework</title>
      <description>In this article I will explain how you can contribute to the open source ABP Framework.</description>
      <pubDate>Thu, 02 Feb 2023 12:53:13 Z</pubDate>
      <a10:updated>2026-11-11T18:14:54Z</a10:updated>
      <content:encoded><![CDATA[<h1>How to Contribute to ABP Framework</h1>
<h2>Introduction</h2>
<p>In this article I will explain how you can contribute to the open source ABP Framework. You will not only learn about the ABP Framework, but also how to contribute to an open source project, what are the standard rules, some git operations, etc.</p>
<h2>What is Open Source?</h2>
<p>Open source software is code designed to be publicly available. Anyone can view, use, modify and distribute the project and code. The fact that the code is open source makes it a natural community and open for improvement. This enables ideas and thoughts to spread rapidly.</p>
<h2>What is ABP Framework?</h2>
<p>ABP Framework is a complete infrastructure for building modern web applications following the best practices and guidelines of software development. ABP Framework is completely free, <a href="https://github.com/abpframework">open source</a> and community driven. ABP is a modular framework and Application Modules provide pre-built application functionalities.</p>
<h2>Before Contribution</h2>
<p>Before making any changes and trying to push them to the target repository we need to create a new <a href="https://github.com/abpframework/abp/issues">issue</a> if there are no issues with the work. If there is an existing issue, you can proceed through this issue. This way, no other developer will work on the same issue and your PR will have a better chance to be accepted.</p>
<p>Previous ABP Community Talk on this topic can be found <a href="https://www.youtube.com/watch?v=Wz4Z-O-YoPg">here</a>.</p>
<h2>GitHub Issues</h2>
<p>You may want to fix a known bug or work on a planned enhancement. See the <a href="https://github.com/abpframework/abp/issues">issue list</a> on GitHub.</p>
<h2>Feature Requests</h2>
<p>If you have a feature idea for the framework or modules, create an issue on GitHub or attend an existing discussion. Then you can implement it if it's embraced by the community.</p>
<h2>How to Contribute to an Open Source Software?</h2>
<p>There are some steps to contribute to OSS projects. You can follow the steps below.</p>
<h2>Step 1: Fork the Project</h2>
<p>The first thing we need to do now is to fork the open source project. Forking will create a copy of the project in your own GitHub account. This will allow users to make changes to the code without affecting the original repository. Just press the fork key in the project.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-01-30-How-To-Contribute-To-a-Open-Source-Software/images/fork-project-image.png" alt="fork-image" /></p>
<p>After forking, it will create a new repo in your own GitHub profile.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-01-30-How-To-Contribute-To-a-Open-Source-Software/images/fork-project-profile.png" alt="fork-image-profile" /></p>
<h2>Step 2: Clone the Project</h2>
<p>In order to develop the project, you need to clone it to your local. After clicking on the code button, select your preferred cloning method and copy the link. You can run the copied link on your local machine with the <code>git clone</code> command, but we will use GitHub Desktop. Press <code>Open with GitHub Desktop</code> and the repo will be installed on your local machine.</p>
<p>or alternatively use the <code>git clone https://github.com/username/abp.git</code> command</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-01-30-How-To-Contribute-To-a-Open-Source-Software/images/clone-image.png" alt="clone-image" /></p>
<h2>Step 3: Create a New Branch</h2>
<p>In this step, you need to create a new branch of your own before you start developing it. Open the repo on GitHub Desktop and create a new branch. When creating a new branch, be careful which branch you create it on.</p>
<p>or alternatively use the <code>git checkout -b new-branch</code> command</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-01-30-How-To-Contribute-To-a-Open-Source-Software/images/branch-image.png" alt="branch-image" /></p>
<h2>Step 4: Development</h2>
<p>Choose a suitable IDE to develop on the new branch you created. In order not to complicate things, we will create a <code>Developers.md</code> file and process it. Let's enter a sample text in the Developers file.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-01-30-How-To-Contribute-To-a-Open-Source-Software/images/developer-list.png" alt="developer-list" /></p>
<p>As you can see, all changes made to the repo are reflected directly on GitHub Desktop.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-01-30-How-To-Contribute-To-a-Open-Source-Software/images/github-desktop-change.png" alt="github-desktop-change" /></p>
<h2>Step 5: Commit</h2>
<p>The commit operation is used to save the changes you have made. It is useful to commit after certain operations are done in the project. It is useful to write a short sentence describing what you've done for the changes made in each commit. Press the <code>Commit to &lt;branch-name&gt;</code> button to commit.</p>
<p>or alternatively use the <code>git add .</code> and <code>git commit -m &quot;Added the Developer List&quot;</code> command</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-01-30-How-To-Contribute-To-a-Open-Source-Software/images/commit-image.png" alt="commit-image" /></p>
<h2>Step 6: Publish the Changes</h2>
<p>The changes you have made so far are only visible on your local machine. You need to publish these changes to submit them to your forked repository. Please press the publish branch button to publish.</p>
<p>or alternatively use the <code>git push origin new-branch</code> command</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-01-30-How-To-Contribute-To-a-Open-Source-Software/images/git-push-image.png" alt="push-image" /></p>
<h2>Step 7: Create a Pull Request</h2>
<p>After the push, the pull request <code>Create Pull Request</code> button will appear on GitHub Desktop. Click it and create a pull request.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-01-30-How-To-Contribute-To-a-Open-Source-Software/images/github-desktop-pull-request.png" alt="github-desktop-pull-request" /></p>
<p>You can also make a pull request from the repo in your GitHub profile.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-01-30-How-To-Contribute-To-a-Open-Source-Software/images/pull-request-image.png" alt="compare-pull-request" /></p>
<p>Before creating the pull request, make sure that the branch you created is making changes to the correct branch. After briefly describing your changes in the title and description, click the <code>Create pull request</code> button. This will send a pull request to the original repository. If the pull request is approved and merged by the community, your changes will also appear in the main repository.</p>
<p><img src="https://raw.githubusercontent.com/abpframework/abp/dev/docs/en/Community-Articles/2023-01-30-How-To-Contribute-To-a-Open-Source-Software/images/open-pull-request-image.png" alt="open-pull-request" /></p>
<p>That's it! You have contributed your development to an open source project.</p>
<h2>Conclusion</h2>
<p>In this article, I showed you how you could contribute to the ABP Framework, an open source and community driven project. Thank you for reading the article, I hope it was useful. See you soon!</p>
<h2>References</h2>
<ul>
<li>https://opensource.guide/how-to-contribute/</li>
<li>https://docs.abp.io/en/abp/latest/Contribution/Index</li>
</ul>
]]></content:encoded>
      <media:thumbnail url="https://abp.io/api/posts/cover-picture-source/086508c5-ca76-2801-fb7b-3a09245d09ba" />
      <media:content url="https://abp.io/api/posts/cover-picture-source/086508c5-ca76-2801-fb7b-3a09245d09ba" medium="image" />
    </item>
  </channel>
</rss>