<?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>Sun, 11 Oct 2026 01:44:34 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=suhaib-mousa" />
    <item>
      <guid isPermaLink="true">https://abp.io/community/posts/.net-11-preview-1-highlights-faster-runtime-smarter-jit-and-aiready-improvements-hspp3o5x</guid>
      <link>https://abp.io/community/posts/.net-11-preview-1-highlights-faster-runtime-smarter-jit-and-aiready-improvements-hspp3o5x</link>
      <a10:author>
        <a10:name>suhaib-mousa</a10:name>
        <a10:uri>https://abp.io/community/members/suhaib-mousa</a10:uri>
      </a10:author>
      <category>EfCore</category>
      <category>maui</category>
      <category>cli</category>
      <category>dotnet</category>
      <category>new-features</category>
      <title>.NET 11 Preview 1 Highlights: Faster Runtime, Smarter JIT, and AI-Ready Improvements</title>
      <description>A quick tour of the most important updates in .NET 11 Preview 1—BFloat16 for AI scenarios, Zstandard compression, runtime and JIT improvements, interactive CLI enhancements, MediaTypeMap, and upgrades for EF Core and MAUI.</description>
      <pubDate>Mon, 16 Feb 2026 08:43:07 Z</pubDate>
      <a10:updated>2026-10-10T21:51:19Z</a10:updated>
      <content:encoded><![CDATA[<p>Noticing how quickly things are changing lately?</p>
<p>We were just getting used to .NET 10. Now, Microsoft has already released <strong>.NET 11 Preview 1</strong>. This release is significant, and the emphasis is clearly on improving performance. <a href="https://devblogs.microsoft.com/dotnet/dotnet-11-preview-1" title=".NET 11 Preview 1 is now available!"><code>Microsoft for Developers</code></a></p>
<p>Here are the key points that caught my attention from the release notes:</p>
<ol>
<li><p>Native AI-friendly numeric support (BFloat16):<br />
.NET 11 Preview 1 introduces support for <strong>BFloat16</strong>. <a href="https://github.com/dotnet/core/blob/main/release-notes/11.0/preview/preview1/libraries.md" title="core/release-notes/11.0/preview/preview1/libraries.md at ..."><code>GitHub</code></a><br />
Why does this matter? BFloat16 is popular in AI training and inference because it lowers memory usage and increases speed while maintaining acceptable precision.</p>
</li>
<li><p>Compression leveled up (Zstandard):<br />
There is now native support for <strong>Zstandard</strong> in <code>System.IO.Compression</code>, including types like <code>ZstandardStream</code> and related options. <a href="https://www.heise.de/en/news/Microsoft-starts-with-previews-for-NET-11-0-11173628.html" title="Microsoft starts with previews for .NET 11.0"><code>heise online</code></a><br />
Why does this matter? Zstandard strikes a great balance between compression ratio and speed, which effectively reduces network traffic and cloud storage costs.</p>
</li>
<li><p>Runtime async improvements (real work under the hood):<br />
This preview includes significant updates for async execution and diagnostics at runtime.<br />
<a href="https://devblogs.microsoft.com/dotnet/dotnet-11-preview-1" title=".NET 11 Preview 1 is now available!"><code>Microsoft for Developers</code></a><br />
Why does this matter? Async paths can operate more efficiently with less overhead, and debugging is getting easier, especially for deep async call chains and handling exceptions.</p>
</li>
<li><p>Smarter JIT for loops (Induction Variable analysis):<br />
The JIT now performs deeper analysis of loops, allowing for more automatic optimizations.<br />
<a href="https://devblogs.microsoft.com/dotnet/dotnet-11-preview-1" title=".NET 11 Preview 1 is now available!"><code>Microsoft for Developers</code></a><br />
Why does this matter? This can speed up code that involves heavy loops and computations without needing you to make changes—especially useful in numeric and processing tasks.</p>
</li>
<li><p>The CLI became interactive (better daily dev experience):<br />
<code>dotnet run</code> now supports selecting target frameworks and devices interactively for multi-target projects, with MAUI being a prime example. <a href="https://github.com/dotnet/core/blob/main/release-notes/11.0/preview/preview1/sdk.md" title="core/release-notes/11.0/preview/preview1/sdk.md at main · ..."><code>GitHub</code></a><br />
Why does this matter? It speeds up your workflow and cuts down on the flags you must remember and type each time.</p>
</li>
<li><p><code>System.Net.Mime.MediaTypeMap</code> (finally!):<br />
There is now an official API to map file extensions to MIME types and back, for example, <code>.png</code> to <code>image/png</code>. <a href="https://learn.microsoft.com/en-us/dotnet/api/system.net.mime.mediatypemap?view=net-11.0&amp;viewFallbackFrom=net-7.0" title="MediaTypeMap Class (System.Net.Mime)"><code>Microsoft Learn</code></a><br />
Why does this matter? For years, we either created our own solutions or relied on third-party libraries for something that should have been standard. Now it’s built-in.</p>
</li>
<li><p>EF Core improvements and faster migrations workflow:<br />
The EF Core tools and JSON mapping are continuing to improve, with enhancements to migration workflows and better JSON support for complex scenarios. <a href="https://devblogs.microsoft.com/dotnet/dotnet-11-preview-1" title=".NET 11 Preview 1 is now available!"><code>Microsoft for Developers</code></a></p>
</li>
<li><p>MAUI got faster (XAML source generation):<br />
XAML source generation is now the default in MAUI for .NET 11. <a href="https://devblogs.microsoft.com/dotnet/dotnet-11-preview-1" title=".NET 11 Preview 1 is now available!"><code>Microsoft for Developers</code></a><br />
Why does this matter? It leads to faster builds, smoother debugging, and better runtime performance as more tasks move from runtime to compile time.</p>
</li>
</ol>
<p>If you want to try it:<br />
.NET 11 Preview 1 is available now, and using preview tooling is recommended. <a href="https://devblogs.microsoft.com/dotnet/dotnet-11-preview-1" title=".NET 11 Preview 1 is now available!"><code>Microsoft for Developers</code></a></p>
<p>In summary, this update demonstrates that .NET is not &quot;just for the web&quot; anymore. It is increasingly evolving into a platform suited for high-performance workloads and AI-ready situations.</p>
]]></content:encoded>
      <media:thumbnail url="https://abp.io/api/posts/cover-picture-source/3a1f77ca-f5b5-5adb-420a-851d3b8c385a" />
      <media:content url="https://abp.io/api/posts/cover-picture-source/3a1f77ca-f5b5-5adb-420a-851d3b8c385a" medium="image" />
    </item>
    <item>
      <guid isPermaLink="true">https://abp.io/community/posts/toon-vs-json-for-llm-prompts-in-abp-tokenefficient-structured-context-b4rn2avd</guid>
      <link>https://abp.io/community/posts/toon-vs-json-for-llm-prompts-in-abp-tokenefficient-structured-context-b4rn2avd</link>
      <a10:author>
        <a10:name>suhaib-mousa</a10:name>
        <a10:uri>https://abp.io/community/members/suhaib-mousa</a10:uri>
      </a10:author>
      <category>abp-commercial</category>
      <category>abp</category>
      <title>TOON vs JSON for LLM Prompts in ABP: Token-Efficient Structured Context</title>
      <description>Why TOON can be more token-efficient than JSON for LLM prompts, how to compare them fairly, and how to apply TOON in ABP apps without changing your APIs.</description>
      <pubDate>Thu, 01 Jan 2026 14:07:39 Z</pubDate>
      <a10:updated>2026-10-10T19:31:06Z</a10:updated>
      <content:encoded><![CDATA[<p>When we build AI features, we often pass structured data (DTOs, lists, tables) to an LLM. The default is usually <strong>JSON</strong> because it’s easy to produce and debug.</p>
<p>But JSON wasn’t designed to be token-efficient for LLMs.</p>
<p><strong>TOON (Token-Oriented Object Notation)</strong> is a format designed for communicating structured data to LLMs with less token overhead than JSON—especially for <strong>arrays of similar objects</strong> (rows in a table).</p>
<p>This article focuses on:</p>
<ul>
<li>why JSON wastes tokens in prompts</li>
<li>what TOON changes</li>
<li>how to compare TOON vs JSON fairly</li>
<li>how to apply TOON in ABP without changing your public APIs</li>
</ul>
<hr />
<h2>Why JSON is inefficient for LLM prompts</h2>
<p>JSON is excellent for APIs, but expensive for prompts because it includes many tokens that add structure rather than meaning:</p>
<h3>1) Repeated property names</h3>
<p>If you send a list of 200 records, each record repeats keys like <code>&quot;id&quot;</code>, <code>&quot;name&quot;</code>, <code>&quot;creationTime&quot;</code>, <code>&quot;status&quot;</code>.</p>
<h3>2) Structural punctuation</h3>
<p>Characters like <code>{ } [ ] , : &quot; </code> are necessary for parsers, but they add tokens that don’t help the model understand your data.</p>
<h3>3) Nested objects amplify overhead</h3>
<p>The more nesting you have, the more braces and repeated keys you pay for.</p>
<p>This is why “just send the DTO as JSON to the LLM” can unexpectedly inflate prompt token count.</p>
<hr />
<h2>What TOON changes</h2>
<p>TOON represents the same JSON data model (objects, arrays, primitives) but optimizes the way structured data is written so that prompts often contain <strong>less repeated text</strong> and <strong>less structural clutter</strong>.</p>
<p>The most useful shape (and the one you’ll feel immediately in real products) is:</p>
<h3>Arrays of similar objects → tabular representation</h3>
<p>Instead of repeating keys in every row, TOON can define the “columns” once and then list rows.</p>
<hr />
<h2>Practical comparison: JSON vs TOON (same data)</h2>
<p>Let’s use a realistic “records list” shape (the kind you commonly pass to LLMs): timestamps + user + text.</p>
<h3>JSON (typical)</h3>
<pre><code class="language-json">[
  {
    &quot;creationTime&quot;: &quot;2026-01-01T10:15:00Z&quot;,
    &quot;userName&quot;: &quot;admin&quot;,
    &quot;text&quot;: &quot;On mobile the Post button disables randomly...&quot;
  },
  {
    &quot;creationTime&quot;: &quot;2026-01-01T10:20:00Z&quot;,
    &quot;userName&quot;: &quot;hamza&quot;,
    &quot;text&quot;: &quot;Please add pagination for large comment lists...&quot;
  }
]
</code></pre>
<h3>TOON (conceptual tabular array)</h3>
<blockquote>
<p>Exact syntax depends on the encoder you use; the important part is the structure:
define columns once, then provide rows.</p>
</blockquote>
<pre><code class="language-text"># records (tabular)
[creationTime userName text]
[
  [&quot;2026-01-01T10:15:00Z&quot; &quot;admin&quot; &quot;On mobile the Post button disables randomly...&quot;]
  [&quot;2026-01-01T10:20:00Z&quot; &quot;hamza&quot; &quot;Please add pagination for large comment lists...&quot;]
]
</code></pre>
<img width="1742" height="856" alt="Screenshot-2025-11-19-234750" src="https://github.com/user-attachments/assets/e513900a-6414-4ada-a86a-5da8768ec691" />
<h3>Why TOON is often more token-efficient here</h3>
<ul>
<li>JSON repeats <code>&quot;creationTime&quot;</code>, <code>&quot;userName&quot;</code>, <code>&quot;text&quot;</code> in every object</li>
<li>TOON pays those field names once, then streams rows</li>
<li>For larger lists (50–500 rows), repeated-key overhead becomes significant</li>
</ul>
<hr />
<h2>Where TOON helps most (and where it doesn’t)</h2>
<h3>TOON usually helps when</h3>
<ul>
<li>You send <strong>lists of records</strong> (audit logs, tickets, comments, search results, transactions)</li>
<li>You return structured results to the model (tool output / function output)</li>
<li>You frequently hit prompt size limits or cost issues</li>
</ul>
<h3>JSON is still fine when</h3>
<ul>
<li>Payloads are tiny (1–3 objects)</li>
<li>Structures are deeply nested and irregular</li>
<li>Human readability of raw prompt payloads is more important than tokens</li>
</ul>
<hr />
<h2>How to compare TOON vs JSON fairly</h2>
<p>To avoid misleading comparisons, keep these rules:</p>
<h3>1) Compare against minified JSON</h3>
<p>Pretty JSON is larger than the JSON you’d actually send. Always compare TOON against <strong>minified JSON</strong>.</p>
<h3>2) Same data, same ordering</h3>
<p>Ensure records are identical, same order, same quoting rules, same escaping.</p>
<h3>3) Use the same tokenizer as your target model</h3>
<p>Token counts differ by model/tokenizer. Use the tokenizer that matches your provider/model whenever possible.</p>
<h3>4) Measure at multiple sizes</h3>
<p>The win usually grows with the number of rows:</p>
<ul>
<li>10 rows</li>
<li>50 rows</li>
<li>100 rows</li>
<li>200 rows</li>
</ul>
<hr />
<h2>A simple “real numbers” section template (fill after measuring)</h2>
<p>Once you’ve measured your real payloads, include a short results section:</p>
<h3>Token comparison results</h3>
<ul>
<li>Dataset: <code>{N}</code> records</li>
<li>Fields: <code>{field list}</code></li>
<li>JSON (minified) tokens: <code>{JSON_TOKENS}</code></li>
<li>TOON tokens: <code>{TOON_TOKENS}</code></li>
<li>Reduction: <code>{PERCENT}%</code></li>
</ul>
<img width="2000" height="1000" alt="02-token-comparison" src="https://github.com/user-attachments/assets/a44fd1ea-43e4-41fe-ba2f-f30cd0356b4e" />
<hr />
<h2>How TOON fits into ABP apps</h2>
<p>ABP applications already have clean separation between:</p>
<ul>
<li>API contracts (DTOs)</li>
<li>application services</li>
<li>integrations</li>
</ul>
<p>That makes it easy to adopt TOON <em>without changing your API</em>:</p>
<h3>Recommended rule</h3>
<ul>
<li><p>Keep your ABP HTTP APIs as <strong>JSON</strong></p>
</li>
<li><p>Use TOON only in the <strong>AI boundary</strong>:</p>
<ul>
<li>prompt context formatting</li>
<li>tool output formatting before sending back to the model</li>
</ul>
</li>
</ul>
<h3>Clean layering idea</h3>
<p>Create a small abstraction like:</p>
<ul>
<li><code>IPromptContextFormatter</code> or <code>IToonFormatter</code></li>
</ul>
<p>So the rest of your application stays provider-agnostic and format-agnostic.</p>
<hr />
<h2>Migration strategy (safe adoption)</h2>
<p>If you’re introducing TOON into an existing AI feature:</p>
<ol>
<li><p>Add TOON formatting behind an interface</p>
</li>
<li><p>Keep a fallback to minified JSON while you validate correctness</p>
</li>
<li><p>Add a feature flag:</p>
<ul>
<li><code>UseToonForAiContext = true/false</code></li>
</ul>
</li>
<li><p>Measure token &amp; latency changes</p>
</li>
</ol>
<p>This lets you roll TOON in gradually and safely.</p>
<hr />
<h2>Conclusion</h2>
<p>JSON is a great API format, but for LLM prompts it often carries unnecessary token overhead—especially for large lists of similar objects.</p>
<p>TOON is a practical alternative for the AI boundary: it preserves structure while often reducing repeated-key and punctuation overhead. The best way to adopt it in ABP is not to replace JSON everywhere, but to <strong>format AI context</strong> as TOON while keeping your public APIs unchanged.</p>
]]></content:encoded>
      <media:thumbnail url="https://abp.io/api/posts/cover-picture-source/3a1e8c0f-8f6a-98b2-5a9c-9bd911356fe3" />
      <media:content url="https://abp.io/api/posts/cover-picture-source/3a1e8c0f-8f6a-98b2-5a9c-9bd911356fe3" medium="image" />
    </item>
    <item>
      <guid isPermaLink="true">https://abp.io/community/posts/visual-studio-2026-whats-new-and-why-im-excited-about-it-e4s5hed7</guid>
      <link>https://abp.io/community/posts/visual-studio-2026-whats-new-and-why-im-excited-about-it-e4s5hed7</link>
      <a10:author>
        <a10:name>suhaib-mousa</a10:name>
        <a10:uri>https://abp.io/community/members/suhaib-mousa</a10:uri>
      </a10:author>
      <title>Visual Studio 2026 — What’s New and Why I’m Excited About It</title>
      <description>Visual Studio 2026 brings AI, speed, and a fresh Fluent UI — built for the future of .NET.</description>
      <pubDate>Thu, 11 Sep 2025 11:49:15 Z</pubDate>
      <a10:updated>2026-10-10T23:27:42Z</a10:updated>
      <content:encoded><![CDATA[<p>Microsoft has released <strong>Visual Studio 2026 (Insiders)</strong>. I work daily with ASP.NET and ABP.io, so I wanted to look at what’s officially new, what I expect, and how it compares to Rider and VS Code.</p>
<p align="center">
  <img src="https://github.com/user-attachments/assets/8dd4253c-afc1-4e54-9cf9-749aea5356e6" alt="vs2026" width="600"/>
</p>
<hr />
<h2>What’s official from Microsoft</h2>
<ul>
<li><p><strong>AI built into the IDE</strong><br />
AI is now part of the workflow. It understands your solution, helps with paste-and-fix, suggests tests and documentation, and shows performance or security insights before you commit.<br />
<a href="https://devblogs.microsoft.com/visualstudio/visual-studio-2026-insiders-is-here/">Read the announcement</a></p>
</li>
<li><p><strong>Insiders Channel</strong><br />
The new Insiders Channel replaces Preview, giving early access to features with frequent updates.</p>
</li>
<li><p><strong>Performance improvements</strong><br />
Faster solution load, quicker builds and debugging, and better first launch. Optimized for both x64 and Arm64.</p>
</li>
<li><p><strong>UI refresh</strong><br />
Fluent UI design, updated icons, cleaner spacing, and a modernized settings experience.</p>
</li>
<li><p><strong>Latest .NET and C# support</strong><br />
Built-in support for <strong>.NET 10</strong> and <strong>C# 14</strong>.</p>
</li>
<li><p><strong>Side-by-side install</strong><br />
Install VS 2026 alongside VS 2022 and migrate your extensions and settings.<br />
<a href="https://visualstudio.microsoft.com/insiders/">Download Visual Studio 2026 Insiders</a></p>
</li>
<li><p><strong>Editor and productivity updates</strong><br />
A more informative bottom margin (line/column numbers, character count, encoding), Copilot context actions, a BenchmarkDotNet template, and Hot Reload improvements for Razor.<br />
<a href="https://learn.microsoft.com/en-us/visualstudio/releases/vs18/release-notes-insiders">See the release notes</a>
<br></p>
</li>
</ul>
<p align="center">
  <img src="https://github.com/user-attachments/assets/a5c5bf3a-2b15-4ca7-b412-7efe8abf62ec" alt="vs2026" width="500"/>
</p>
<hr />
<h2>What I hope to see next</h2>
<p>These aren’t confirmed by Microsoft, but they’re on my wishlist as an ABP.io developer:</p>
<ul>
<li>AI that understands modular ABP solutions and can suggest best practices.</li>
<li>Easier setup for multi-tenant projects with less boilerplate.</li>
<li>Built-in helpers for Azure CI/CD pipelines.</li>
<li>Lower memory usage on very large solutions.</li>
</ul>
<hr />
<h2>Visual Studio 2026 vs Rider vs VS Code</h2>
<ul>
<li><strong>VS Code</strong> — great for smaller projects and quick edits, but still just an editor with extensions.</li>
<li><strong>JetBrains Rider</strong> — often praised for responsiveness and strong refactoring/navigation tools, especially on large codebases.</li>
<li><strong>Visual Studio 2026</strong> — strongest integration with Microsoft’s ecosystem, support for new .NET/C# releases immediately, and deeper AI and performance improvements.</li>
</ul>
<hr />
<h2>Why this matters for ABP.io projects</h2>
<ul>
<li>ABP.io is all about modular monoliths and multi-tenancy. Faster solution load and better Hot Reload directly help in these setups.</li>
<li>ABP.io provides identity, auditing, background jobs, and modules out of the box. If Visual Studio’s AI continues to improve, it could save a lot of time on scaffolding and boilerplate.</li>
</ul>
<hr />
<h2>Conclusion</h2>
<p>Visual Studio 2026 Insiders already brings:</p>
<ul>
<li>AI integrated into the IDE</li>
<li>Performance gains for large solutions</li>
<li>A modern UI refresh</li>
<li>Support for .NET 10 and C# 14</li>
<li>Productivity updates like Hot Reload and Benchmarking</li>
</ul>
<p>For me, the big question is how well it will handle large ABP.io solutions and whether the AI tools actually reduce development time. If it delivers, it could easily become my main IDE.</p>
<p><a href="https://visualstudio.microsoft.com/insiders/">Download Visual Studio 2026 Insiders</a></p>
]]></content:encoded>
      <media:thumbnail url="https://abp.io/api/posts/cover-picture-source/3a1c4ac8-98e8-3e8f-33bd-50a4cd71044d" />
      <media:content url="https://abp.io/api/posts/cover-picture-source/3a1c4ac8-98e8-3e8f-33bd-50a4cd71044d" medium="image" />
    </item>
    <item>
      <guid isPermaLink="true">https://abp.io/community/posts/debugging-nuget-packages-in-abp.io-a-complete-guide-h13y2033</guid>
      <link>https://abp.io/community/posts/debugging-nuget-packages-in-abp.io-a-complete-guide-h13y2033</link>
      <a10:author>
        <a10:name>suhaib-mousa</a10:name>
        <a10:uri>https://abp.io/community/members/suhaib-mousa</a10:uri>
      </a10:author>
      <title>Debugging NuGet Packages in ABP.IO: A Complete Guide</title>
      <description>Ever found yourself struggling to understand what's happening inside a NuGet package while working with ABP Framework?</description>
      <pubDate>Thu, 08 May 2025 09:32:30 Z</pubDate>
      <a10:updated>2026-10-10T09:45:02Z</a10:updated>
      <content:encoded><![CDATA[<p>Ever found yourself struggling to understand what's happening inside a NuGet package while working with ABP Framework? Perhaps you've encountered unexpected behavior in <code>Volo.Abp.Account</code> or <code>Volo.Abp.Identity</code> but couldn't see what was actually going on under the hood.</p>
<p>The good news is that Visual Studio provides powerful tools that allow you to step directly into NuGet packages, observe their internal workings, and gain invaluable insights for troubleshooting and learning.</p>
<h2>Why Debug NuGet Packages?</h2>
<p>Before diving into the how-to, let's quickly understand why this capability matters:</p>
<ul>
<li><strong>Troubleshooting</strong>: Identify the root cause of issues that originate within package code</li>
<li><strong>Learning</strong>: Understand how ABP Framework implements various features</li>
<li><strong>Better Integration</strong>: See how your code should interact with ABP modules</li>
<li><strong>Customization</strong>: Make informed decisions when overriding or extending ABP functionality</li>
</ul>
<h2>Prerequisites</h2>
<ul>
<li>Visual Studio 2019 or later</li>
<li>An ABP Framework project with NuGet packages you want to debug</li>
</ul>
<h2>Setting Up Visual Studio for NuGet Package Debugging</h2>
<p>Let's walk through the process step by step:</p>
<h3>1. Disable &quot;Just My Code&quot;</h3>
<p>This is the first critical step that tells Visual Studio to allow debugging of external code.</p>
<ol>
<li>Open Visual Studio</li>
<li>Navigate to <strong>Tools → Options</strong></li>
<li>In the Options dialog, select <strong>Debugging → General</strong></li>
<li><strong>Uncheck</strong> the option labeled &quot;<strong>Enable Just My Code</strong>&quot;</li>
</ol>
<p><img src="https://github.com/user-attachments/assets/60f880a3-2a4e-407c-8b46-cbaa5c125bd3" alt="Disable Just My Code" /></p>
<h3>2. Configure Symbol Loading</h3>
<p>Symbols (PDB files) provide the mapping between compiled code and source code, making debugging possible.</p>
<ol>
<li>In the Options dialog, go to <strong>Debugging → Symbols</strong></li>
<li>Check &quot;<strong>Microsoft Symbol Servers</strong>&quot; to download symbols from Microsoft's servers</li>
<li>Check &quot;<strong>NuGet.org Symbol Server</strong>&quot; if available (or add <code>https://symbols.nuget.org/download/symbols</code> manually)</li>
<li>Set a cache location for symbol files (the default is typically in your AppData folder)</li>
</ol>
<p><img src="https://github.com/user-attachments/assets/0c017cd4-d6db-4280-af56-092e5b84fa82" alt="Configure Symbol Servers" /></p>
<h3>3. Enable Source Link Support</h3>
<p>Source Link is a technology that helps the debugger locate and download source code from repositories.</p>
<ol>
<li>In the same Options dialog, ensure you're in <strong>Debugging → General</strong></li>
<li>Check &quot;<strong>Enable Source Link support</strong>&quot;</li>
<li>For additional control, you can also check &quot;<strong>Enable Source Server support</strong>&quot;</li>
</ol>
<p><img src="https://github.com/user-attachments/assets/b3835cfc-a6a6-465c-9633-8a2e5b5253d8" alt="Enable Source Link Support" /></p>
<h2>Understanding Source Link</h2>
<p>Source Link is a vital technology that bridges the gap between compiled code and source code repositories. Here's what you need to know:</p>
<ul>
<li><p><strong>What is Source Link?</strong> It's a technology that embeds source control metadata into NuGet packages and assemblies, allowing debuggers to download the exact source code used to build those binaries.</p>
</li>
<li><p><strong>How it Works:</strong> When you step into a method from a NuGet package, Source Link provides the debugger with information about where to find the corresponding source file in the original repository.</p>
</li>
<li><p><strong>ABP Framework Compatibility:</strong> Most ABP.IO packages already support Source Link, making it possible to debug directly into their source code.</p>
</li>
</ul>
<h2>Debugging in Action: A Real-World Example</h2>
<p>Let's say you're overriding the <code>IdentityUserAppService</code> in your application, and you want to understand how the base implementation works:</p>
<ol>
<li>First, place a breakpoint on your call to the base method:</li>
</ol>
<pre><code class="language-csharp">public override async Task&lt;IdentityUserDto&gt; CreateAsync(IdentityUserCreateDto input)
{
    // Place breakpoint here
    var result = await base.CreateAsync(input);
    // Your custom code
    return result;
}
</code></pre>
<ol start="2">
<li>Start debugging your application and navigate to the part that triggers this code</li>
<li>When execution hits your breakpoint, press <strong>F11</strong> (Step Into) to step into the base class implementation</li>
<li>Visual Studio will:
<ul>
<li>Download necessary symbols (if not already cached)</li>
<li>Use Source Link to fetch the original source code</li>
<li>Open the source file and position the cursor at the method you're stepping into</li>
</ul>
</li>
</ol>
<p><img src="https://github.com/user-attachments/assets/19ff707e-da08-44b8-b2e0-dfee812cb1d9" alt="image" /></p>
<ol start="5">
<li>You can now debug through the ABP Framework code just like your own code:
<ul>
<li>Inspect variables</li>
<li>See the execution flow</li>
<li>Set additional breakpoints</li>
<li>Use all standard debugging features</li>
</ul>
</li>
</ol>
<h2>Debugging ABP Commercial Modules</h2>
<p>Commercial ABP modules (e.g., Volo.Saas, Volo.Payment, Volo.FormManagement) are not open-source and are distributed as obfuscated and encrypted DLLs. Consequently, Source Link does not support these modules, and you cannot debug them directly unless you have access to their source code .</p>
<h2>What About ABP Commercial Packages?</h2>
<p>Commercial packages like <code>Volo.Saas</code>, <code>Volo.Payment</code>, and <code>Volo.FormManagement</code>:</p>
<ul>
<li>Are not Source Link enabled</li>
<li>Contain obfuscated and protected DLLs</li>
<li>Cannot be debugged unless you have direct source code access</li>
</ul>
<p>✅ If You Have an ABP Commercial License:
You can access the source code directly:</p>
<ol>
<li>Follow the official <a href="https://abp.io/docs/latest/suite/source-code#downloading-source-code-of-a-module">guide</a></li>
<li>Reference the source modules instead of NuGet packages</li>
<li>You can then debug them like any other part of your app</li>
</ol>
<blockquote>
<p>⚠️ Do not attempt to decompile or reverse-engineer ABP Commercial DLLs — it violates licensing agreements.</p>
</blockquote>
<h2>Troubleshooting Common Issues</h2>
<h3>Symbols Not Loading</h3>
<p>If you're unable to load symbols:</p>
<ol>
<li>Verify your symbol server settings are correct</li>
<li>Check your internet connection (symbols need to be downloaded)</li>
<li>Try clearing your symbol cache:
<ul>
<li>Go to <strong>Tools → Options → Debugging → Symbols</strong></li>
<li>Click &quot;<strong>Clear All Symbol Cache Directories</strong>&quot;</li>
</ul>
</li>
<li>Ensure the package actually includes symbols (not all do)</li>
</ol>
<h3>Source Code Not Found</h3>
<p>If symbols load but source code doesn't:</p>
<ol>
<li>Verify that &quot;<strong>Enable Source Link support</strong>&quot; is checked</li>
<li>Check if the repository containing the source code is public</li>
<li>For private repositories, you may need to configure authentication</li>
<li>Try enabling verbose Source Link diagnostics to see what's happening</li>
</ol>
<h3>Performance Considerations</h3>
<p>Debugging with symbols and Source Link can impact performance:</p>
<ol>
<li>Loading symbols and source files takes time, especially on first use</li>
<li>Consider using the &quot;<strong>Load only specified modules</strong>&quot; option to load symbols selectively</li>
<li>Once you're done debugging packages, re-enable &quot;Just My Code&quot; for normal debugging</li>
</ol>
<h2>Best Practices for ABP Development</h2>
<h3>When to Use NuGet Package Debugging</h3>
<ul>
<li>During troubleshooting of unexpected behavior</li>
<li>When learning how to properly extend ABP functionality</li>
<li>Before implementing complex customizations</li>
</ul>
<h3>When to Avoid It</h3>
<ul>
<li>For day-to-day development when you don't need to see inside packages</li>
<li>When performance is a concern</li>
<li>When you're already familiar with the internals</li>
</ul>
<h2>Conclusion</h2>
<p>Stepping into NuGet packages is an invaluable skill for ABP developers. Whether you're troubleshooting complex issues, understanding how to properly extend the framework, or simply learning how ABP works under the hood, this technique provides insights that would otherwise be difficult to obtain.</p>
<p>Remember to toggle these settings only when needed, as they can impact your debugging performance. Once you're done exploring package internals, consider re-enabling &quot;Just My Code&quot; for your regular development workflow.</p>
<p>By mastering this technique, you'll be better equipped to work with ABP Framework effectively, troubleshoot issues faster, and create better integrations with the ABP ecosystem.</p>
<h2>Additional Resources</h2>
<ul>
<li><a href="https://learn.microsoft.com/en-us/visualstudio/debugger/just-my-code">Official Visual Studio Debugging Documentation</a></li>
<li><a href="https://endjin.com/blog/2022/05/debugging-nuget-packages-understanding-debugging-symbols-and-using-source-link.html">Understanding Debugging Symbols and Source Link</a></li>
<li><a href="https://docs.abp.io/">ABP Framework Documentation</a></li>
<li><a href="https://abp.io/support/questions/978/How-can-I-debug-in-the-source-code-of-ABP-framework">Debugging ABP Framework Internals</a></li>
</ul>
]]></content:encoded>
      <media:thumbnail url="https://abp.io/api/posts/cover-picture-source/3a19c16a-1c49-386a-1389-2ba78bc9f6c8" />
      <media:content url="https://abp.io/api/posts/cover-picture-source/3a19c16a-1c49-386a-1389-2ba78bc9f6c8" medium="image" />
    </item>
    <item>
      <guid isPermaLink="true">https://abp.io/community/posts/using-abps-aws-blob-storing-provider-with-digitalocean-spaces-7hlyb25g</guid>
      <link>https://abp.io/community/posts/using-abps-aws-blob-storing-provider-with-digitalocean-spaces-7hlyb25g</link>
      <a10:author>
        <a10:name>suhaib-mousa</a10:name>
        <a10:uri>https://abp.io/community/members/suhaib-mousa</a10:uri>
      </a10:author>
      <title>Using ABP's AWS Blob Storing Provider with DigitalOcean Spaces</title>
      <description>Using DigitalOcean with ABP.io's AWS Blob Provider? Here's how to make it work seamlessly!</description>
      <pubDate>Thu, 20 Mar 2025 18:30:27 Z</pubDate>
      <a10:updated>2026-10-10T09:33:58Z</a10:updated>
      <content:encoded><![CDATA[<p><a href="https://www.digitalocean.com/products/spaces">DigitalOcean Spaces</a> is an S3-compatible object storage service, making it easy to integrate with ABP’s AWS Blob Storage Provider. However, because DigitalOcean requires a custom ServiceURL, we need a few changes to make it work seamlessly.</p>
<p>This guide walks you through setting up DigitalOcean Spaces as your blob storage provider in an ABP application.</p>
<h2>Step 1: Install the Required Blob Storage Packages</h2>
<p>Before setting up DigitalOcean Spaces, make sure you have the <strong>core Blob Storing package</strong> installed:</p>
<pre><code class="language-sh">abp add-package Volo.Abp.BlobStoring
</code></pre>
<p>Then, install the <strong>AWS Blob Storage Provider</strong> to enable S3-compatible storage:</p>
<pre><code class="language-sh">abp add-package Volo.Abp.BlobStoring.Aws
</code></pre>
<hr />
<h2>Step 2: Configure DigitalOcean Spaces</h2>
<p>Modify your module configuration file (<code>YourModule.cs</code>) and include the AWS provider settings:</p>
<pre><code class="language-csharp">// required DependsOn
[DependsOn(
    typeof(AbpBlobStoringModule),
    typeof(AbpBlobStoringAwsModule)
)]
public class YourModule : AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        Configure&lt;AbpBlobStoringOptions&gt;(options =&gt;
        {
            options.Containers.Configure&lt;DigitalOceanContainer&gt;(container =&gt;
            {
                container.UseAws(aws =&gt;
                {
                    aws.AccessKeyId = &quot;your-digitalocean-access-key&quot;;
                    aws.SecretAccessKey = &quot;your-digitalocean-secret-key&quot;;
                });
            });
        });
    }
}
</code></pre>
<hr />
<h2>Step 3: Implement a Custom S3 Client Factory</h2>
<h4>❓ Why Do We Need a Custom <code>AmazonS3Client</code>?</h4>
<p>Unlike AWS S3, <strong>DigitalOcean Spaces requires setting a specific <code>ServiceURL</code></strong> (e.g., <code>https://nyc3.digitaloceanspaces.com</code>). The <strong>default <code>AmazonS3Client</code> in ABP does not allow this</strong>, so we need to override the S3 client factory.</p>
<p>Here’s what a standard <a href="https://docs.digitalocean.com/products/spaces/how-to/use-aws-sdks/#configure-a-client">C# DigitalOcean S3 client</a> looks like:</p>
<pre><code class="language-csharp">var config = new AmazonS3Config
{
    ServiceURL = &quot;https://nyc3.digitaloceanspaces.com&quot;,
    ForcePathStyle = true
};

var client = new AmazonS3Client(&quot;YOUR-ACCESS-KEY&quot;, &quot;YOUR-SECRET-KEY&quot;, config);
</code></pre>
<p>Since ABP doesn’t support setting the <code>ServiceURL</code> directly, we must <strong>replace the default S3 client factory</strong>, here’s how you override the <strong>default Amazon S3 client</strong> in ABP:</p>
<pre><code class="language-csharp">using Amazon.S3;
using Volo.Abp.BlobStoring.Aws;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Security.Encryption;

[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IAmazonS3ClientFactory))]
public class CustomAmazonS3ClientFactory : DefaultAmazonS3ClientFactory
{
    public CustomAmazonS3ClientFactory(
        IDistributedCache&lt;AwsTemporaryCredentialsCacheItem&gt; cache,
        IStringEncryptionService stringEncryptionService)
        : base(cache, stringEncryptionService)
    {
    }

    public override Task&lt;AmazonS3Client&gt; GetAmazonS3Client(AwsBlobProviderConfiguration configuration)
    {
        var config = new AmazonS3Config
        {
            ServiceURL = &quot;https://nyc3.digitaloceanspaces.com&quot;, // Replace with your region's endpoint
            ForcePathStyle = true
        };

        return Task.FromResult(new AmazonS3Client(configuration.AccessKeyId, configuration.SecretAccessKey, config));
    }
}
</code></pre>
<p>This ensures all <strong>S3 requests are correctly routed</strong> to DigitalOcean Spaces.</p>
<hr />
<h2>Step 4: Define a Blob Storage Container</h2>
<p>To store files in DigitalOcean Spaces, create a <strong>blob container</strong>:</p>
<pre><code class="language-csharp">using Volo.Abp.BlobStoring;

[BlobContainerName(&quot;abp-digital-ocean&quot;)]
public class DigitalOceanContainer {}
</code></pre>
<h2>Step 5: Upload Files to DigitalOcean Spaces</h2>
<p>Inject the <strong>blob container</strong> into your service and start uploading files:</p>
<pre><code class="language-csharp">using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Volo.Abp.BlobStoring;
using Volo.Abp.DependencyInjection;

public class HelloWorldService : ITransientDependency
{
    public ILogger&lt;HelloWorldService&gt; Logger { get; set; }
    public IBlobContainer&lt;DigitalOceanContainer&gt; BlobContainer { get; }

    public HelloWorldService(IBlobContainer&lt;DigitalOceanContainer&gt; blobContainer)
    {
        Logger = NullLogger&lt;HelloWorldService&gt;.Instance;
        BlobContainer = blobContainer;
    }

    public async Task UploadFileAsync()
    {
        string filePath = &quot;hi/hello-world.txt&quot;;
        string content = &quot;Hello from DigitalOcean Spaces!&quot;;
        await BlobContainer.SaveAsync(filePath, content.GetBytes());

        Logger.LogInformation($&quot;File '{filePath}' uploaded successfully.&quot;);
    }
}
</code></pre>
<h2>Additional Blob Storing Operations</h2>
<p>Once your integration is set up, you can <strong>retrieve, delete, and manage files</strong> easily:</p>
<p><strong>Get a file:</strong></p>
<pre><code class="language-csharp">var fileBytes = await BlobContainer.GetAllBytesAsync(&quot;hi/hello-world.txt&quot;);
</code></pre>
<p><strong>Delete a file:</strong></p>
<pre><code class="language-csharp">await BlobContainer.DeleteAsync(&quot;hi/hello-world.txt&quot;);
</code></pre>
<p>For more details, check the <a href="https://abp.io/docs/latest/framework/infrastructure/blob-storing"><strong>official ABP documentation</strong></a></p>
<hr />
<h2>Conclusion</h2>
<p>Using <strong>DigitalOcean Spaces with ABP’s AWS Blob Storing Provider</strong> is straightforward because DigitalOcean is S3-compatible. If ABP’s built-in AWS integration does not support setting <code>ServiceURL</code>, replacing the <strong>Amazon S3 Client Factory</strong> ensures seamless integration.</p>
<p>By following this guide, you can <strong>fully integrate DigitalOcean Spaces</strong> with ABP’s Blob Storing system and use it just like AWS S3! 🚀</p>
]]></content:encoded>
      <media:thumbnail url="https://abp.io/api/posts/cover-picture-source/3a18c6ff-04a0-ab33-dac3-1651ebee4acb" />
      <media:content url="https://abp.io/api/posts/cover-picture-source/3a18c6ff-04a0-ab33-dac3-1651ebee4acb" medium="image" />
    </item>
    <item>
      <guid isPermaLink="true">https://abp.io/community/posts/dynamic-widget-communication-uvun7q23</guid>
      <link>https://abp.io/community/posts/dynamic-widget-communication-uvun7q23</link>
      <a10:author>
        <a10:name>suhaib-mousa</a10:name>
        <a10:uri>https://abp.io/community/members/suhaib-mousa</a10:uri>
      </a10:author>
      <title>Dynamic Widget Communication</title>
      <description>In modern web development, ensuring that widgets communicate smoothly and update dynamically based on user actions is crucial. I achieved this in the ABP.IO Widgets by leveraging an event-driven approach, allowing widgets to interact seamlessly without the need for complex dependencies.</description>
      <pubDate>Mon, 26 Aug 2024 07:15:00 Z</pubDate>
      <a10:updated>2026-10-10T18:18:18Z</a10:updated>
      <content:encoded><![CDATA[<h3>Dynamic Widget Communication</h3>
<p>In modern web development, ensuring that widgets communicate smoothly and update dynamically based on user actions is crucial. I achieved this in the ABP.IO Widgets by leveraging an event-driven approach, allowing widgets to interact seamlessly without the need for complex dependencies.</p>
<h4>The Core Idea</h4>
<p>Rather than having widgets tightly coupled—where one directly manipulates another—you can have them emit and listen for events. This approach keeps your code clean and your widgets reusable.</p>
<p>For example:</p>
<ol>
<li><strong>Categories Widget</strong>: Displays categories and triggers an event when a category is selected.</li>
<li><strong>Courses Widget</strong>: Listens for the category selection event and refreshes the course list accordingly.</li>
<li><strong>Courses Number Widget</strong>: Updates the course count based on the refreshed list.</li>
</ol>
<p><img src="https://github.com/user-attachments/assets/67c0fcad-92ee-4870-9f93-fa3431799119" alt="widgets-communication" /></p>
<h4>Quick Implementation</h4>
<p>Here's a brief overview of how it works:</p>
<ul>
<li><strong>Categories Widget</strong> triggers a <code>category-selected</code> event:</li>
</ul>
<pre><code class="language-javascript">(function ($) {
    abp.widgets.Categories = function ($widget) {
        var widgetManager = new abp.WidgetManager({
            wrapper: '.abp-widget-wrapper[data-widget-name=&quot;Categories&quot;]',
            filterCallback: function () {
                return {
                    // returned values here
                };
            }
        });

        async function init() {
            // ...
            // Emit that the category selected
            $(&quot;.category-tab&quot;).off('click').on('click', function () {
                var categoryName = $(this).attr('category-name');
                $(document).trigger('category-selected', { category: categoryName });
            });
        }

        return {
            init: init,
        };
    };
    
})(jQuery);
</code></pre>
<ul>
<li><strong>Courses Widget</strong> listens for this event and updates the courses:</li>
</ul>
<pre><code class="language-javascript">(function ($) {
    let category = 'All'; // initial category
    abp.widgets.Courses = function ($widget) {
        var widgetManager = new abp.WidgetManager({
            wrapper: '.abp-widget-wrapper[data-widget-name=&quot;Courses&quot;]',
            filterCallback: function () {
                return {
                    category: category
                };
            }
        });

        async function init() {
            //...
            $(document).trigger('courses-updated', { courses: filteredCourses });
        }

        function refreshCourses(_category) {
            category = _category;
            widgetManager.refresh();
        }
       
        return {
            init: init,
            refreshCourses: refreshCourses
        };
    }

})(jQuery);
</code></pre>
<ul>
<li><strong>Courses Number Widget</strong> listens for the <code>courses-updated</code> event to update the course count:</li>
</ul>
<pre><code class="language-javascript">(function ($) {
    let number = 0;
    abp.widgets.CoursesNumber = function ($widget) {
        var widgetManager = new abp.WidgetManager({
            wrapper: '.abp-widget-wrapper[data-widget-name=&quot;CoursesNumber&quot;]',
            filterCallback: function () {
                return {
                    number: number
                };
            }
        });
        async function init() {
            $('#number').text(number);
        }
        async function refreshCoursesNumber($number) {
            number = $number;
            widgetManager.refresh();
        }
        return {
            init: init,
            refreshCoursesNumber: refreshCoursesNumber
        };
    };
})(jQuery);
</code></pre>
<p>To link the widgets and ensure they refresh based on emitted events, you can hard-code this on the page containing the widgets or use the script field if you’re working within the ABP CMS Kit pages feature.</p>
<p><img src="https://github.com/user-attachments/assets/ff8cb98d-553a-44ef-b7f6-3edee54b29ff" alt="widgets-communication-script" /></p>
<p>This setup makes your widgets flexible and easy to manage. Place them anywhere on the page, and they’ll work together effortlessly.</p>
<p>By using event-driven communication, you simplify your development process and make your application more scalable and easier to maintain. Try it in your next project!</p>
<p>Happy coding 😁❤️</p>
]]></content:encoded>
      <media:thumbnail url="https://abp.io/api/posts/cover-picture-source/3a149fb6-97f0-e73c-e55f-0ce2cf4270e9" />
      <media:content url="https://abp.io/api/posts/cover-picture-source/3a149fb6-97f0-e73c-e55f-0ce2cf4270e9" medium="image" />
    </item>
    <item>
      <guid isPermaLink="true">https://abp.io/community/posts/exciting-new-feature-in-abp.io-cms-kit-marked-item-system.-2hvpq0me</guid>
      <link>https://abp.io/community/posts/exciting-new-feature-in-abp.io-cms-kit-marked-item-system.-2hvpq0me</link>
      <a10:author>
        <a10:name>suhaib-mousa</a10:name>
        <a10:uri>https://abp.io/community/members/suhaib-mousa</a10:uri>
      </a10:author>
      <category>cms-kit</category>
      <title>Exciting New Feature in ABP.IO CMS Kit: Marked Item System.</title>
      <description>Discover the new Marked Item feature! Users can now favorite, star, or bookmark resources with custom icons, simplifying tracking and enhancing user interaction.</description>
      <pubDate>Thu, 01 Aug 2024 10:44:47 Z</pubDate>
      <a10:updated>2026-10-10T08:57:41Z</a10:updated>
      <content:encoded><![CDATA[<p>Hello ABP.IO Community,</p>
<p>I am excited to announce that we have a new helpful CMS feature 😁!</p>
<p><img src="https://github.com/user-attachments/assets/809c8d2b-98b8-46cd-8547-2644b22cd71d" alt="cmskit-module-markedItemsFilter" /></p>
<h3>What's the Marked Item Feature?</h3>
<p>Imagine being able to easily flag your favorite blog posts or star important products. The Marked Item system does just that. It allows users to mark items with icons or emojis, making it super easy to keep track of what’s important to them. This nifty addition lets users mark any kind of resource, like blog posts or products, as favorites, starred, flagged, or bookmarked.</p>
<h3>Key Features</h3>
<ol>
<li><p><strong>Marked Toggling Component</strong>:</p>
<ul>
<li>Users can mark items using customizable icons or emojis. This makes the user experience more interactive and fun!</li>
<li>Here’s a quick example of how you can use it:
<pre><code class="language-razor">@await Component.InvokeAsync(typeof (MarkedItemToggleViewComponent), new
{
    entityId = &quot;...&quot;,
    entityType = &quot;product&quot;,
    needsConfirmation = true // (optional)
})
</code></pre>
</li>
</ul>
</li>
<li><p><strong>Simple Configuration</strong>:</p>
<ul>
<li>You can easily set up your own entity types and mark types (like favorite or starred).</li>
<li>Just add this configuration in your <code>YourModule.cs</code>:
<pre><code class="language-csharp">Configure&lt;CmsKitMarkedItemOptions&gt;(options =&gt;
{
    options.EntityTypes.Add(
        new MarkedItemEntityTypeDefinition(
            &quot;product&quot;,
            StandardMarkedItems.Favorite
        )
    );
});
</code></pre>
</li>
</ul>
</li>
</ol>
<h3>How to Enable the Marked Item Feature</h3>
<p>By default, the CMS Kit features are turned off. Here’s how to turn on the Marked Item feature in your application:</p>
<ol>
<li><strong>During Development</strong>: Use the Global Feature system.</li>
<li><strong>At Runtime</strong>: Use the ABP Framework's Feature System.</li>
</ol>
<blockquote>
<p>Check the <a href="https://github.com/suhaib-mousa/Abp.Posts/blob/main/Marked-item/Index.md#how-to-install">&quot;How to Install&quot; section of the CMS Kit Module documentation</a> to see how to enable/disable CMS Kit features on development time.</p>
</blockquote>
<h3>Filtering on Marked Items</h3>
<p>Users can filter their marked items to easily find their favorites. Here’s how to utilize the <code>GetEntityIdsFilteredByUserAsync</code> method to filter the user's marked items within your repository queries:</p>
<pre><code class="language-csharp">List&lt;string&gt; entityIdFilters = null;
if (userId.HasValue)
{
    entityIdFilters = await UserMarkedItemRepository.GetEntityIdsFilteredByUserAsync(userId.Value, entityType, cancellationToken: cancellationToken);
}

var queryable = (await GetDbSetAsync())
    .WhereIf(entityIdFilters != null, x =&gt; entityIdFilters.Contains(x.Id.ToString()));
// Additional query logic...
</code></pre>
<h3>Conclusion</h3>
<p>This new feature excites me much, and I hope it adds even more engagement and user experience to your apps. Try it out and see how it can enhance your applications.</p>
<p>Happy coding!</p>
]]></content:encoded>
      <media:thumbnail url="https://abp.io/api/posts/cover-picture-source/3a141fb7-acb1-9b18-5931-fb2b6f9aef59" />
      <media:content url="https://abp.io/api/posts/cover-picture-source/3a141fb7-acb1-9b18-5931-fb2b6f9aef59" medium="image" />
    </item>
  </channel>
</rss>