﻿<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="https://community.devexpress.com/feed-stylesheets/rss.xsl" media="screen"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dx="https://www.devexpress.com/" xmlns:a10="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title>Developer Express Inc.</title>
    <link>https://community.devexpress.com/Blogs</link>
    <description>Microsoft ASP.NET, WinForms Controls, Delphi &amp; C++ VCL Controls, Visual Studio IDE Productivity Tools &amp; Application Frameworks. WPF &amp; Reporting
Got questions? Email us: info@DevExpress.com</description>
    <language>en-US</language>
    <item>
      <guid isPermaLink="false">bd716303-653c-428d-8b8a-a7d998cde032:388296</guid>
      <link>https://community.devexpress.com/Blogs/news/archive/2026/07/12/migrating-winforms-amp-wpf-from-net-framework-to-net-10.aspx</link>
      <category domain="https://community.devexpress.com/Tags/.NET">.NET</category>
      <category domain="https://community.devexpress.com/Tags/.net+10">.net 10</category>
      <category domain="https://community.devexpress.com/Tags/ai">ai</category>
      <category domain="https://community.devexpress.com/Tags/AI+Skills">AI Skills</category>
      <category domain="https://community.devexpress.com/Tags/copilot">copilot</category>
      <category domain="https://community.devexpress.com/Tags/MCP">MCP</category>
      <category domain="https://community.devexpress.com/Tags/net+core">net core</category>
      <category domain="https://community.devexpress.com/Tags/NuGet">NuGet</category>
      <category domain="https://community.devexpress.com/Tags/WinForms">WinForms</category>
      <category domain="https://community.devexpress.com/Tags/WPF">WPF</category>
      <title>Migrating WinForms &amp; WPF from .NET Framework to .NET 10</title>
      <description> &lt;h2&gt;What This Guide Covers&lt;/h2&gt;
  &lt;p&gt;I&amp;#39;ve hand-migrated more legacy codebases than I care to count, back when &amp;quot;modernisation&amp;quot; meant a fortnight of find-and-replace, a wall of compiler errors, and a knot in your stomach every time you hit Build. So when I recently took a fifteen-year-old WinForms line-of-business app from .NET Framework 4.8 to .NET 10 in a matter of days, with an AI agent doing the grunt work and me keeping my hands on the decisions, I paid attention to what actually worked. This guide is that method, written up as steps you can follow.&lt;/p&gt;
  &lt;p&gt;It assumes a real codebase: a non-SDK project, &lt;code&gt;packages.config&lt;/code&gt;, a commercial control suite referenced the old way, and a decade of dependencies that were sensible in 2012 and a bit embarrassing now. If you&amp;#39;ve worked on real enterprise software, you&amp;#39;ve met this codebase. Odds are you maintain one. The app I&amp;#39;ll keep referring to is WinForms, so the specifics lean that way, but the process is the same for WPF and I&amp;#39;ll flag where the two part company.&lt;/p&gt;
  &lt;p&gt;The migration is rarely &lt;em&gt;hard&lt;/em&gt;. It&amp;#39;s vast and fiddly: thousands of small mechanical changes where one wrong move turns a working app into a non-compiling mystery you&amp;#39;ll spend a day unpicking. It&amp;#39;s tedious and easy to get wrong, which is exactly the kind of work worth automating, as long as you keep checking what it produces. Follow the steps below in order, commit after each one, and a job that&amp;#39;s sat in the &amp;quot;someday&amp;quot; pile for years turns into this week&amp;#39;s work.&lt;/p&gt;
  &lt;blockquote&gt;
    &lt;p&gt;&lt;strong&gt;Before you start:&lt;/strong&gt; you need Visual Studio 2026 (or Visual Studio 2022 17.14.17+), your source in Git so every step is reversible, access to your DevExpress and NuGet feeds, and a paid GitHub Copilot plan if you want to run the modernization agent. With DevExpress v26.2 setting .NET 10 as the minimum supported target, this is the version to aim at.&lt;/p&gt;
  &lt;/blockquote&gt;
  &lt;hr&gt;
  &lt;h2&gt;Step 0: Pick the Right Target (LTS vs STS)&lt;/h2&gt;
  &lt;p&gt;Decide the target framework before you touch anything, because it&amp;#39;s one line in a project file that decides whether you do this again next year. Microsoft alternates its releases. The even-numbered ones (8, 10, 12) are Long-Term Support with a three-year window; the odd numbers in between are Standard-Term Support and shorter-lived (&lt;a href="https://devblogs.microsoft.com/dotnet/dotnet-sts-releases-supported-for-24-months/" target="_blank"&gt;24 months now&lt;/a&gt;).&lt;/p&gt;
  &lt;p&gt;The first useful thing the AI did on my migration wasn&amp;#39;t code. My obvious target was .NET 8. It pointed out that 8&amp;#39;s support window was nearly up (&lt;a href="https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core" target="_blank"&gt;November 2026&lt;/a&gt;), while .NET 10 was the current LTS with years of runway ahead of it. That&amp;#39;s one line in a project file standing between &amp;quot;done&amp;quot; and &amp;quot;doing this again next year,&amp;quot; and most juniors wouldn&amp;#39;t have raised it. For an app that has to sit stable for years, you want the LTS. Right now that&amp;#39;s &lt;strong&gt;.NET 10&lt;/strong&gt;, which also happens to be the minimum DevExpress sets in v26.2 for .NET / .NET Core apps.&lt;/p&gt;&lt;div class="Note"&gt;&lt;span&gt;Since&amp;nbsp;.NET 10, .NET Framework 4.7.2 (likely), and Visual Studio 2022&amp;nbsp;will be minimally supported versions for DevExpress libraries in v26.2, we are also planning to update &lt;a href="https://docs.devexpress.com/GeneralInformation/2529/updates/project-converter#target-devexpress-based-projects-to-net-8-and-net-framework-462" target="_blank"&gt;the DevExpress Project Converter&lt;/a&gt; accordingly: it will re-target .NET versions in DevExpress-based projects  and update 3rd party NuGet packages to the latest compatible versions (optionally and very similar to what we did &lt;a href="https://community.devexpress.com/blogs/news/archive/2024/10/15/net-easy-automatic-upgrade-of-net-and-external-dependency-versions-converting-assembly-to-package-references-and-more-v24-2.aspx" target="_blank"&gt;for .NET 6 to 8 migration in 2024&lt;/a&gt;).&lt;/span&gt;&lt;/div&gt;
  &lt;hr&gt;
  &lt;h2&gt;Step 1: Run an Assessment&lt;/h2&gt;
  &lt;p&gt;Before changing code, get an honest picture of what stands between you and .NET 10. This is the job of &lt;a href="https://learn.microsoft.com/en-us/dotnet/core/porting/github-copilot-app-modernization/overview"&gt;GitHub Copilot app modernization for .NET&lt;/a&gt;, the Copilot agent that took over from &lt;a href="https://developercommunity.visualstudio.com/t/NET-Upgrade-Assistant-extension-is-no-l/10971375" target="_blank"&gt;the old Microsoft .NET Upgrade Assistant&lt;/a&gt;. In Visual Studio, right-click the solution in Solution Explorer and choose &lt;strong&gt;Modernize&lt;/strong&gt;, or open Copilot Chat and invoke the agent:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@Modernize upgrade this solution to .NET 10&lt;/code&gt;&lt;/pre&gt;
  &lt;p&gt;In VS Code or the Copilot CLI the agent is &lt;code&gt;@modernize-dotnet&lt;/code&gt;. However you start it, the first thing it produces is an &lt;code&gt;assessment.md&lt;/code&gt; in your repo: outdated NuGet packages, APIs with no modern equivalent, and the likely blockers. Read it before you agree to anything. That&amp;#39;s the difference between planning a migration and discovering one.&lt;/p&gt;
  &lt;p&gt;Two caveats. Running the agent needs a paid GitHub Copilot plan, and if the Modernize option isn&amp;#39;t there you&amp;#39;ll need the GitHub Copilot app modernization component from the Visual Studio installer, so factor both in. And treat the assessment as a briefing, not a verdict: it&amp;#39;s very good at finding the mechanical work, but the judgement calls are still yours.&lt;/p&gt;
  &lt;hr&gt;
  &lt;h2&gt;Step 2: Review and Edit the Plan&lt;/h2&gt;
  &lt;p&gt;Once the assessment&amp;#39;s done, the agent writes a &lt;code&gt;plan.md&lt;/code&gt; that sequences the upgrade into steps. The thing that matters about this file is that it&amp;#39;s yours to edit. Reorder it, pull out steps you&amp;#39;d rather do by hand, and split anything that looks too big into smaller moves.&lt;/p&gt;
  &lt;p&gt;This is where you impose the one rule that keeps migrations safe, and I&amp;#39;ve learned it the hard way: never do it as a big bang. Work in small, reversible, committed steps, so a bad change is a &lt;code&gt;git revert&lt;/code&gt; away rather than an afternoon of unpicking. A sensible plan for a DevExpress desktop app usually runs in this order:&lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;Convert the project to SDK-style, targeting &lt;code&gt;net10.0-windows&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;Move dependencies from &lt;code&gt;packages.config&lt;/code&gt; to &lt;code&gt;PackageReference&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;Prove the restore works against your feeds before attempting a build.&lt;/li&gt;
    &lt;li&gt;Fix what modern .NET rejects, then clear the build, then clear the warnings.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p&gt;Approve the plan only when it reads like something you&amp;#39;d have written yourself. Then let the agent start executing, one step at a time.&lt;/p&gt;
  &lt;hr&gt;
  &lt;h2&gt;Step 3: SDK-Style, PackageReference and CPM&lt;/h2&gt;
  &lt;p&gt;The first executed step converts the old project format and moves your references. A couple of things are worth watching, because they catch you out.&lt;/p&gt;&lt;p&gt;&lt;span&gt;If your .NET Framework project relied on assembly references, DevExpress assembly names do not match the DevExpress NuGet package names (for example, for the DevExpress.XtraGrid assembly there is a DevExpress.Win.Grid NuGet package). If you do not want to trust AI for this important conversion, we recommend that you use our Project Converter and its deterministic &lt;a href="https://docs.devexpress.com/WindowsForms/405091/net-net-core-support/migrate-net-framework-app-to-net#step-1-convert-devexpress-assemblies-to-nuget-packages" target="_blank"&gt;Convert DevExpress assembly references to NuGet packages&lt;/a&gt;&amp;nbsp;option before you trigger actual project conversion.&lt;/span&gt;&lt;/p&gt;
  &lt;p&gt;If the project sits at the repository root, default file-globbing in an SDK-style project can hoover up source from other projects nearby. This is one the AI caught that I&amp;#39;d have walked straight into: my project sat at the repo root, so the default globbing would&amp;#39;ve pulled in source from the projects around it. It turned globbing off and carried the explicit file lists across. Keep an eye out for it, because it&amp;#39;s easy to miss and a pain to debug.&lt;/p&gt;
  &lt;p&gt;If your solution has more than one project, this is the moment to adopt &lt;a href="https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management" target="_blank"&gt;Central Package Management (CPM)&lt;/a&gt;, so every project shares one set of versions. Drop a &lt;code&gt;Directory.Packages.props&lt;/code&gt; at the repository root:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-xml"&gt;&amp;lt;Project&amp;gt;
  &amp;lt;PropertyGroup&amp;gt;
    &amp;lt;ManagePackageVersionsCentrally&amp;gt;true&amp;lt;/ManagePackageVersionsCentrally&amp;gt;
  &amp;lt;/PropertyGroup&amp;gt;
  &amp;lt;ItemGroup&amp;gt;
    &amp;lt;PackageVersion Include=&amp;quot;DevExpress.Win&amp;quot; Version=&amp;quot;26.2.*&amp;quot; /&amp;gt;
  &amp;lt;/ItemGroup&amp;gt;
&amp;lt;/Project&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;p&gt;That example pins the WinForms meta-package; for a WPF app you&amp;#39;d use &lt;code&gt;DevExpress.Wpf&lt;/code&gt; instead. Individual projects then reference the package without a version, and your DevExpress and framework versions stop drifting apart across the solution. Prove &lt;code&gt;dotnet restore&lt;/code&gt; succeeds against your component feed before you try to compile. Get restore green first and you skip a whole category of confusing build errors.&lt;/p&gt;&lt;p&gt;&lt;span&gt;For more information on how your projects can benefit from CPM, please also review a related article&amp;nbsp;&lt;a href="https://community.devexpress.com/Blogs/news/archive/2026/04/24/application-security-project-dependency-version-bumps-demystified-modern-security-realities-in-net-nuget-ecosystem.aspx" target="_blank"&gt;Application Security — Project Dependency &amp;quot;Version Bumps&amp;quot; Demystified or Modern Security Realities in .NET / NuGet Ecosystem&lt;/a&gt;.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
  &lt;hr&gt;
  &lt;h2&gt;Step 4: Fix What Modern .NET Rejects&lt;/h2&gt;
  &lt;p&gt;Now the code itself. On my migration the first compile threw 36 errors and roughly 1,795 warnings. That sounds alarming, and mostly it isn&amp;#39;t: the errors collapsed to a handful of root causes, and the warnings came down to one. Clear them in that order, errors first and then warnings, committing as you go. These are the ones you&amp;#39;re most likely to meet on a DevExpress desktop app.&lt;/p&gt;
  &lt;h3&gt;Retire APIs with no modern equivalent&lt;/h3&gt;
  &lt;p&gt;Swap out the usual suspects: an old zip library for &lt;code&gt;System.IO.Compression&lt;/code&gt;, LINQ-to-SQL screens for a supported data path, dead &lt;code&gt;app.config&lt;/code&gt; sections for their modern equivalents. The assessment will have flagged most of them.&lt;/p&gt;
  &lt;h3&gt;Watch for namespace clashes&lt;/h3&gt;
  &lt;p&gt;A properly sneaky one on my app: a bare &lt;code&gt;Windows.Forms…&lt;/code&gt; reference stopped resolving on the new framework, thanks to a namespace collision that didn&amp;#39;t exist on Framework. Fully qualify it and the error vanishes. One line, but a baffling one until you spot it.&lt;/p&gt;
  &lt;h3&gt;The screens look wrong: fix DPI awareness&lt;/h3&gt;
  &lt;p&gt;The app compiled and launched, but the forms came up subtly wrong: controls a touch out of place, spacing not quite right. That&amp;#39;s the DPI-awareness default changing between frameworks, and it&amp;#39;s the sort of thing you can stare at for a while before the penny drops. The AI worked it out from a screenshot and a description, pointed me at the DevExpress high-DPI docs to back it up, and one setting put the screens back exactly as they were. That trap is a WinForms one; WPF scales differently and won&amp;#39;t hit it, though it has its own breaking changes to watch for, the removal of &lt;code&gt;BinaryFormatter&lt;/code&gt; being the one that bites most often (&lt;a href="https://supportcenter.devexpress.com/ticket/details/t1263793/deprecation-of-microsoft-s-binaryformatter-and-its-impact-on-drag-drop-operations" target="_blank"&gt;learn more&lt;/a&gt;).&lt;/p&gt;
  &lt;h3&gt;Collapse the warning storm&lt;/h3&gt;
  &lt;p&gt;The warning count after a big migration can look terrifying and usually is anything but. Two moves cleared most of mine: declaring the assembly&amp;#39;s supported-platform attribute to keep the compatibility analyser happy, and pinning a data-access package to the last version before it was marked obsolete. That second change alone dropped 500-plus warnings without touching a line of generated code.&lt;/p&gt;
  &lt;hr&gt;
  &lt;h2&gt;Step 5: Lean on Compatibility Shims&lt;/h2&gt;
  &lt;p&gt;You don&amp;#39;t have to migrate everything before you can run. I&amp;#39;d assumed I would need to move my two in-house .NET Framework libraries first. I didn&amp;#39;t. The modernised app compiled and ran on .NET 10 while still referencing those libraries through the .NET Framework compatibility shim. One thing to be clear about: that only holds while those libraries stick to APIs modern .NET still provides. You&amp;#39;ll get a build warning, and any code path that calls an API .NET 10 has dropped will fail at runtime rather than at compile time, so exercise the paths that go through them before you call it done. Even so, if you&amp;#39;ve got in-house libraries pinned to Framework, leave them where they are for now. Get the main application onto .NET 10 first, confirm it runs, and book the deeper library work as a separate job that blocks nothing.&lt;/p&gt;
  &lt;p&gt;This is the single biggest reason these migrations stall for no good reason. Teams assume every dependency has to move first, and give up. It doesn&amp;#39;t, and they don&amp;#39;t. You don&amp;#39;t have to boil the ocean. Get a working, current-LTS application in place, then chip away at the rest without holding the whole project hostage.&lt;/p&gt;
  &lt;hr&gt;
  &lt;h2&gt;Where AI Fits, and Where You Stay in Charge&lt;/h2&gt;
  &lt;p&gt;The reason this workflow holds up is that the agent proposes and you dispose. The &lt;code&gt;assessment.md&lt;/code&gt; and &lt;code&gt;plan.md&lt;/code&gt; aren&amp;#39;t decoration; they&amp;#39;re your checkpoints. You read the assessment, you edit the plan, you approve each step, and every change lands as a described commit you can review or revert. The AI carries the vast, repetitive sweep across dozens of files with no fatigue and no typos. The judgement and the checking stay with you. I never once typed &amp;quot;trust me,&amp;quot; and that&amp;#39;s the whole point.&lt;/p&gt;
  
    &lt;a&gt;
      &lt;img src="https://community.devexpress.com/blogs/news/2026/upgrade-workflow-diagram.png" width="820" alt="The upgrade workflow runs in three reviewable stages: assessment (assessment.md), then an editable plan (plan.md), then execution in small commits, ending with the app running on .NET 10. You review and approve at every stage."&gt;
    &lt;/a&gt;
    Assess, plan, execute. The agent does the work; you sign off each stage.
  
  &lt;hr&gt;
  &lt;h2&gt;Keep the Component Code Current: AI Skills and the MCP Server&lt;/h2&gt;
  &lt;p&gt;The modernization agent is built to move your framework, not to know your component vendor&amp;#39;s latest API surface. That gap does the most damage during a migration, because a migration is when you touch the most component code in the shortest time. Ask a general-purpose model to update a DevExpress grid or report and it&amp;#39;ll often reach for an older namespace it saw more of in training. The code looks right, compiles, and sits there on a superseded API. Two DevExpress tools close that gap, and they&amp;#39;re worth adding to the same IDE for the fix-up work.&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/DevExpress/agent-skills"&gt;DevExpress AI Skills&lt;/a&gt;&lt;/strong&gt; hand the assistant current DevExpress namespaces, entry points and configuration patterns before it writes a line. They install into the coding assistant you already use (GitHub Copilot, Claude Code, Cursor or JetBrains), they work even without a live documentation connection, and they keep the component code on supported APIs rather than remembered ones. On a migration that pays off directly: fewer convincing-but-stale suggestions to catch in review, and a first answer you can build on instead of unpick. Call the relevant skill explicitly at the start of a task rather than trusting auto-detection, with &lt;code&gt;#&lt;/code&gt; in Copilot or &lt;code&gt;/&lt;/code&gt; in Cursor and Claude Code.&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;&lt;a href="https://docs.devexpress.com/GeneralInformation/405551"&gt;The DevExpress MCP Server&lt;/a&gt;&lt;/strong&gt; adds the other half: live access to current documentation and version-sensitive detail when a task gets specific. Where a Skill sets the right starting point, the MCP Server supplies the authoritative reference to finish the job, so the assistant spends its lookups on real implementation questions instead of working out which API it should&amp;#39;ve used in the first place. Adding it is a one-line job in most assistants; in Claude Code, for example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;claude mcp add --transport http dxdocs https://api.devexpress.com/mcp/docs&lt;/code&gt;&lt;/pre&gt;
  &lt;p&gt;Put them together and the split is clean: the modernization agent carries the framework move, the Skills keep your DevExpress code correct, and the MCP Server fills in the detail on demand. It&amp;#39;s the same partnership principle as the rest of this guide, pointed at your component layer. I went deeper on why this matters, and how the two work together, with worked before-and-after examples in an earlier post: &lt;a href="https://community.devexpress.com/Blogs/news/archive/2026/07/09/beyond-prompts-teaching-ai-how-to-build-with-devexpress.aspx"&gt;Beyond Prompts: Teaching AI How to Build with DevExpress&lt;/a&gt;. If you haven&amp;#39;t read it, that&amp;#39;s the companion piece to this guide.&lt;/p&gt;
  &lt;hr&gt;
  &lt;h2&gt;Step 6: Verify You Are Actually Done&lt;/h2&gt;
  &lt;p&gt;&amp;quot;It compiles&amp;quot; isn&amp;#39;t the finish line. Before you call it migrated, confirm the app launches and the main workflows behave, the screens render correctly at your users&amp;#39; DPI settings, the warning count is down to something you actually understand, and each step is a clean commit in history. Only then start building new features on the modern foundation, which you can now do this week rather than someday.&lt;/p&gt;
  &lt;hr&gt;
  &lt;h2&gt;The Takeaway&lt;/h2&gt;
  &lt;p&gt;The blocker on most legacy migrations isn&amp;#39;t capability. It&amp;#39;s the sheer volume of small changes, and the fear of breaking an app that&amp;#39;s quietly worked for years. This workflow deals with both. The modernization agent carries the tedium and surfaces the landmines as an assessment you approve, DevExpress AI Skills keep the component code on current APIs, compatibility shims stop a single old dependency holding everything hostage, and small reversible commits keep the risk low at every step.&lt;/p&gt;
  &lt;p&gt;With DevExpress v26.2 aiming to make .NET 10 the minimum for .NET / .NET Core apps, now is the time to plan this migration, not a reason to panic. The app I did this on was fifteen years old and threw 36 errors and getting on for 1,800 warnings on its first .NET 10 compile. It was running clean within days, and I was building new features on it the same week. The migration is the part everyone dreads. Worked in small steps, with the tooling doing the legwork and you making the calls, it turns out to be the manageable bit.&lt;/p&gt;
  &lt;hr&gt;
  &lt;h2&gt;Further Reading&lt;/h2&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/dotnet/core/porting/github-copilot-app-modernization/overview"&gt;GitHub Copilot app modernization for .NET (overview)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/dotnet/core/porting/github-copilot-app-modernization/how-to-upgrade-with-github-copilot"&gt;How to upgrade a .NET app with Copilot modernization&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://dotnet.microsoft.com/platform/support/policy/dotnet-core"&gt;.NET Support Policy: LTS vs STS release cadence&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://learn.microsoft.com/nuget/consume-packages/central-package-management"&gt;Central Package Management (NuGet)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://learn.microsoft.com/dotnet/desktop/winforms/high-dpi-support-in-windows-forms"&gt;High DPI support in Windows Forms&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://github.com/DevExpress/agent-skills"&gt;DevExpress AI Skills for coding agents&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://community.devexpress.com/Blogs/news/archive/2026/07/09/beyond-prompts-teaching-ai-how-to-build-with-devexpress.aspx"&gt;Beyond Prompts: Teaching AI How to Build with DevExpress (companion post)&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;

  &lt;p class="dx-tags"&gt;
    &lt;a href="https://community.devexpress.com/Tags/WinForms"&gt;WinForms&lt;/a&gt;
    &lt;a href="https://community.devexpress.com/Tags/WPF"&gt;WPF&lt;/a&gt;
    &lt;a href="https://community.devexpress.com/Tags/NET"&gt;.NET&lt;/a&gt;
    &lt;a href="https://community.devexpress.com/Tags/Migration"&gt;Migration&lt;/a&gt;
    &lt;a href="https://community.devexpress.com/Tags/Legacy+Modernization"&gt;Legacy Modernization&lt;/a&gt;
    &lt;a href="https://community.devexpress.com/Tags/AI"&gt;AI&lt;/a&gt;
    &lt;a href="https://community.devexpress.com/Tags/AI-Assisted+Development"&gt;AI-Assisted Development&lt;/a&gt;
    &lt;a href="https://community.devexpress.com/Tags/NuGet"&gt;NuGet&lt;/a&gt;
  &lt;/p&gt;</description>
      <pubDate>Sun, 12 Jul 2026 22:05:00 Z</pubDate>
      <dc:creator>Paul Usher (DevExpress)</dc:creator>
    </item>
    <item>
      <guid isPermaLink="false">bd716303-653c-428d-8b8a-a7d998cde032:388295</guid>
      <link>https://community.devexpress.com/Blogs/news/archive/2026/07/09/beyond-prompts-teaching-ai-how-to-build-with-devexpress.aspx</link>
      <category domain="https://community.devexpress.com/Tags/ai">ai</category>
      <category domain="https://community.devexpress.com/Tags/AI+Skills">AI Skills</category>
      <category domain="https://community.devexpress.com/Tags/AI-Assistant">AI-Assistant</category>
      <category domain="https://community.devexpress.com/Tags/Featured">Featured</category>
      <category domain="https://community.devexpress.com/Tags/MCP">MCP</category>
      <category domain="https://community.devexpress.com/Tags/Office+File+API">Office File API</category>
      <category domain="https://community.devexpress.com/Tags/productivity">productivity</category>
      <category domain="https://community.devexpress.com/Tags/Reporting">Reporting</category>
      <category domain="https://community.devexpress.com/Tags/skills">skills</category>
      <title>Beyond Prompts: Teaching AI How to Build with DevExpress</title>
      <description>&lt;h2&gt;AI Needs More Than Good Prompts&lt;/h2&gt;

&lt;p&gt;If you&amp;#39;ve paired Claude Code, GitHub Copilot or Cursor with DevExpress, you already know the moment I&amp;#39;m about to describe. It&amp;#39;s the same one the team kept running into while building the &lt;a href="https://www.devexpress.com/products/net/office-file-api/" target="_blank" title="DevExpress Office &amp;amp; PDF File API"&gt;DevExpress Office &amp;amp; PDF File API&lt;/a&gt; and &lt;a href="https://www.devexpress.com/subscriptions/reporting/" target="_blank" title="DevExpress Reports"&gt;DevExpress Reports&lt;/a&gt;&amp;nbsp;Skills, and their evaluation notes are what this post is really about. The assistant starts strong. Clean C#, sensible class names, code that looks like it belongs in your solution. Then you read it a second time and something&amp;#39;s off: the namespace is from a release two versions back, the API has been superseded, or the whole thing has quietly wandered off to a third-party library because that&amp;#39;s what the model saw most often in training.&lt;/p&gt;

&lt;p&gt;The interesting part wasn&amp;#39;t that the AI got things wrong. Everyone expects that. What struck me about the team&amp;#39;s findings was how &lt;em&gt;convincing&lt;/em&gt; the wrong answers were. The ones that failed to compile cost them nothing; those get spotted immediately. The expensive ones looked completely reasonable right up until someone compared them with the current documentation. More often than not, they were yesterday&amp;#39;s best practice dressed up as today&amp;#39;s.&lt;/p&gt;

&lt;p&gt;That single observation ended up shaping how the team designed the Skills.&lt;/p&gt;

&lt;p&gt;As they worked through the results, the same theme kept coming back. When the generated code missed, the problem was almost never C#, and it certainly wasn&amp;#39;t the model&amp;#39;s ability to reason. It was product knowledge. The model didn&amp;#39;t have the current namespaces, the right entry points or the small amount of framework-specific context it needed before it started typing. Hand it those things and the quality of the output jumped straight away.&lt;/p&gt;

&lt;p&gt;We spend a lot of energy on prompt engineering, and good prompts genuinely help. But a prompt can only work with what the model already knows. No amount of clever wording fills a gap in product knowledge that isn&amp;#39;t there to begin with. Every time, giving the assistant accurate context &lt;em&gt;before&lt;/em&gt; it wrote anything beat trying to talk it back from a bad first answer.&lt;/p&gt;

&lt;p&gt;That&amp;#39;s the whole idea behind &lt;a href="https://github.com/DevExpress/agent-skills" target="_blank" title="DevExpress AI Skills — GitHub"&gt;DevExpress AI Skills&lt;/a&gt;. They don&amp;#39;t replace the model&amp;#39;s reasoning, and they don&amp;#39;t try to re-host the documentation. They hand the assistant a concise, product-specific starting point before it writes the first line of code, so it can spend its effort solving your actual problem instead of reconstructing an unfamiliar API from scraps of training data.&lt;/p&gt;

&lt;p&gt;The easiest way to show you what I mean is to walk through the same prompts the team used during the review, with and without the Skill.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;When Good Code Is Still Wrong&lt;/h2&gt;

&lt;p&gt;This showed up early in the team&amp;#39;s evaluation. Completely made-up APIs were never the issue, because you catch those instantly. The answers that slowed them down were the believable ones: code that read like it came from someone who knew the framework reasonably well, but carried just enough stale or incorrect detail to send you chasing the wrong problem for half an hour.&lt;/p&gt;

&lt;p&gt;That&amp;#39;s the trap with specialised frameworks. They move constantly. Namespaces get reorganised, newer APIs replace older programming models, and products grow in directions that simply aren&amp;#39;t in the model&amp;#39;s training data yet. The assistant has no way of knowing a better approach exists unless something tells it, so it does the reasonable thing and fills the gap with the closest match it can find. Most of the time that match looks plausible enough to trust.&lt;/p&gt;

&lt;p&gt;Across the Office &amp;amp; PDF File API and DevExpress Reports review, the team watched this happen again and again. Same prompt, same model, same task. The only thing they changed was what the assistant knew before it started. And the moment it started from accurate DevExpress guidance rather than memory, the code changed.&lt;/p&gt;

&lt;p&gt;Here are three examples straight from that work.&lt;/p&gt;

&lt;h2&gt;Example 1: Generating a QR Code&lt;/h2&gt;

&lt;p&gt;Start with something ordinary.&lt;/p&gt;

&lt;div style="background:#f7f9fb;border-left:4px solid #fa6432;border-radius:0 6px 6px 0;padding:14px 18px;margin:0 0 22px;"&gt;
&lt;p style="margin:0 0 6px;"&gt;&lt;strong&gt;Prompt&lt;/strong&gt;&lt;/p&gt;
&lt;p style="margin:0;"&gt;&lt;em&gt;Generate a QR Code containing &lt;code&gt;https://community.devexpress.com&lt;/code&gt; and save it as a PNG using DevExpress.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Without the Barcode Skill, the assistant reached for an older DevExpress API. The important thing to note, the Barcode functionality was NOT removed, simply improved and updated.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-csharp"&gt;using DevExpress.BarCodes;

BarCode barCode = new BarCode();
barCode.Symbology = Symbology.QRCode;
barCode.CodeText = url;
barCode.Save(&amp;quot;qr.png&amp;quot;);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There&amp;#39;s almost nothing to object to here. It reads cleanly, it follows normal C# conventions, and if you didn&amp;#39;t already know the current Barcode API you&amp;#39;d have every reason to assume it was fine. That&amp;#39;s exactly what makes this kind of error awkward. It doesn&amp;#39;t look absurd. It looks sensible.&lt;/p&gt;

&lt;p&gt;The trouble is the historical &lt;code&gt;DevExpress.BarCodes&lt;/code&gt; namespace and an object model that no longer reflects the current API. The model hasn&amp;#39;t invented nonsense; it has rebuilt a solution out of older fragments that showed up often enough in training to feel right.&lt;/p&gt;

&lt;p&gt;With the Barcode Skill loaded, the same prompt lands on the current API.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-csharp"&gt;using System.IO;
using DevExpress.Docs.Barcode;
using DevExpress.Drawing;

var qrOptions = new QRCodeOptions {
    ModuleSize = 4f,
    Dpi = 96
};

using var generator = new BarcodeGenerator(qrOptions);
using var output = new FileStream(&amp;quot;qr.png&amp;quot;, FileMode.Create, FileAccess.Write);
generator.Export(&amp;quot;https://community.devexpress.com&amp;quot;, output, DXImageFormat.Png);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Nothing changed except what the assistant knew going in. That matters more than it first appears, because the first answer becomes the foundation for everything after it. Start the conversation on an obsolete namespace and every follow-up (styling the barcode, switching the output format, dropping the image into another document) tends to stay on that same dead branch.&lt;/p&gt;

&lt;p&gt;I&amp;#39;ll be honest: these errors worry me more than a broken build ever has. A bad method name announces itself. Convincing code built on an old API doesn&amp;#39;t, and it&amp;#39;s easiest to trust precisely when you&amp;#39;re moving fast and not looking closely. The Skill heads that off by putting the assistant on the right API before the conversation picks up speed.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;Example 2: Exporting Large Excel Files&lt;/h2&gt;

&lt;p&gt;This one&amp;#39;s trickier, because the &amp;quot;wrong&amp;quot; code isn&amp;#39;t wrong in the usual sense. It compiles. It produces a perfectly valid workbook. The problem is that the assistant picked the wrong DevExpress product for the job.&lt;/p&gt;

&lt;div style="background:#f7f9fb;border-left:4px solid #fa6432;border-radius:0 6px 6px 0;padding:14px 18px;margin:0 0 22px;"&gt;
&lt;p style="margin:0 0 6px;"&gt;&lt;strong&gt;Prompt&lt;/strong&gt;&lt;/p&gt;
&lt;p style="margin:0;"&gt;&lt;em&gt;Export 100,000 rows to an Excel workbook efficiently using DevExpress.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Without the &lt;a href="https://docs.devexpress.com/OfficeFileAPI/114031/excel-export-library" target="_blank" title="Excel Export Library"&gt;Excel Export Library&lt;/a&gt; Skill, most assistants reach for the Spreadsheet API.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-csharp"&gt;using var workbook = new Workbook();

Worksheet sheet = workbook.Worksheets[0];

for (int i = 0; i &amp;lt; 100_000; i++)
{
    sheet.Cells[i, 0].Value = data[i];
}

workbook.SaveDocument(&amp;quot;output.xlsx&amp;quot;, DocumentFormat.Xlsx);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Functionally, this is a fair answer. It builds a workbook and writes data into it, and for most day-to-day work the DevExpress Spreadsheet API is exactly what you want: it gives you a rich in-memory object model for creating, editing, formatting, calculating and analysing content.&lt;/p&gt;

&lt;p&gt;But look at the prompt again. It says &lt;strong&gt;efficiently&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Building an Excel document and streaming out a large dataset are related jobs, not the same job. The Spreadsheet API holds the whole workbook in memory so everything stays editable for the life of the document. That&amp;#39;s a strength when you&amp;#39;re editing. At 100,000 rows it&amp;#39;s mostly overhead, because once a row is written you&amp;#39;re never going back to touch it, the formulas usually don&amp;#39;t need recalculating mid-generation, and what you actually care about is memory that stays flat as the row count climbs. That&amp;#39;s the exact problem the DevExpress Excel Export Library was built for.&lt;/p&gt;

&lt;p&gt;With the Excel Export Skill in play, the assistant switches to the streaming API.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-csharp"&gt;using DevExpress.Export.Xl;

IXlExporter exporter = XlExport.CreateExporter(XlDocumentFormat.Xlsx);

using var document = exporter.CreateDocument(stream);
using var sheet = document.CreateSheet();

foreach (var customer in customers)
{
    using var row = sheet.CreateRow();
    using var cell = row.CreateCell();
    cell.Value = customer.Name;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These two libraries aren&amp;#39;t rivals. They solve different problems. One hands you a full workbook object model for manipulation; the other writes rows straight to the stream and keeps memory predictable no matter how big the export gets. On its own, the assistant has no real basis for preferring one over the other, because both technically satisfy the loose wording of the prompt.&lt;/p&gt;

&lt;p&gt;That&amp;#39;s the gap the Skill fills. It isn&amp;#39;t fixing syntax; it&amp;#39;s supplying the engineering judgement to match the API to the workload.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;Example 3: Report Viewer Setup and Customization&lt;/h2&gt;

&lt;p&gt;DevExpress Reports is a great stress test for AI-assisted development, because so much of it hinges on small platform-specific details. The code can look structurally perfect and still be missing the one registration call, callback or client-side API that makes the viewer actually work.&lt;/p&gt;

&lt;p&gt;One evaluation prompt asked for the native DevExpress Report Viewer in a Blazor Server app. Without the DevExpress Blazor Reports Skill, the assistant registered services for the JavaScript-based viewer family instead of the native Blazor one.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-csharp"&gt;builder.Services.AddDevExpressBlazorReporting();&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Easy mistake to make. The method name sounds right, it slots neatly into the ASP.NET Core service registration pipeline, and nothing about it raises a flag. But native Blazor Reporting needs a different call.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-csharp"&gt;builder.Services.AddDevExpressServerSideBlazorReportViewer();&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is the kind of thing that costs a disproportionate amount of pain. The app compiles, the page loads, and you&amp;#39;re left staring at a blank viewer wondering what you did wrong. Nothing failed at the C# level. It failed at knowing which DevExpress Reports viewer family the prompt was even talking about.&lt;/p&gt;

&lt;p&gt;The same story plays out when you customise the viewer. Say you want to hide the Print button and limit exports to PDF. With no product guidance, assistants tend to invent APIs that feel plausible but don&amp;#39;t exist.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-javascript"&gt;previewModel.GetToolbarItemCommands().forEach(command =&amp;gt; {
    if (command.id === &amp;quot;print&amp;quot;) {
        command.visible = false;
    }
});

previewModel.GetExportFormatItems().forEach(item =&amp;gt; {
    if (item.format !== &amp;quot;pdf&amp;quot;) {
        item.visible = false;
    }
});&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It reads like it belongs in a reporting viewer: sensible names, a clean split between toolbar and export customisation, the shape of a real client-side API. But the actual DevExpress callbacks use different entry points.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-javascript"&gt;function customizeMenuActions(s, e) {
    var printAction = e.GetById(DevExpress.Reporting.Viewer.ActionId.PrintPage);
    if (printAction) {
        printAction.visible = false;
    }
}

function customizeExportOptions(s, e) {
    e.HideFormat(DevExpress.Reporting.Viewer.ExportFormatID.XLS);
    e.HideFormat(DevExpress.Reporting.Viewer.ExportFormatID.XLSX);
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is why specialised frameworks are hard for general-purpose assistants. The answer has the right shape and the wrong product knowledge, and in reporting, where so much of the setup is declarative or callback-driven, one wrong method name is the difference between a working viewer and a dead end.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;When the Best Answer Is Another Question&lt;/h2&gt;

&lt;p&gt;Not every win comes from better code. Some of my favourite Skill behaviour shows up when the assistant decides &lt;em&gt;not&lt;/em&gt; to write code yet.&lt;/p&gt;

&lt;p&gt;AI assistants are heavily biased towards answering the prompt in front of them. When a requirement is underspecified, they&amp;#39;ll usually make an assumption and press on. That keeps things moving, but it also produces software that satisfies the words of the prompt rather than what you actually meant.&lt;/p&gt;

&lt;p&gt;Picture asking for &amp;quot;a chart using DevExpress.&amp;quot; From a developer&amp;#39;s point of view that request is wide open. Bar, line, pie, scatter? What&amp;#39;s the data source? Who&amp;#39;s the audience? Any experienced developer would ask a question or two before writing a line.&lt;/p&gt;

&lt;p&gt;Most assistants won&amp;#39;t. They&amp;#39;ll pick whatever chart type seems most likely and start generating.&lt;/p&gt;

&lt;p&gt;Several DevExpress Skills nudge the assistant the other way: when something essential is missing, ask first.&lt;/p&gt;

&lt;div style="background:#f7f9fb;border-left:4px solid #fa6432;border-radius:0 6px 6px 0;padding:14px 18px;margin:0 0 22px;"&gt;
&lt;p style="margin:0 0 6px;"&gt;&lt;strong&gt;Developer&lt;/strong&gt;&lt;/p&gt;
&lt;p style="margin:0 0 12px;"&gt;&lt;em&gt;Create a chart using DevExpress.&lt;/em&gt;&lt;/p&gt;
&lt;p style="margin:0 0 6px;"&gt;&lt;strong&gt;AI with the Skill&lt;/strong&gt;&lt;/p&gt;
&lt;p style="margin:0;"&gt;&lt;em&gt;Which chart type would you like to create? For example, Bar, Line, Pie, Area or Scatter?&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;That small shift makes the whole thing feel less like poking a code generator and more like working with a colleague. And it saves you the classic time-sink of unwinding an implementation built on an assumption nobody ever made.&lt;/p&gt;

&lt;p&gt;You could bake this into your own prompts, of course, but then you&amp;#39;re on the hook to remember it, repeat it across every assistant you use, and keep it in step with how your team works. Putting it in a Skill makes it part of the workflow instead of one more line you have to paste into every request.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;Skills and the DevExpress MCP Server&lt;/h2&gt;

&lt;p&gt;One question comes up almost every time I talk about this:&lt;/p&gt;

&lt;div style="background:#f7f9fb;border-left:4px solid #fa6432;border-radius:0 6px 6px 0;padding:14px 18px;margin:0 0 22px;"&gt;
&lt;p style="margin:0;"&gt;&lt;em&gt;If the DevExpress MCP Server already gives AI agents access to the documentation, why do we need Skills too?&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Because they&amp;#39;re solving different problems.&lt;/p&gt;

&lt;p&gt;A Skill is the focused guidance the assistant gets &lt;em&gt;before&lt;/em&gt; it starts: enough to recognise the right product area, follow the common implementation patterns, and sidestep the mistakes that come from leaning on training data alone. Skills are deliberately small, so they load fast and cover a lot of everyday work without sending the assistant off on several rounds of exploration.&lt;/p&gt;

&lt;p&gt;The MCP Server plays a different role. It gives compatible agents live access to the current documentation, API details and examples. That&amp;#39;s the shipping product, not whatever the model happened to memorise.&lt;/p&gt;


&lt;img src="https://community.devexpress.com/blogs/paulu/skill-mcp-flow.png" alt="A developer prompt passes through a DevExpress Skill to the AI coding assistant, which exchanges requests and authoritative detail with the DevExpress MCP Server before producing generated code." style="max-width:100%;height:auto;"&gt;
A Skill points the assistant to the right product area up front; the MCP Server supplies authoritative detail once the task gets specific.


&lt;p&gt;In practice they hand off to each other. The Skill gets the assistant to the right place; when the task needs more depth, the MCP Server supplies the authoritative reference to carry it through. Together they cut the guesswork at both ends: the Skill keeps the assistant out of the wrong product area, and the MCP Server fills in the specifics once the work gets detailed.&lt;/p&gt;

&lt;p&gt;That pairing also trims a lot of back-and-forth. Without a Skill, an agent can burn several tool calls just working out which API it should be using. With the right Skill loaded, those MCP calls go towards real implementation questions instead of correcting the assistant&amp;#39;s starting assumptions.&lt;/p&gt;

&lt;p&gt;There&amp;#39;s a discoverability angle here too. In a recent customer survey, roughly a third of respondents didn&amp;#39;t know the DevExpress MCP Server existed. Skills give us a natural way to reintroduce it as part of a broader AI-assisted workflow, rather than leaving it as a separate tool people may never stumble across.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;Why Smaller Models Benefit Even More&lt;/h2&gt;

&lt;p&gt;The big frontier models are impressive even when their product knowledge is patchy. Claude Opus, Claude Sonnet and the latest GPT-class models can often reason their way to something that works, especially with documentation access or a patient developer steering. They still slip up, but they tend to recover.&lt;/p&gt;

&lt;p&gt;Smaller and older models have a harder time. Compact models like Claude Haiku and Gemini Flash (and the local models more teams are running now) are built to be fast, responsive and cheap. They&amp;#39;re a great fit for plenty of coding work, but they carry less specialised product knowledge out of training.&lt;/p&gt;

&lt;p&gt;This is where Skills earn their keep. Rather than asking a compact model to reverse-engineer an unfamiliar API from a handful of examples, the Skill hands it the essentials up front: current namespaces, recommended entry points, the usual patterns and the traps worth avoiding, all dropped straight into its working context.&lt;/p&gt;

&lt;p&gt;And it matters beyond the hosted services. More teams are looking at local models for privacy, compliance or cost reasons. Those models will keep improving, but they&amp;#39;re never going to hold detailed knowledge of every commercial framework or every recently shipped API. Skills close that gap by supplying the DevExpress-specific context regardless of whether the model runs in the cloud or on the developer&amp;#39;s own machine.&lt;/p&gt;

&lt;p&gt;The aim isn&amp;#39;t to make a small model behave like a large one. It&amp;#39;s to let you choose the model that suits your workflow without giving up confidence that it understands the DevExpress APIs you&amp;#39;re working with.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;Skills Versus Custom Instructions&lt;/h2&gt;

&lt;p&gt;Most AI assistants already give you a way to shape their behaviour. Copilot has custom instructions, Cursor has rule files, Claude Code has project instructions, and just about every other agent has its own flavour. Useful, all of them, but also fragmenting: each one wants its guidance in a different format.&lt;/p&gt;

&lt;p&gt;Work across a few tools and you end up maintaining the same advice in several places at once. Coding conventions, preferred APIs, project-specific practices, all copied between config files and quietly drifting out of sync.&lt;/p&gt;

&lt;p&gt;Skills take a more portable route. They load when they&amp;#39;re relevant and stay out of the way when they&amp;#39;re not: a DevExpress Reports&amp;nbsp;Skill turns up for reporting work, a Barcode Skill for barcode generation, spreadsheet guidance when you&amp;#39;re in Excel territory. The assistant gets what it needs without dragging a giant instruction file into every unrelated conversation.&lt;/p&gt;

&lt;p&gt;That on-demand behaviour is the point. Loading everything into every request eats context and pulls the assistant&amp;#39;s attention off the task at hand. Progressive disclosure keeps the working context tight, which really shows when you&amp;#39;ve got several DevExpress products installed, or a project that mixes reporting, document processing and web UI.&lt;/p&gt;

&lt;p&gt;Portability is just as valuable. Because Skills aren&amp;#39;t tied to one assistant, the same guidance travels across every supported agent. And as plugin-based distribution matures, Skills give updates a path to evolve alongside DevExpress products, instead of leaving each developer to hand-maintain their own instruction files.&lt;/p&gt;

&lt;p&gt;The takeaway is simple: you shouldn&amp;#39;t have to teach every AI assistant how to use DevExpress from scratch. Install the relevant Skills, pair them with the MCP Server when you need more depth, and let the tooling carry consistent guidance wherever the work happens.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;Looking Beyond the Prompt&lt;/h2&gt;

&lt;p&gt;A year ago, most of the conversation around AI-assisted development was about prompt engineering, with whole posts hunting for the magic phrasing that would unlock better code. Prompts matter, no argument. But they&amp;#39;re only part of the story. An assistant can only work with what it knows, and no amount of elegant wording makes up for knowledge that isn&amp;#39;t there.&lt;/p&gt;

&lt;p&gt;That&amp;#39;s the lesson that runs through the team&amp;#39;s work on the Office File &amp;amp; PDF API and DevExpress Reports Skills. When the assistant only half-knew DevExpress, it papered over the gaps with educated guesses. When it started from accurate context, the output was more reliable, more current, and a lot closer to what an experienced DevExpress developer would actually write.&lt;/p&gt;

&lt;p&gt;The MCP Server rounds out the picture, handing compatible agents the current documentation, examples and API details whenever the task needs more depth. Skills get the assistant to the right starting point; the MCP Server keeps it honest from there.&lt;/p&gt;

&lt;p&gt;Assistants will keep getting better. New models, stronger reasoning, today&amp;#39;s rough edges smoothing out. What won&amp;#39;t change is the value of context. General-purpose models will always do better when they understand the frameworks they&amp;#39;re building on, especially frameworks that move faster than any training run can keep up with.&lt;/p&gt;

&lt;p&gt;That&amp;#39;s the thinking behind both DevExpress AI Skills and the DevExpress Documentation MCP Server. Between them, the assistant gets immediate guidance and access to current product knowledge. The payoff isn&amp;#39;t just cleaner code. It&amp;#39;s a development experience that feels less like correcting a stranger and more like working alongside someone who already knows the framework you&amp;#39;re using.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;Further Reading&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/DevExpress/agent-skills"&gt;DevExpress AI Skills on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.devexpress.com/Blazor/405919"&gt;DevExpress AI Skills for Coding Agents (Getting Started)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.devexpress.com/GeneralInformation/405551/help-resources/dev-express-documentation-mcp-server-configure-an-ai-powered-assistant"&gt;Configure the DevExpress Documentation MCP Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://community.devexpress.com/Blogs/news/archive/2025/10/16/transform-your-development-experience-with-the-devexpress-mcp-server.aspx"&gt;Introducing the DevExpress MCP Server (DevExpress Blog)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.devexpress.com/OfficeFileAPI/14911/office-file-api"&gt;Office &amp;amp; PDF File API Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.devexpress.com/XtraReports/2162/reporting"&gt;DevExpress Reporting Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <pubDate>Thu, 09 Jul 2026 03:23:00 Z</pubDate>
      <dc:creator>Paul Usher (DevExpress)</dc:creator>
    </item>
    <item>
      <guid isPermaLink="false">bd716303-653c-428d-8b8a-a7d998cde032:388292</guid>
      <link>https://community.devexpress.com/Blogs/markmiller/archive/2026/06/22/what-39-s-new-in-coderush-26-1-mermaid-diagrams-latex-formulas-and-smarter-ai.aspx</link>
      <category domain="https://community.devexpress.com/Tags/AI">AI</category>
      <category domain="https://community.devexpress.com/Tags/AI+Agents">AI Agents</category>
      <category domain="https://community.devexpress.com/Tags/AiGen">AiGen</category>
      <category domain="https://community.devexpress.com/Tags/CodeRush">CodeRush</category>
      <category domain="https://community.devexpress.com/Tags/Formulas+in+Source+Code">Formulas in Source Code</category>
      <category domain="https://community.devexpress.com/Tags/IDE">IDE</category>
      <category domain="https://community.devexpress.com/Tags/LaTeX">LaTeX</category>
      <category domain="https://community.devexpress.com/Tags/Math+expressions">Math expressions</category>
      <category domain="https://community.devexpress.com/Tags/Mermaid+Diagrams">Mermaid Diagrams</category>
      <category domain="https://community.devexpress.com/Tags/productivity">productivity</category>
      <category domain="https://community.devexpress.com/Tags/Visual+Studio">Visual Studio</category>
      <category domain="https://community.devexpress.com/Tags/visual+studio+2022">visual studio 2022</category>
      <category domain="https://community.devexpress.com/Tags/Voice+Commands">Voice Commands</category>
      <title>What's New in CodeRush 26.1: Mermaid Diagrams, LaTeX Formulas, and Smarter AI</title>
      <description>&lt;p&gt;This release adds support for embedding &lt;a href="https://mermaid.ai/" target="_blank"&gt;Mermaid diagrams&lt;/a&gt; and&amp;nbsp;beautifully rendered formulas (math, chemistry, physics) into source code comments. This release also adds support for the latest AI models, improves AiGen&amp;#39;s ability to work with diagrams and formulas, and introduces a new Test Runner feature that makes it easier to troubleshoot failing tests with AI assistance.&lt;/p&gt;&lt;p&gt;Let&amp;#39;s take a look.&lt;/p&gt;&lt;h2&gt;Mermaid Diagrams in Rich Comments&lt;/h2&gt;&lt;p&gt;Rich Comments can now render Mermaid diagrams directly inside source code comments.&lt;/p&gt;&lt;p&gt;Instead of maintaining architectural&amp;nbsp;diagrams in separate documentation systems that inevitably drift from the implementation, you can keep them alongside the code they describe. Mermaid source is stored in external &lt;code&gt;.mmd&lt;/code&gt; files and referenced in the source code comment where it renders, allowing diagrams to participate naturally in source control and code reviews.&lt;/p&gt;&lt;p&gt;CodeRush renders Mermaid diagrams directly inside the editor, supporting a broad range of diagram types including:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Flowcharts&lt;/li&gt;&lt;li&gt;Sequence diagrams&lt;/li&gt;&lt;li&gt;Class diagrams&lt;/li&gt;&lt;li&gt;State diagrams&lt;/li&gt;&lt;li&gt;Entity Relationship diagrams&lt;/li&gt;&lt;li&gt;Git graphs&lt;/li&gt;&lt;li&gt;Mind maps&lt;/li&gt;&lt;li&gt;Timelines&lt;/li&gt;&lt;li&gt;ZenUML&lt;/li&gt;&lt;li&gt;And many more&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;em&gt;&lt;span&gt;]&lt;img src="https://community.devexpress.com/blogs/markmiller/SequenceDiagram.png" alt="" style="width:1341px;height:951px;"&gt;&lt;/span&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Diagrams can be edited in place by right-clicking the rendered image and selecting &lt;strong&gt;Edit Diagram&lt;/strong&gt;. The integrated editor provides a live preview while you modify the Mermaid source inside Visual Studio, eliminating the need to switch to external tools.&amp;nbsp;You can even have AiGen&amp;nbsp;generate and modify Mermaid source automatically -- more on that in a bit.&amp;nbsp;&lt;/p&gt;&lt;img src="https://community.devexpress.com/blogs/markmiller/SequenceDiagram2.png" alt=""&gt;&lt;p&gt;We added two display options make diagrams easier to manage in larger files.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Thumbnail Mode&lt;/strong&gt; collapses a diagram into a compact preview that expands on demand, making it ideal for large architectural diagrams. Just click the thumbnail to see it in the full size image viewer.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="https://community.devexpress.com/blogs/markmiller/Thumbnail.png" alt="" style="width:817px;height:269px;"&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;When a thumbnail expands, it appears in a special image viewer that makes it easy to explore large images.&amp;nbsp;You can zoom in and out with the mouse wheel and you can click and drag to shift your view into the large image.&amp;nbsp;&lt;/span&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Fit in TextView&lt;/strong&gt; automatically scales diagrams to fit the current editor window, helping them remain readable at a glance without introducing unnecessary scrolling.&lt;/p&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;h2&gt;Enhanced LaTeX Support&lt;/h2&gt;&lt;p&gt;LaTeX support has graduated from beta and now provides sharper output, improved performance, and expanded support for complex mathematical notation, including matrices, piecewise functions, chemistry notation, physics symbols, and multi-line expressions.&lt;/p&gt;&lt;p&gt;&lt;img src="https://community.devexpress.com/blogs/markmiller/ApproximateErrorFunction.png" alt=""&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;Formulas automatically scale with the editor font, allowing them to integrate naturally with surrounding code.&amp;nbsp;&lt;/p&gt;&lt;p&gt;The following templates create formula placeholders&amp;nbsp;inside code comments:&lt;/p&gt;
&lt;table&gt;

&lt;tr&gt;
&lt;th&gt;Language&lt;/th&gt;
&lt;th&gt;Template&lt;/th&gt;
&lt;th&gt;Expansion&lt;/th&gt;
&lt;/tr&gt;


&lt;tr&gt;
&lt;td&gt;C#&lt;/td&gt;
&lt;td&gt;/f&lt;/td&gt;
&lt;td&gt;// &amp;lt;formula &amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VB&lt;/td&gt;
&lt;td&gt;‘f&lt;/td&gt;
&lt;td&gt;‘ &amp;lt;formula &amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;XAML&lt;/td&gt;
&lt;td&gt;!f&lt;/td&gt;
&lt;td&gt;&amp;lt;!– &amp;lt;formula &amp;gt; –&amp;gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;
&lt;p&gt;After expanding one of the templates above in the appropriate source file, you can paste in the LaTeX equation (you can also use &lt;a href="https://latexeditor.lagrida.com/" target="_blank"&gt;online LaTeX equation editors&lt;/a&gt; to create formulas)&lt;/p&gt;&lt;p&gt;Templates for LaTeX formula components:
&lt;/p&gt;
&lt;table&gt;

&lt;tr&gt;
&lt;th&gt;Template&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Expansion&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;


&lt;tr&gt;
&lt;td&gt;\.&lt;/td&gt;
&lt;td&gt;Centered dot&lt;/td&gt;
&lt;td&gt;\cdot&lt;/td&gt;
&lt;td&gt;&lt;img src="https://docs.devexpress.com/CodeRushForRoslyn/images/cdot.png" alt="centered-dot"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\..&lt;/td&gt;
&lt;td&gt;Three centered dots&lt;/td&gt;
&lt;td&gt;\cdots&lt;/td&gt;
&lt;td&gt;&lt;img src="https://docs.devexpress.com/CodeRushForRoslyn/images/cdots.png" alt="three-centered-dots"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\8&lt;/td&gt;
&lt;td&gt;Infinity&lt;/td&gt;
&lt;td&gt;\infty&lt;/td&gt;
&lt;td&gt;&lt;img src="https://docs.devexpress.com/CodeRushForRoslyn/images/infinity.png" alt="infinity"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\b&lt;/td&gt;
&lt;td&gt;Braces&lt;/td&gt;
&lt;td&gt;{}&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\bca&lt;/td&gt;
&lt;td&gt;Big Cap&lt;/td&gt;
&lt;td&gt;\bigcap_{lower}^{upper}&lt;/td&gt;
&lt;td&gt;&lt;img src="https://docs.devexpress.com/CodeRushForRoslyn/images/bigCap.png" alt="big-cap"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\bcu&lt;/td&gt;
&lt;td&gt;Big Cup&lt;/td&gt;
&lt;td&gt;\bigcup_{lower}^{upper}&lt;/td&gt;
&lt;td&gt;&lt;img src="https://docs.devexpress.com/CodeRushForRoslyn/images/bigCup.png" alt="big-cup"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\cp&lt;/td&gt;
&lt;td&gt;Co-product&lt;/td&gt;
&lt;td&gt;\coprod_{lower}^{upper}&lt;/td&gt;
&lt;td&gt;&lt;img src="https://docs.devexpress.com/CodeRushForRoslyn/images/coprod.png" alt="co-prodict"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\f&lt;/td&gt;
&lt;td&gt;Fraction&lt;/td&gt;
&lt;td&gt;\frac{numerator}{denominator}&lt;/td&gt;
&lt;td&gt;&lt;img src="https://docs.devexpress.com/CodeRushForRoslyn/images/frac.png" alt="fraction"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\l&lt;/td&gt;
&lt;td&gt;Limit&lt;/td&gt;
&lt;td&gt;\lim_{x\to\infty}&lt;/td&gt;
&lt;td&gt;&lt;img src="https://docs.devexpress.com/CodeRushForRoslyn/images/lim.png" alt="limit"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\lr&lt;/td&gt;
&lt;td&gt;Left &amp;amp; Right Parens&lt;/td&gt;
&lt;td&gt;\left( \right)&lt;/td&gt;
&lt;td&gt;&lt;img src="https://docs.devexpress.com/CodeRushForRoslyn/images/parens.png" alt="left-right-parens"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\nr&lt;/td&gt;
&lt;td&gt;nth Root&lt;/td&gt;
&lt;td&gt;\sqrt[root]{value}&lt;/td&gt;
&lt;td&gt;&lt;img src="https://docs.devexpress.com/CodeRushForRoslyn/images/nthRoot.png" alt="nth-root"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\o&lt;/td&gt;
&lt;td&gt;Circle symbol&lt;/td&gt;
&lt;td&gt;\circ&lt;/td&gt;
&lt;td&gt;&lt;img src="https://docs.devexpress.com/CodeRushForRoslyn/images/circ.png" alt="circle-symbol"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\oi&lt;/td&gt;
&lt;td&gt;Contour integral&lt;/td&gt;
&lt;td&gt;\oint&lt;/td&gt;
&lt;td&gt;&lt;img src="https://docs.devexpress.com/CodeRushForRoslyn/images/oint.png" alt="contour-integral"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\p&lt;/td&gt;
&lt;td&gt;Product&lt;/td&gt;
&lt;td&gt;\prod_{lower}^{upper}&lt;/td&gt;
&lt;td&gt;&lt;img src="https://docs.devexpress.com/CodeRushForRoslyn/images/prod.png" alt="product"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\s&lt;/td&gt;
&lt;td&gt;Sum&lt;/td&gt;
&lt;td&gt;\sum_{lower}^{upper}&lt;/td&gt;
&lt;td&gt;&lt;img src="https://docs.devexpress.com/CodeRushForRoslyn/images/sum.png" alt="sum"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\sq&lt;/td&gt;
&lt;td&gt;Square Root&lt;/td&gt;
&lt;td&gt;\sqrt{value}&lt;/td&gt;
&lt;td&gt;&lt;img src="https://docs.devexpress.com/CodeRushForRoslyn/images/sqrt.png" alt="square-root"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\v&lt;/td&gt;
&lt;td&gt;Vector&lt;/td&gt;
&lt;td&gt;\vec{numerator}&lt;/td&gt;
&lt;td&gt;&lt;img src="https://docs.devexpress.com/CodeRushForRoslyn/images/vec.png" alt="vector"&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;&lt;p&gt;Together with Mermaid support, Rich Comments become an effective place to capture visuals of algorithms, mathematical derivations, engineering and architectural diagrams directly within the source code.&lt;/p&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;h2&gt;AiGen Works with Code, Diagrams, and Formulas&lt;/h2&gt;&lt;p&gt;AiGen now understands not only your source code, but also the Mermaid diagrams and LaTeX formulas contained within Rich Comments.&lt;/p&gt;&lt;p&gt;This enables new workflows. You can ask AiGen to generate diagrams from existing code, generate code from diagrams, create LaTeX representations of algorithms, or analyze whether documentation and implementation remain consistent.&lt;/p&gt;&lt;p&gt;Here&amp;#39;s an example of a Mermaid diagram in Visual Studio generated from the source code below it.&lt;br&gt;&lt;/p&gt;&lt;img src="https://community.devexpress.com/blogs/markmiller/FlowChartForSimpleMethod.png" alt="" style="width:361px;height:649px;"&gt;&lt;p&gt;&lt;span&gt;Keeping documentation synchronized with evolving code has traditionally been a manual process. Because AI can now reason across both implementation and in-source documentation (including diagrams and formulas), you can use CodeRush and AiGen to realign architectural drift over time.&lt;/span&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;You can also ask AiGen to &lt;strong&gt;generate LaTeX formulas for expressions inside a&amp;nbsp;method and have those placed inside a comment&amp;nbsp;&lt;/strong&gt;in the code. In the screenshot below notice that AI found the local variable &lt;code class="language-csharp"&gt;u = 1 - t&lt;/code&gt;&amp;nbsp;and substituted its expression everywhere the &lt;code class="language-csharp"&gt;u&lt;/code&gt;&amp;nbsp;variable appeared in the code. It also found coefficients and power equivalents and incorporated them into the formula.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;img src="https://community.devexpress.com/blogs/markmiller/CubicBezierFormula2.png" alt="" style="width:681px;height:305px;"&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;h2&gt;Expanded AI Model Support&lt;/h2&gt;&lt;p&gt;AiGen now supports the latest generation of AI models from multiple providers, including:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Anthropic Claude 4.5 models&lt;/li&gt;&lt;li&gt;Google Gemini 2.x and 3.x models&lt;/li&gt;&lt;li&gt;OpenAI GPT-5.5 models&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Support has also been added for advanced reasoning capabilities available on supported models.&lt;/p&gt;&lt;p&gt;Configuring providers, selecting models, and understanding model-specific capabilities is covered in a separate blog post dedicated to AI configuration.&lt;/p&gt;&lt;div&gt;&lt;hr&gt;&lt;/div&gt;&lt;h2&gt;Copy Failed Test Report&lt;/h2&gt;&lt;p&gt;The Test Runner includes a new &lt;strong&gt;Copy Failed Test Report&lt;/strong&gt; command.&lt;/p&gt;&lt;p&gt;Available from the context menu, this command copies detailed information for every failing test within the selected node (and child nodes)&amp;nbsp;including fully-qualified test names, execution times, exception information, and complete stack traces.&lt;/p&gt;&lt;p&gt;The generated report is ideal for direct use with AI assistants, making it easy to send the clipboard results to AiGen or another LLM for analysis of failing tests and identification of common root causes.&lt;/p&gt;&lt;p&gt;&lt;img src="https://community.devexpress.com/blogs/markmiller/CopyFailedTestReport.png" alt="" style="width:439px;height:570px;"&gt;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:&amp;#39;Open Sans Condensed&amp;#39;, HelveticaNeue-CondensedBold, Helvetica, &amp;#39;Arial Narrow&amp;#39;, Calibri, Arial, &amp;#39;Lucida Grande&amp;#39;, sans-serif;font-size:30px;"&gt;Wrapping Up&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The features in this release share a common goal: keeping more of your project&amp;#39;s knowledge inside the source code itself.&lt;/p&gt;&lt;p&gt;Mermaid diagrams, LaTeX formulas, and AI-generated documentation all become first-class citizens, and AiGen gets the ability to reason across code and diagram documentation together. Along with expanded AI model support and improved developer tooling like &lt;strong&gt;Copy Failed Test Report&lt;/strong&gt;, these new features&amp;nbsp;streamline everyday development while helping in-source documentation stay in sync with implementation.&lt;/p&gt;&lt;p&gt;As always, we look forward to hearing your feedback.&lt;/p&gt;</description>
      <pubDate>Mon, 22 Jun 2026 09:00:00 Z</pubDate>
      <dc:creator>Mark Miller (DevExpress)</dc:creator>
    </item>
    <item>
      <guid isPermaLink="false">bd716303-653c-428d-8b8a-a7d998cde032:388288</guid>
      <link>https://community.devexpress.com/Blogs/news/archive/2026/06/02/devexpress-developer-survey-ai-impact-security-accessibility-compliance-upgrade-other-product-experience.aspx</link>
      <category domain="https://community.devexpress.com/Tags/Accessibility">Accessibility</category>
      <category domain="https://community.devexpress.com/Tags/ai">ai</category>
      <category domain="https://community.devexpress.com/Tags/Compliance">Compliance</category>
      <category domain="https://community.devexpress.com/Tags/Featured">Featured</category>
      <category domain="https://community.devexpress.com/Tags/installation">installation</category>
      <category domain="https://community.devexpress.com/Tags/licensing">licensing</category>
      <category domain="https://community.devexpress.com/Tags/security">security</category>
      <category domain="https://community.devexpress.com/Tags/Survey">Survey</category>
      <category domain="https://community.devexpress.com/Tags/upgrade">upgrade</category>
      <category domain="https://community.devexpress.com/Tags/ux">ux</category>
      <title>DevExpress Developer Survey — AI Impact, Regulatory Compliance, Upgrade &amp; General Product Experience</title>
      <description>&lt;p&gt;As always, we thank you for your continued support and for choosing DevExpress for your software development needs.&lt;/p&gt;&lt;p&gt;Below is&amp;nbsp;an important usage survey and we ask that you take a few minutes to submit your feedback to us. Your thoughts/comments will help us shape our future R&amp;amp;D efforts so they better align with your development objectives.&amp;nbsp;&lt;span&gt;The survey should take&amp;nbsp;&lt;/span&gt;&lt;strong&gt;about 10 minutes&lt;/strong&gt;&lt;span&gt;&amp;nbsp;to complete.&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;The focus of this survey is as follows:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;AI-assisted development and its impact on your enterprise&lt;/li&gt;&lt;li&gt;Regulatory compliance requirements in an ever-changing regulatory landscape&lt;/li&gt;&lt;li&gt;Satisfaction with DevExpress product delivery model and licensing&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Your Feedback Matters!&lt;/h2&gt;
&lt;div data-survey-id="67e5b107-c501-4b6b-9d32-727b9d7a3577" data-survey-auth-required="true"&gt;&lt;/div&gt;
&lt;p&gt;&lt;span&gt;Thanks,&lt;/span&gt;&lt;br&gt;&lt;span&gt;Dennis Garavsky&lt;/span&gt;&lt;br&gt;&lt;span&gt;Principal Product Manager&lt;/span&gt;&lt;br&gt;&lt;a href="mailto:dennis@devexpress.com" title="Email me if you have questions or suggestions"&gt;dennis@devexpress.com&lt;/a&gt;&lt;br&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 02 Jun 2026 07:08:00 Z</pubDate>
      <dc:creator>Dennis Garavsky (DevExpress)</dc:creator>
    </item>
    <item>
      <guid isPermaLink="false">bd716303-653c-428d-8b8a-a7d998cde032:388291</guid>
      <link>https://community.devexpress.com/Blogs/xaf/archive/2026/06/01/xaf-blazor-winforms-ui-case-study-by-datawerkes-field-services-management-platform-timewerkes.aspx</link>
      <category domain="https://community.devexpress.com/Tags/Audit">Audit</category>
      <category domain="https://community.devexpress.com/Tags/bi">bi</category>
      <category domain="https://community.devexpress.com/Tags/blazor">blazor</category>
      <category domain="https://community.devexpress.com/Tags/case+study">case study</category>
      <category domain="https://community.devexpress.com/Tags/charts">charts</category>
      <category domain="https://community.devexpress.com/Tags/Dashboards">Dashboards</category>
      <category domain="https://community.devexpress.com/Tags/LOB">LOB</category>
      <category domain="https://community.devexpress.com/Tags/lowcode">lowcode</category>
      <category domain="https://community.devexpress.com/Tags/PivotGrid">PivotGrid</category>
      <category domain="https://community.devexpress.com/Tags/rad">rad</category>
      <category domain="https://community.devexpress.com/Tags/reporting">reporting</category>
      <category domain="https://community.devexpress.com/Tags/Reports">Reports</category>
      <category domain="https://community.devexpress.com/Tags/scheduler">scheduler</category>
      <category domain="https://community.devexpress.com/Tags/security">security</category>
      <category domain="https://community.devexpress.com/Tags/TreeList">TreeList</category>
      <category domain="https://community.devexpress.com/Tags/Validation">Validation</category>
      <category domain="https://community.devexpress.com/Tags/WinForms">WinForms</category>
      <category domain="https://community.devexpress.com/Tags/workflow">workflow</category>
      <category domain="https://community.devexpress.com/Tags/XAF">XAF</category>
      <category domain="https://community.devexpress.com/Tags/XPO">XPO</category>
      <title>XAF Blazor/WinForms UI — Case Study by DataWerkes: Field Services Management Platform (TimeWerkes)</title>
      <description>&lt;p&gt;Meet &lt;a href="https://www.datawerkes.ca/" target="_blank"&gt;DataWerkes&lt;/a&gt;&amp;nbsp;(&lt;span&gt;an independent software vendor&amp;nbsp;&lt;/span&gt;in Alberta, Canada) and &lt;span&gt;Keith Courneyea (a founder),&amp;nbsp;&lt;/span&gt;who has been using our&amp;nbsp;&lt;a href="https://www.devexpress.com/products/net/application_framework/" target="_blank" style="background-color:#ffff99;"&gt;Cross-Platform .NET App UI (XAF)&lt;/a&gt;&amp;nbsp;since 2019.&lt;br&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="https://www.devexpress.com/aboutus/testimonials/assets/casestudies/datawerkes-logo.png" alt="DataWerkes"&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;We recently &lt;strong&gt;&lt;a href="https://www.devexpress.com/AboutUs/Testimonials/timewerkes/" target="_blank" style="background-color:#ffff99;"&gt;published a case study&lt;/a&gt;&lt;/strong&gt; about their &lt;span&gt;flagship commercial product&lt;/span&gt; (TimeWerkes)&amp;nbsp;powered by &lt;a href="https://www.devexpress.com/products/net/application_framework/" target="_blank"&gt;XAF&lt;/a&gt; WinForms/Blazor UI as well as DevExpress&amp;nbsp;&lt;a href="https://www.devexpress.com/products/net/controls/blazor/" target="_blank"&gt;Blazor&lt;/a&gt;&amp;nbsp;/&amp;nbsp;&lt;a href="https://www.devexpress.com/products/net/controls/winforms/" target="_blank"&gt;WinForms&lt;/a&gt;&amp;nbsp;(Grid &amp;amp; Data&amp;nbsp;Editors, Charts, Pivot Grid, TreeList, Scheduler, Rich Text Editor),&amp;nbsp;&lt;a href="https://www.devexpress.com/subscriptions/reporting/" target="_blank"&gt;Reporting&lt;/a&gt;&amp;nbsp;and &lt;a href="https://www.devexpress.com/products/net/dashboard/" target="_blank"&gt;BI Dashboard&lt;/a&gt; components. &lt;/p&gt;&lt;p&gt;Here is how Keith Courneyea described their product TimeWerkes (has been in active client use since late 2024):&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;TimeWerkes is a commercial, end-to-end field services management platform for industrial contractors. It manages the full business lifecycle of a contracting operation — from initial quoting through job execution, field ticketing (aka time reporting), inspection reporting, and final invoicing — within a single integrated application available as both a Windows desktop client and a Blazor Server web application. Currently the Blazor app in the primary client.&lt;br&gt;&lt;br&gt;The platform is architected as a core business foundation with industry-specific modules that can be added as client requirements evolve. The core handles workflows common to all contractors: quotes, jobs, field tickets (aka timesheets) with labour and billable items, rate sheets, approval workflows, staff and certification management, equipment tracking, document management, and full invoicing. Specialized modules adapt this base for specific industries.&lt;br&gt;&lt;br&gt; TimeWerkes is offered commercially. It is built on Microsoft SQL Server with Azure SQL in production and uses Azure Blob Storage for all document/image attachments, Azure Functions for background workflow processing, and Azure Communication Services for automated email notifications.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;&lt;img src="https://www.devexpress.com/AboutUs/Testimonials/timewerkes/i/03-job-detail-view@2x.png" alt=""&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="https://www.devexpress.com/AboutUs/Testimonials/timewerkes/i/05-corrosion-survey-report@2x.png" alt=""&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;DataWerkes has been in operation for seven years.&amp;nbsp;&lt;/span&gt;Keith&amp;#39;s decision to build on DevExpress in 2019 was not the result of a product evaluation or a recommendation — it was a return. He had worked with DevExpress components in the early 2000s and had a positive experience that stayed with him. When he decided to pursue serious application development, DevExpress was the first place he went back to.&lt;/p&gt;&lt;p&gt;&lt;span&gt;The specific choice of &lt;a href="https://www.devexpress.com/products/net/application_framework/" target="_blank"&gt;XAF&lt;/a&gt; as the framework was driven by what Keith needed as a first-time C# developer with a clear vision of what he wanted to build. XAF&amp;#39;s model-driven approach — where defining a domain class in XPO produces a working UI, security system, and data layer without writing boilerplate infrastructure code — meant that Keith could focus on the business logic he understood deeply and let the framework handle the rest.&lt;/span&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;And here’s what&amp;nbsp;Keith Courneyea&amp;nbsp;said about XAF&amp;#39;s primary benefits&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;TimeWerkes uses the full breadth of the XAF module ecosystem. The &lt;a href="https://docs.devexpress.com/eXpressAppFramework/113366/data-security-and-safety/security-system" target="_blank"&gt;Security System&lt;/a&gt; provides role-based access control across the entire application without custom authentication code. The &lt;a href="https://docs.devexpress.com/eXpressAppFramework/112782/data-security-and-safety/audit-trail-module-overview" target="_blank"&gt;Audit Trail&lt;/a&gt; module — extended through Llamachant&amp;#39;s enhanced implementation — tracks every change across all 120 domain entities. The &lt;a href="https://docs.devexpress.com/eXpressAppFramework/113008/validation/validation-rules" target="_blank"&gt;Validation&lt;/a&gt; module enforces business rules declaratively. &lt;a href="https://docs.devexpress.com/eXpressAppFramework/113286/conditional-appearance" target="_blank"&gt;Conditional Appearance&lt;/a&gt; drives dynamic UI behaviour. The &lt;a href="https://docs.devexpress.com/eXpressAppFramework/112811/event-planning-and-notifications/scheduler-module" target="_blank"&gt;Scheduler&lt;/a&gt; handles staff and job scheduling. &lt;a href="https://docs.devexpress.com/eXpressAppFramework/113591/shape-export-print-data/reports/reports-v2-module-overview" target="_blank"&gt;Reports Module&lt;/a&gt; V2 powers 34 reports covering every business document in the system, from client-facing inspection reports to internal job cost summaries and invoices.&lt;br&gt;&lt;br&gt;Critically, XAF&amp;#39;s cross-platform architecture meant that the same core module and XPO domain model powers three deployment targets simultaneously: a WinForms desktop client, a Blazor Server web application, and an Azure Functions background processing host. A team of any size would find that a significant time saving. For a product owned by one person and built in partnership with a small development firm, it is what made the product possible at all.&lt;br&gt;&lt;br&gt;Dave Hesketh of Llamachant Technology Ltd., whose team serves as the primary development partner on TimeWerkes, describes the XAF ecosystem as central to how Llamachant approaches every engagement. &lt;a href="https://www.llamachant.com/docs/Modules" target="_blank"&gt;Llamachant&amp;#39;s own framework extensions&lt;/a&gt; — including the workflow engine, Azure Blob file attachment integration, AutoIncrementingID, and LlamaLogger — are themselves built on top of XAF, which is a measure of how extensible and production-ready the platform is.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://www.devexpress.com/AboutUs/Testimonials/timewerkes/" target="_blank" style="background-color:#ffff99;"&gt;Read the full article&lt;/a&gt;&amp;nbsp;to learn why DataWerkes chose XAF&amp;nbsp;for&amp;nbsp;cross-platform RAD project development and&amp;nbsp;what they liked about our tools.&amp;nbsp;&lt;/p&gt;&lt;div class="Note"&gt;&lt;a href="https://docs.devexpress.com/eXpressAppFramework/113577/getting-started" style="background-color:#ffff99;"&gt;Get&amp;nbsp;Started with XAF today&lt;/a&gt;&amp;nbsp;if you want to build Office-like line-of-business (LOB) apps powered by Blazor and WinForms much faster than using traditional approaches. Check out XAF&amp;#39;s demos in your DevExpress installation or online at&amp;nbsp;&lt;a href="https://demos.devexpress.com/xaf/blazordemo/" target="_blank"&gt;https://demos.devexpress.com/xaf/blazordemo/&lt;/a&gt;. You can learn more about&amp;nbsp;&lt;a href="https://www.devexpress.com/products/net/application_framework/" target="_blank"&gt;XAF benefits here&lt;/a&gt;,&amp;nbsp;and our &lt;a href="https://www.devexpress.com/products/net/application_framework/xaf-considerations-for-newcomers.xml" target="_blank"&gt;Considerations for Newcomers&lt;/a&gt;&amp;nbsp;will help you understand whether this application framework is right for your business.&lt;br&gt;&lt;/div&gt;&lt;h2&gt;Do You Have a Story to Share?&lt;/h2&gt;&lt;p&gt;We&amp;#39;d love to publish your story on our website. It doesn’t matter if the project is big or small, or which DevExpress tools you used. Fill out this simple&amp;nbsp;&lt;a href="https://community.devexpress.com/blogs/xaf/social/Developer_Express_General_Case_Study_Template.docx" target="_blank"&gt;case&amp;nbsp;study form&lt;/a&gt;&amp;nbsp;and email us at&amp;nbsp;&lt;a href="mailto:clientservices@devexpress.com"&gt;clientservices@devexpress.com&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Thanks,&lt;br&gt;Dennis Garavsky&lt;br&gt;Principal Product Manager&lt;br&gt;&lt;a title="Email me if you have questions or suggestions" href="mailto:dennis@devexpress.com?subject=Feedback%20on%20Installation-NuGet%20Experience"&gt;dennis@devexpress.com&lt;/a&gt;&amp;nbsp;&lt;/p&gt;</description>
      <pubDate>Mon, 01 Jun 2026 12:49:00 Z</pubDate>
      <dc:creator>Dennis Garavsky (DevExpress)</dc:creator>
    </item>
    <item>
      <guid isPermaLink="false">bd716303-653c-428d-8b8a-a7d998cde032:388290</guid>
      <link>https://community.devexpress.com/Blogs/news/archive/2026/05/29/application-security-documents-are-untrusted-input.aspx</link>
      <category domain="https://community.devexpress.com/Tags/.NET">.NET</category>
      <category domain="https://community.devexpress.com/Tags/.net+core">.net core</category>
      <category domain="https://community.devexpress.com/Tags/Architecture">Architecture</category>
      <category domain="https://community.devexpress.com/Tags/ASP.NET">ASP.NET</category>
      <category domain="https://community.devexpress.com/Tags/Blazor">Blazor</category>
      <category domain="https://community.devexpress.com/Tags/Office+File+API">Office File API</category>
      <category domain="https://community.devexpress.com/Tags/Reporting">Reporting</category>
      <category domain="https://community.devexpress.com/Tags/security">security</category>
      <category domain="https://community.devexpress.com/Tags/WinForms">WinForms</category>
      <category domain="https://community.devexpress.com/Tags/WPF">WPF</category>
      <category domain="https://community.devexpress.com/Tags/XAF">XAF</category>
      <title>Application Security — Documents Are Untrusted Input</title>
      <description>&lt;h2 id="a-docx-is-a-zip-file"&gt;A .docx is a ZIP file&lt;/h2&gt;
&lt;p&gt;Open a &lt;code&gt;.docx&lt;/code&gt; file in a hex editor and the first two bytes are &lt;code&gt;PK&lt;/code&gt;. Every
modern Office format - &lt;code&gt;.docx&lt;/code&gt;, &lt;code&gt;.xlsx&lt;/code&gt;, &lt;code&gt;.pptx&lt;/code&gt; - is a ZIP archive of XML parts
and embedded resources. PDF is not a ZIP file, but just like Office formats it
is a container. When your code loads any of these file types, some complex work
is done with the content of that container: compressed streams are inflated,
references are resolved, an object graph is materialized.&lt;/p&gt;
&lt;p&gt;Most of us understand a “load document” feature to be a passive read operation:
bytes in, document model out, nothing happens that we didn’t ask for. But
loading is not passive, and the document itself dictates the shape and size of
the process. A document can instruct the loader to allocate gigabytes from a few
kilobytes on disk, to follow a path that climbs out of the extraction directory,
or to decrypt with primitives pulled in by the format specification
implicitly. The document is input, but it must be treated as untrusted input.&lt;/p&gt;
&lt;p&gt;Loading a document implies a security boundary.&lt;/p&gt;
&lt;p&gt;Here are a few examples of known attack vectors used “in the wild” against document loaders:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“Decompression bombs” are small archives that inflate to a size which exhausts memory.&lt;/li&gt;
&lt;li&gt;Path traversal (“Zip Slip”) can write outside the intended directory when
extracted carelessly, by using an entry named &lt;code&gt;../../etc/something&lt;/code&gt; or &lt;code&gt;..\..\Windows\System32\something&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Symlink and device-name tricks use entries resolving to absolute paths, or to
reserved Windows names like &lt;code&gt;CON&lt;/code&gt;, &lt;code&gt;NUL&lt;/code&gt;, &lt;code&gt;PRN&lt;/code&gt;, to cause damage when extracted.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="compatible-is-not-secure"&gt;”Compatible” is not “secure”&lt;/h2&gt;
&lt;p&gt;Most applications which load documents can’t easily decide to only support the
latest formats. Of course we know not to assume that old formats are as secure
as new ones, but since support for legacy formats is required, we may believe
that if our loader algorithms are compliant with the latest standards, then we
are secure. Unfortunately, that is not always the case.&lt;/p&gt;
&lt;p&gt;For example, a PDF may be encrypted with AES-128. By name that is a modern
choice, nothing obviously legacy about it. But the PDF standard (ISO 32000-1)
requires AES-128-encrypted PDFs to derive the encryption key with MD5 and to
validate permissions with RC4. Both are long recognized as cryptographically
weak, and neither is permitted under FIPS 140-2, the US government’s
cryptographic standard. PDF readers that support AES-128 encryption need to
support MD5 and RC4, and this means that the code path that loads such documents
is not FIPS-compliant.&lt;/p&gt;
&lt;p&gt;This is what “compatible isn’t secure” actually means: you didn’t knowingly pick
something old, but your choice to support a seemingly current format carries a
hidden legacy dependency. The same is true of Office document protection: the
latest OpenXML formats support SHA-512 hashing, but they also support SHA-1 and
MD5 for legacy reasons. If you support the format, you support the legacy
algorithms too.&lt;/p&gt;
&lt;p&gt;A document format is a specification, and it can mandate approaches that your
application code can’t avoid. Your exposure is inherited from the standards you
choose to support, not introduced by any mistakes you made.&lt;/p&gt;
&lt;p&gt;In the .NET space in particular, the Windows FIPS policy used to be the main
line of defence against this problem. If you tried to load a document that
triggered a non-compliant code path, the runtime would throw an
exception. However, this safety mechanism was never perfect:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;On .NET Framework with the Windows FIPS policy enabled, instantiating a
non-validated algorithm threw an exception. However, that exception was a
&lt;code&gt;TargetInvocationException&lt;/code&gt; with a message pointing at a generic non-validated
implementation, and lacking details like the document type or the offending
algorithm.&lt;/li&gt;
&lt;li&gt;On .NET 5 and later, managed FIPS enforcement was largely removed. An MD5/RC4
code path now runs with no error at all. The trap is the transition: code that
threw reliably on .NET Framework can fall silent after a routine upgrade to
.NET 5 or later, with no source change. It is easy to read that silence as the
problem having been fixed, when in fact only the diagnostic has gone, while
the code remains exactly as non -compliant, just quieter about it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This means that any loader code is responsible for auditing the document types
it supports. We can’t rely on the runtime to enforce compliance.&lt;/p&gt;
&lt;h2 id="office-file-api-compliance-and-safety-by-design"&gt;Office &amp;amp; PDF File API: compliance and safety by design&lt;/h2&gt;
&lt;p&gt;The latest &lt;a href="https://www.devexpress.com/products/net/office-file-api/" target="_blank" style="background-color:#ffffff;"&gt;Office &amp;amp; PDF File API&lt;/a&gt; answers both halves of the problem with a single
idea: &lt;strong&gt;compliance and structural safety should be enforced automatically and
early in the pipeline&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;At the cryptographic layer, FIPS enforcement is now explicit. On a FIPS-enforced
Windows system, opening or saving a document that depends on cryptography
prohibited by FIPS (this includes encrypted XLS or DOC files, AES-128 or ARC4
PDFs, OpenXML protection using SHA-1 or MD5 hashes) throws a
&lt;code&gt;DevExpress.Utils.OperatingSystemLevelFipsMode.ComplianceViolationException&lt;/code&gt;
&lt;em&gt;before&lt;/em&gt; processing. We made two design choices to improve upon the .NET
Framework-style handling. First,
the exception derives from &lt;code&gt;System.Security.SecurityException&lt;/code&gt;, so existing
&lt;code&gt;catch (SecurityException)&lt;/code&gt; blocks keep working unchanged. Second, the message
includes actionable details: instead of the runtime’s generic string, our
message tells you which detail of the document you attempted to load was
non-compliant, and we include suggestions for compliance.&lt;/p&gt;
&lt;p&gt;Note that on machines which are not configured with the Windows FIPS policy, or
in non-Windows environments, no cryptography validation is performed. It is
possible to force the same behavior by setting
&lt;code&gt;DevExpress.Utils.OperatingSystemLevelFipsMode.ForcedFipsMode&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt;, and
you can use &lt;code&gt;IsEnabled&lt;/code&gt; on the same type to detect whether the policy is
active. Setting &lt;code&gt;ForcedFipsMode&lt;/code&gt; does not change the operating system level
policy.&lt;/p&gt;
&lt;p&gt;At the structural layer, the new &lt;code&gt;SecureZipPolicy&lt;/code&gt; applies to both the low-level
data engine (&lt;code&gt;DevExpress.Utils.Zip&lt;/code&gt;) and the high-level API
(&lt;code&gt;DevExpress.Compression.ZipArchive&lt;/code&gt;). It enforces resource limits with sensible
defaults, such as maximum entry count, per-entry and total uncompressed size,
per-entry and total compression ratio to guard against “decompression bombs”, as
well as path-nesting depth. It blocks the structural attacks mentioned earlier:
path traversal, absolute paths, control characters, reserved device names,
symlinks. The write-time encryption default also changes from the old
&lt;code&gt;EncryptionType.PkZip&lt;/code&gt; to AES-256.&lt;/p&gt;
&lt;p&gt;The structural enforcement through &lt;code&gt;SecureZipPolicy&lt;/code&gt; applies to all ZIP
processing and is not tied to the FIPS policy. But on systems that do not have
FIPS enabled, a call to &lt;code&gt;SecureZipPolicy.SetEncryptionPolicy(...)&lt;/code&gt; with either
&lt;code&gt;AesRequired&lt;/code&gt; or &lt;code&gt;FipsStrict&lt;/code&gt; (the latter disallows any unknown encryption types
on read) enables the encryption policies regardless of any OS-level
configuration.&lt;/p&gt;
&lt;h2 id="some-of-these-changes-may-be-breaking"&gt;Some of these changes may be “breaking”&lt;/h2&gt;
&lt;p&gt;If you process documents on FIPS-enforced systems, code that previously ran on
.NET 5 or later may now throw an exception. We have published detailed guidance
for existing code, &lt;a href="https://supportcenter.devexpress.com/ticket/details/t1327031/office-pdf-file-api-fips-enforcement-for-encrypted-doc-xls-and-pdf-documents" rel="nofollow noreferrer" target="_blank"&gt;Breaking Change T1327031 for the Office and PDF File
API&lt;/a&gt;
and &lt;a href="https://supportcenter.devexpress.com/ticket/details/t1325920/new-zip-security-policy-has-been-applied-to-both-our-low-level-data-engine-devexpress" rel="nofollow noreferrer" target="_blank"&gt;Breaking Change T1325920 for the new Zip Security
Policy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It is important to point out that these changes are only “breaking” in the sense
that they change behavior for existing implementations. They make your code
safer (very directly so in the case of the new Zip security policy), and offer
improved discoverability and auditability of violations for FIPS compliance.&lt;/p&gt;
&lt;p&gt;Without repeating the details of the guides, it is possible to adjust some of
the defaults to restore old behavior, but also to accommodate your
requirements. For example, the Zip policy has tunable parameters for resource
protection.&lt;/p&gt;
&lt;p&gt;We recommend that you take the opportunity to review your document processing
code and consider whether you can migrate to more secure formats. You can use
the new observable violations to identify documents that are currently being
processed but would not be compliant with the new policies, and then make
informed decisions.&lt;/p&gt;&lt;p&gt;&lt;span&gt;See also:&amp;nbsp;&lt;/span&gt;&lt;a href="https://community.devexpress.com/Blogs/news/archive/2026/04/17/application-security-stronger-hashes-and-safer-passwords.aspx"&gt;Application Security — Stronger Hashes and Safer Passwords&lt;/a&gt;&lt;span&gt;.&lt;/span&gt;&lt;br&gt;&lt;/p&gt;
&lt;h2 id="compatibility-and-security"&gt;Compatibility and security&lt;/h2&gt;
&lt;p&gt;A common perception is that security and compatibility are always in tension. We
should state up front that this is not generally true. The new &lt;a href="https://www.devexpress.com/products/net/office-file-api/" target="_blank"&gt;Office &amp;amp; PDF File API&lt;/a&gt;
is an example of a case where the compliant choice and the convenient choice are
the same, and the new enforcement simply makes that alignment visible. For many
applications, there is no meaningful trade-off between security and
compatibility.&lt;/p&gt;
&lt;p&gt;The real conflict between security and compatibility is mostly at the legacy
surface area. Sticking to documents as the main topic of this article, that
legacy surface area can be large if you need to support old formats and old
storage standards, but it can be small if you can migrate to current formats.&lt;/p&gt;
&lt;p&gt;There are two recommendations for navigation of this tension.&lt;/p&gt;
&lt;p&gt;First, if you can use current formats, do. Migrating encrypted XLS to XLSX, DOC
to DOCX and AES-128/ARC4 PDFs to AES-256 (Revision 6) is an easy and cheap
path - speaking from the purely technical perspective of course, while
organizational and regulatory constraints may be more complex, and only you can
judge the practical complexity of migration in your environment.&lt;/p&gt;
&lt;p&gt;If legacy formats are genuinely unavoidable, then treat those documents
explicitly as untrusted input and wrap them accordingly: you now get resource
limits by default, and you can consider separating your loading or conversion
logic out to a standalone process that makes it possible to apply OS limits on
memory use or prevent network access - bearing in mind that any loading method
still parses the document, so the point of a separate process is to contain that
parse, not to avoid it.&lt;/p&gt;
&lt;p&gt;Depending on the exposure your project has to unverified input, you will find
your own balance of “defense in depth” measures, but it is important to make
active decisions about these assessments. Monitoring for violations is easy with
the new policies, and the &lt;code&gt;ResourceLimitViolation&lt;/code&gt; and &lt;code&gt;TrustBoundaryViolation&lt;/code&gt;
events exist precisely so that you gain auditability that matters particularly
in regulated, enterprise, and government environments.&lt;/p&gt;

&lt;h2&gt;Your Feedback Matters!&lt;/h2&gt;
&lt;div data-survey-id="b31c0c9e-b420-4b2b-9501-2a16d14dd7af" data-survey-auth-required="false"&gt;&lt;/div&gt;</description>
      <pubDate>Fri, 29 May 2026 07:04:00 Z</pubDate>
      <dc:creator>Oliver Sturm (DevExpress)</dc:creator>
    </item>
    <item>
      <guid isPermaLink="false">bd716303-653c-428d-8b8a-a7d998cde032:388289</guid>
      <link>https://community.devexpress.com/Blogs/aspnet/archive/2026/05/22/devexpress-blazor-ai-chat-multi-model-support-mcp-server-integration-and-a-look-at-what-39-s-coming-next.aspx</link>
      <category domain="https://community.devexpress.com/Tags/AI">AI</category>
      <category domain="https://community.devexpress.com/Tags/Blazor">Blazor</category>
      <category domain="https://community.devexpress.com/Tags/Chat+UI">Chat UI</category>
      <category domain="https://community.devexpress.com/Tags/LLM">LLM</category>
      <category domain="https://community.devexpress.com/Tags/MCP">MCP</category>
      <category domain="https://community.devexpress.com/Tags/v26.1">v26.1</category>
      <title>DevExpress Blazor AI Chat — Multi-Model Support, MCP Server Integration, and a Look at What's Coming Next</title>
      <description>&lt;p&gt;We continue to extend the capabilities of the&amp;nbsp;&lt;a href="https://docs.devexpress.com/Blazor/DevExpress.AIIntegration.Blazor.Chat.DxAIChat" target="_blank" title="DevExpress Blazor AI Chat"&gt;DevExpress Blazor AI Chat&lt;/a&gt; component and publish GitHub examples designed to address real-world usage scenarios. This post highlights two new examples: a multi-model chat with persistent conversation history, and MCP server integration that extends AI context with external data sources. I&amp;#39;ll also share planned features for v26.1 (scheduled for mid-June 2026).&lt;/p&gt;

&lt;h2 id="multi-model-chat-with-conversation-history"&gt;Multi-Model Chat with Conversation History&lt;/h2&gt;

&lt;p&gt;Our &lt;a href="https://community.devexpress.com/Blogs/aspnet/archive/2025/05/06/devexpress-blazor-ai-chat-build-a-multi-llm-chat-application.aspx" target="_blank" title="DevExpress Blazor AI Chat — Build a Multi-LLM Chat Application"&gt;earlier multi-LLM chat application example&lt;/a&gt; demonstrated how to switch between AI providers within a single chat session. The new &lt;a href="https://github.com/DevExpress-Examples/blazor-ai-chat-with-multiple-llm-services" target="_blank" title="DevExpress Blazor AI Chat — Multi-Model Chat with Conversation History"&gt;DevExpress Blazor AI Chat — Multi-Model Chat with Conversation History&lt;/a&gt; example adds persistent conversation threads and automated chat session title generation.&lt;/p&gt;

&lt;img class="small" src="https://community.devexpress.com/blogs/aspnet/26.1/mcp-multi-llm/devexpress-ai-blazor-chat-multi-llm-with-title-generation.png" alt="The multi-model chat UI showing the left sidebar with a list of conversation threads (each with an auto-generated title), a model selector dropdown at the top, and the active chat pane on the right." style="width:730px;height:606px;"&gt;

&lt;p&gt;The application uses a two-pane layout with &lt;code&gt;DxSplitter&lt;/code&gt;. The left pane is a sidebar that hosts a &lt;code&gt;DxComboBox&lt;/code&gt; for model selection and a &lt;code&gt;DxListBox&lt;/code&gt; for conversation threads. &lt;code&gt;InMemoryChatThreadStore&lt;/code&gt; manages thread data. This thread-safe dictionary-backed store tracks message history and timestamps. The right pane hosts the &lt;code&gt;DxAIChat&lt;/code&gt; component. The following Razor markup defines the layout:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;DxSplitter CssClass=&amp;quot;chat-splitter&amp;quot; Height=&amp;quot;100%&amp;quot;&amp;gt;
    &amp;lt;Panes&amp;gt;
        &amp;lt;DxSplitterPane Size=&amp;quot;320px&amp;quot; MinSize=&amp;quot;220px&amp;quot; MaxSize=&amp;quot;500px&amp;quot;&amp;gt;
            &amp;lt;DxButton RenderStyle=&amp;quot;ButtonRenderStyle.Primary&amp;quot;
                      RenderStyleMode=&amp;quot;ButtonRenderStyleMode.Contained&amp;quot;
                      Text=&amp;quot;New Chat&amp;quot;
                      Click=&amp;quot;CreateNewThreadAsync&amp;quot; /&amp;gt;
            &amp;lt;DxComboBox Data=&amp;quot;@ModelsList&amp;quot;
                        Value=&amp;quot;@SelectedModel&amp;quot;
                        TextFieldName=&amp;quot;@nameof(ChatClientSession.Name)&amp;quot;
                        ValueChanged=&amp;quot;@((ChatClientSession session) =&amp;gt; OnSelectedThreadModelChangedAsync(session))&amp;quot; /&amp;gt;
            &amp;lt;DxListBox Data=&amp;quot;@Threads&amp;quot;
                       Value=&amp;quot;@SelectedThread&amp;quot;
                       ValueChanged=&amp;quot;@((ChatThread thread) =&amp;gt; OnThreadSelectedAsync(thread))&amp;quot;
                       TextFieldName=&amp;quot;@nameof(ChatThread.Title)&amp;quot;&amp;gt;
                &amp;lt;ItemDisplayTemplate&amp;gt;
                    &amp;lt;div class=&amp;quot;thread-list-item&amp;quot;&amp;gt;
                        &amp;lt;div class=&amp;quot;thread-title&amp;quot;&amp;gt;@context.DataItem.Title&amp;lt;/div&amp;gt;
                        &amp;lt;div class=&amp;quot;thread-model&amp;quot;&amp;gt;@GetModelName(context.DataItem.ModelSessionId)&amp;lt;/div&amp;gt;
                    &amp;lt;/div&amp;gt;
                &amp;lt;/ItemDisplayTemplate&amp;gt;
            &amp;lt;/DxListBox&amp;gt;
        &amp;lt;/DxSplitterPane&amp;gt;
        &amp;lt;DxSplitterPane&amp;gt;
            &amp;lt;DxAIChat @ref=&amp;quot;DxAiChat&amp;quot;
                      Initialized=&amp;quot;OnChatInitialized&amp;quot; /&amp;gt;
        &amp;lt;/DxSplitterPane&amp;gt;
    &amp;lt;/Panes&amp;gt;
&amp;lt;/DxSplitter&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Automatic thread title generation is a key implementation detail. The &lt;code&gt;CompositeChatClient&lt;/code&gt; class implements &lt;code&gt;IChatClient&lt;/code&gt; and intercepts outgoing user messages via &lt;code&gt;GetResponseAsync&lt;/code&gt; and &lt;code&gt;GetStreamingResponseAsync&lt;/code&gt; methods. On the first message in a new thread, the class sends a background request to the selected AI model using a dedicated system prompt and requests a concise 3–6 word title. &lt;code&gt;IChatThreadStore&lt;/code&gt; stores the result. The &lt;code&gt;ThreadTitleUpdated&lt;/code&gt; event updates the UI and refreshes the sidebar without blocking the main chat response:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-csharp"&gt;// CompositeChatClient.cs
public IAsyncEnumerable&amp;lt;ChatResponseUpdate&amp;gt; GetStreamingResponseAsync(IEnumerable&amp;lt;ChatMessagegt; messages, 
ChatOptions? options = null, CancellationToken cancellationToken = new CancellationToken())
    {
        var selectedSession = GetRequiredSelectedSession();
        var messageList = messages.ToList();
        TryQueueTitleGeneration(messageList, selectedSession);
		...
        await foreach (var update in selectedSession.Client.GetStreamingResponseAsync(
        	messageList, options, cancellationToken))
            yield return update;
        ...
    }

private void TryQueueTitleGeneration(IEnumerable&amp;lt;ChatMessage&amp;gt; messages, ChatClientSession selectedSession) {
    var threadId = _activeThreadId.Value;
    var firstUserMessage = GetFirstUserMessage(messages);
    ...
    _ = GenerateTitleForThreadAsync(threadId, selectedSession, firstUserMessage);
}

private async Task GenerateTitleForThreadAsync(Guid threadId,
    ChatClientSession selectedSession, string firstUserMessage) {
    try {
        var thread = await _threadStore.GetThreadAsync(threadId, CancellationToken.None);
        if (thread is null || thread.HasGeneratedTitle)
            return;

        var modelSession = AvailableChatClients
            .FirstOrDefault(x =&amp;gt; x.Id == thread.ModelSessionId) ?? selectedSession;

        string generatedTitle;
            try {
                generatedTitle = await _titleGenerator.GenerateTitleAsync(modelSession, firstUserMessage, CancellationToken.None);
            }
            catch {
                generatedTitle = _titleGenerator.BuildFallbackTitle(firstUserMessage);
            }

            if (string.IsNullOrWhiteSpace(generatedTitle)) {
                generatedTitle = _titleGenerator.BuildFallbackTitle(firstUserMessage);
            }

            await _threadStore.UpdateTitleAsync(threadId, generatedTitle, true, CancellationToken.None);
            lock (_syncRoot) {
                _titledThreadIds.Add(threadId);
            }
            ThreadTitleUpdated?.Invoke(threadId, generatedTitle);
        }
        catch (OperationCanceledException) { }
        finally {
            lock (_syncRoot)
                _titleGenerationInProgress.Remove(threadId);
        }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The example includes an in-memory store. The &lt;code&gt;IChatThreadStore&lt;/code&gt; interface allows for replacement with an EF Core-backed implementation for applications that require persistent history.&lt;/p&gt;

&lt;p&gt;To download and explore our implementation, navigate to the following&amp;nbsp;DevExpress GitHub repository: &lt;a href="https://github.com/DevExpress-Examples/blazor-ai-chat-with-multiple-llm-services" target="_blank" title="Blazor AI Chat — Multi-Model Chat with Conversation History"&gt;Blazor AI Chat — Multi-Model Chat with Conversation History&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id="mcp-server-integration"&gt;MCP Server Integration&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/DevExpress-Examples/blazor-ai-chat-mcp-resources" target="_blank" title="DevExpress Blazor AI Chat — Integration with Model Context Protocol"&gt;DevExpress Blazor AI Chat — Integration with Model Context Protocol&lt;/a&gt; example connects our Blazor AI Chat component to external data through the &lt;a href="https://modelcontextprotocol.io/docs/getting-started/intro" target="_blank" title="Model Context Protocol — Introduction"&gt;Model Context Protocol (MCP)&lt;/a&gt;.&lt;/p&gt;

&lt;img class="small" src="https://community.devexpress.com/blogs/aspnet/26.1/mcp-multi-llm/devexpress-ai-blazor-chat-mcp-resources-window.png" alt="The Blazor AI Chat UI with an MCP-powered chat session open, showing the chat querying a server access log and receiving an AI-generated analysis in response." style="width:626px;height:602px;"&gt;

&lt;p&gt;The solution includes two projects.&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;code&gt;AIChatMcpServer&lt;/code&gt; is a custom MCP server that exposes sample tools, resources, and prompt templates to the client application.&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;AIChatMcpClient&lt;/code&gt; is a Blazor Server application that hosts &lt;code&gt;DxAIChat&lt;/code&gt; and loads MCP capabilities at startup through a hosted &lt;code&gt;McpRepository&lt;/code&gt; service.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The sample MCP server exposes three primitives: &lt;strong&gt;tools&lt;/strong&gt; (executable functions the AI model can call automatically), &lt;strong&gt;resources&lt;/strong&gt; (static content such as logs, text files, and binary images), and &lt;strong&gt;prompts&lt;/strong&gt; (reusable parameterized templates). &lt;code&gt;McpRepository&lt;/code&gt; loads these primitives at startup and passes them to &lt;code&gt;DxAIChat&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Each primitive maps directly to a &lt;code&gt;DxAIChat&lt;/code&gt; feature. Resources map to &lt;code&gt;AIChatResource&lt;/code&gt; objects and populate the &lt;code&gt;Resources&lt;/code&gt; collection. Prompts map to &lt;code&gt;DxAIChatPromptSuggestion&lt;/code&gt; entries displayed when the chat opens. Tools attach to &lt;code&gt;IChatClient&lt;/code&gt; through &lt;code&gt;UseFunctionInvocation&lt;/code&gt; at startup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Index.razor&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;DxAIChat FileUploadEnabled=&amp;quot;true&amp;quot;
          Resources=&amp;quot;Resources&amp;quot;
          IncludeFunctionCallInfo=&amp;quot;true&amp;quot;&amp;gt;
        &amp;lt;PromptSuggestions&amp;gt;
            @foreach (var suggestion in PromptSuggestions){
                &amp;lt;DxAIChatPromptSuggestion PromptMessage=&amp;quot;@suggestion.PromptMessage&amp;quot; Title=&amp;quot;@suggestion.Title&amp;quot; Text=&amp;quot;@suggestion.PromptMessage&amp;quot;/&amp;gt;
            }
        &amp;lt;/PromptSuggestions&amp;gt;
        &amp;lt;AIChatSettings&amp;gt;
            &amp;lt;DxAIChatFileUploadSettings MaxFileSize=&amp;quot;10000000&amp;quot; MaxFileCount=&amp;quot;3&amp;quot;/&amp;gt;
        &amp;lt;/AIChatSettings&amp;gt;
    &amp;lt;/DxAIChat&amp;gt;

@code {
    IEnumerable&amp;lt;AIChatResource&amp;gt; Resources { get; set; } = [];
    IEnumerable&amp;lt;PromptSuggestion&amp;gt; PromptSuggestions { get; set; } = [];

    protected override async Task OnInitializedAsync() {
        // Map MCP resources to AIChatResource — DxAIChat fetches content on demand via LoadResourceData
        Resources = McpRepository.Resources.Select(x =&amp;gt;
            new AIChatResource(x.Uri, x.Name, LoadResourceData, x.MimeType, x.Description));
        // Map MCP prompt templates to prompt suggestions shown in the chat UI
        PromptSuggestions = McpRepository.PromptSuggestions;
    }

    async Task&amp;lt;IList&amp;lt;AIContent&amp;gt;&amp;gt; LoadResourceData(AIChatResource resource, CancellationToken ct) {
        var result = await McpRepository.Client.ReadResourceAsync(resource.Uri, cancellationToken: ct);
        return result.Contents.ToAIContents();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Program.cs&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-csharp"&gt;using Azure;
using Azure.AI.OpenAI;
using AIChatMcpClient;
using AIChatMcpClient.Components;
using AIChatMcpClient.Services;
using Microsoft.Extensions.AI;
...

builder.Services.AddSingleton&amp;lt;McpRepository&amp;gt;();
builder.Services.AddHostedService(sp =&amp;gt; sp.GetRequiredService&amp;lt;McpRepository&amp;gt;());

builder.Services.AddSingleton&amp;lt;IChatClient&amp;gt;(sp =&amp;gt; {
    var mcpRepository = sp.GetService&amp;lt;McpRepository&amp;gt;();
    var azureOpenAIClient = new AzureOpenAIClient(
        new Uri(azureOpenAISettings.Endpoint),
        new AzureKeyCredential(azureOpenAISettings.ApiKey));
    var chatClient = azureOpenAIClient.GetChatClient(azureOpenAISettings.DeploymentName).AsIChatClient();
    return new ChatClientBuilder(chatClient)
        .ConfigureOptions(co =&amp;gt; {
            co.Tools = mcpRepository.Tools.ToArray&amp;lt;AITool&amp;gt;();
        })
        .UseFunctionInvocation()
        .Build();
});
...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The implementation follows MCP standards. Client code requires no changes when you switch to another MCP-compliant backend. To connect the Blazor application to a different MCP server, modify the &lt;code&gt;McpRepository&lt;/code&gt; endpoint:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-csharp"&gt;using AIChatMcpClient.Models;
using ModelContextProtocol.Client;
using ModelContextProtocol.Protocol;
...
public class McpRepository : IHostedService, IAsyncDisposable {
    private readonly string _mcpEndpoint;

    public McpClient Client { get; private set; } = null!;
    public List&amp;lt;McpClientTool&amp;gt; Tools { get; } = [];
    public List&amp;lt;McpClientResource&amp;gt; Resources { get; } = [];
    public List&amp;lt;McpClientPrompt&amp;gt; Prompts { get; } = [];
    public List&amp;lt;PromptSuggestion&amp;gt; PromptSuggestions { get; } = [];

    public McpRepository(IConfiguration configuration) {
        _mcpEndpoint = configuration.GetSection(&amp;quot;McpServer:Endpoint&amp;quot;).Value 
                       ?? throw new InvalidOperationException(&amp;quot;McpServer:Endpoint is not configured in appsettings.json&amp;quot;);
    }

    public async Task StartAsync(CancellationToken cancellationToken) {
        var transport = new HttpClientTransport(new() { Endpoint = new(_mcpEndpoint) });
        Client = await McpClient.CreateAsync(transport);
        
        var tools = await Client.ListToolsAsync(cancellationToken: cancellationToken);
        var resources = await Client.ListResourcesAsync(cancellationToken: cancellationToken);
        var prompts = await Client.ListPromptsAsync(cancellationToken: cancellationToken);
        
        Tools.AddRange(tools);
        Resources.AddRange(resources);
        Prompts.AddRange(prompts);

        // Preload prompt suggestions at startup
        foreach (var prompt in Prompts) {
            var result = await prompt.GetAsync();
            var content = result.Messages[0].Content;
            PromptSuggestions.Add(new PromptSuggestion {
                PromptMessage = ((TextContentBlock)content).Text,
                Title = prompt.Title ?? &amp;quot;Untitled&amp;quot;
            });
        }
    }

    public Task StopAsync(CancellationToken cancellationToken) =&amp;gt; Task.CompletedTask;

    public async ValueTask DisposeAsync() {
        await Client.DisposeAsync();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;To download and explore our implementation, navigate to the following&amp;nbsp;DevExpress GitHub repository&lt;/span&gt;: &lt;a href="https://github.com/DevExpress-Examples/blazor-ai-chat-mcp-resources" target="_blank" title="DevExpress Blazor AI Chat — Integration with Model Context Protocol"&gt;DevExpress Blazor AI Chat — Integration with Model Context Protocol&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id="whats-coming-in-v26-1"&gt;What&amp;#39;s Coming in v26.1&lt;/h2&gt;

&lt;p&gt;Our v26.1 release is scheduled for mid-June 2026 and includes the following enhancements to DevExpress AI Chat components for Blazor, WinForms, and WPF.&lt;/p&gt;

&lt;h3 id="microsoft-agent-framework-and-openai-responses-api-support"&gt;Microsoft Agent Framework and OpenAI Responses API Support&lt;/h3&gt;

&lt;p&gt;The most substantial addition is a new &lt;code&gt;IChatResponseProvider&lt;/code&gt; abstraction layer that decouples the chat UI from the underlying AI service. This layer allows you to bind &lt;code&gt;DxAIChat&lt;/code&gt; to a wider set of AI backends beyond the standard &lt;code&gt;IChatClient&lt;/code&gt; interface, including the Microsoft Agent Framework (with support for agents, executors, and multi-step workflows), the OpenAI Responses API, and Azure AI Projects. The API also supports custom &lt;code&gt;IChatResponseProvider&lt;/code&gt; implementations for usage scenarios that don&amp;#39;t fit standard providers.&lt;/p&gt;

&lt;p&gt;Planned demos will illustrate how to connect our&amp;nbsp;AI Chat Control to individual agents, composite workflows, AG-UI backends, and tool approval workflows in agentic pipelines.&lt;/p&gt;

&lt;h3 id="api-enhancements"&gt;API Enhancements&lt;/h3&gt;

&lt;p&gt;v26.1 replaces the &lt;code&gt;MessageSent&lt;/code&gt; event with &lt;code&gt;MessageSending&lt;/code&gt;. This event fires before the message is added to chat history and sent to the AI service. Additionally, this event exposes an &lt;code&gt;e.Cancel&lt;/code&gt; parameter that allows you to block send operations entirely. Use it to preprocess and validate input, filter content, call external services and handle the messaging pipeline manually. Alternatively, if &lt;code&gt;e.Cancel&lt;/code&gt; is set to &lt;code&gt;false&lt;/code&gt;, the AI Chat Control will continue sending and displaying messages and allow you to log and audit user messages without disruption to the normal message pipeline.&lt;/p&gt;

&lt;p&gt;The new event also supports augmentation before delivery — for example, appending a system message or supplemental context to the chat history via the new &lt;code&gt;AppendMessageAsync&lt;/code&gt; method:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-csharp"&gt;async void AiChatControl1_MessageSending(object sender, AIChatControlMessageSendingEventArgs e) {
    // Append a system message before sending the user&amp;#39;s prompt to the AI service.
    await e.Chat.AppendMessageAsync(&amp;quot;Translate text to Spanish&amp;quot;, ChatRole.System);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="empty-chat-customization"&gt;Empty Chat Customization&lt;/h3&gt;

&lt;p&gt;v26.1 introduces two new properties designed to customize initial chat state. &lt;code&gt;EmptyMessageAreaText&lt;/code&gt; specifies text dispalyed in the empty chat area, and &lt;code&gt;InputBoxNullText&lt;/code&gt; specifies placeholder text in the input box. These properties allow you to align the initial chat experience with application context and tone:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;DxAIChat EmptyMessageAreaText=&amp;quot;How can I help you today?&amp;quot;
          InputBoxNullText=&amp;quot;Ask a question or describe a task...&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;img src="https://community.devexpress.com/blogs/aspnet/26.1/mcp-multi-llm/26-1-blazor-aichat-empty-chat-ui@2x.png" alt="Blazor AI Chat — Customized Empty Text Area and Input Null Text" style="width:780px;height:300px;"&gt;

&lt;h2 id="share-your-feedback"&gt;Share Your Feedback&lt;/h2&gt;

&lt;p&gt;Looking for a particular code example? &lt;a href="https://supportcenter.devexpress.com/" target="_blank" title="DevExpress Support Center"&gt;Contact us via the DevExpress Support Center&lt;/a&gt; to share your usage scenario and we&amp;#39;ll be happy to recommend an implementation.&lt;/p&gt;</description>
      <pubDate>Fri, 22 May 2026 00:01:00 Z</pubDate>
      <dc:creator>Dmitry Tokmachev (DevExpress)</dc:creator>
    </item>
    <item>
      <guid isPermaLink="false">bd716303-653c-428d-8b8a-a7d998cde032:388287</guid>
      <link>https://community.devexpress.com/Blogs/news/archive/2026/05/07/sboms-for-cra-compliance-in-devexpress-based-apps-preview-now-open.aspx</link>
      <category domain="https://community.devexpress.com/Tags/.NET">.NET</category>
      <category domain="https://community.devexpress.com/Tags/.net+core">.net core</category>
      <category domain="https://community.devexpress.com/Tags/CRA">CRA</category>
      <category domain="https://community.devexpress.com/Tags/Featured">Featured</category>
      <category domain="https://community.devexpress.com/Tags/JS">JS</category>
      <category domain="https://community.devexpress.com/Tags/npm">npm</category>
      <category domain="https://community.devexpress.com/Tags/NuGet">NuGet</category>
      <category domain="https://community.devexpress.com/Tags/SBOM">SBOM</category>
      <category domain="https://community.devexpress.com/Tags/security">security</category>
      <category domain="https://community.devexpress.com/Tags/VCL">VCL</category>
      <title>SBOMs for CRA Compliance in DevExpress-Based Apps — Preview Now Open</title>
      <description>&lt;p&gt;If you ship apps to customers in the EU, the Cyber Resilience Act (CRA) will require a Software Bill of Materials&amp;nbsp;(SBOM) as part of your conformity documentation. SBOM generation and CRA compliance are top priorities for DevExpress, and CycloneDX SBOM files for our .NET NuGet packages are now available as a preview. We are looking for feedback to help us refine our solution before a broader release.&lt;/p&gt;
&lt;h2 id="why-this-matters"&gt;Why This Matters&lt;/h2&gt;
&lt;p&gt;Regulatory expectations around software supply chain transparency have moved from emerging practice to a baseline requirement over the past four years:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;2021&lt;/strong&gt; — SBOM became a key requirement of the &lt;a href="https://www.whitehouse.gov/briefing-room/presidential-actions/2021/05/12/executive-order-on-improving-the-nations-cybersecurity/"&gt;US Executive Order 14028 on Improving the Nation&amp;#39;s Cybersecurity&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2022&lt;/strong&gt; — Microsoft open-sourced its &lt;a href="https://devblogs.microsoft.com/engineering-at-microsoft/microsoft-open-sources-software-bill-of-materials-sbom-generation-tool/"&gt;SBOM generation tool&lt;/a&gt;, signaling SBOM as a standard part of the build pipeline.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2024&lt;/strong&gt; — Germany&amp;#39;s &lt;a href="https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TR03183/BSI-TR-03183-2_v2_1_0.pdf"&gt;BSI TR-03183 Part 2&lt;/a&gt; made SBOM delivery mandatory for products in scope. The &lt;a href="https://en.wikipedia.org/wiki/Cyber_Resilience_Act"&gt;EU Cyber Resilience Act (CRA)&lt;/a&gt; adopted the same requirement and entered into force on December 10, 2024, with a three-year transition period. Manufacturers selling digital products in the EU must produce and maintain SBOMs for conformity assessment.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2026&lt;/strong&gt; — CRA vulnerability reporting obligations apply from September 11, 2026, ahead of full applicability on December 11, 2027.&lt;/li&gt;
&lt;/ul&gt;
&lt;img src="https://community.devexpress.com/blogs/news/2026/sbom-announcement/sbom-timeline.png" alt="sbom-timeline"&gt;
&lt;p&gt;Under the CRA, SBOM obligation falls on the manufacturer of the finished product. You can run an SBOM generation tool against your project and assemble most of what you need. But tools that read package manifests cannot reliably see bundled NPM assets, statically-linked code, or license attribution for third-party components embedded at build time. A vendor-signed SBOM can fill these gaps and serve as stronger evidence when compared to tool-derived data. Our goal is to provide SBOMs that fit cleanly into workflows you already use.&lt;/p&gt;
&lt;h2 id="what-s-available-today-preview-"&gt;What&amp;#39;s Available Today (Preview)&lt;/h2&gt;
&lt;p&gt;DevExpress publishes digitally-signed CycloneDX 1.6 SBOM files for our .NET NuGet packages. Each SBOM is updated with every build. These files use our production format and signing pipeline — &amp;quot;preview&amp;quot; status reflects ongoing metadata alignment with &lt;a href="https://www.cisa.gov/sites/default/files/2025-08/2025_CISA_SBOM_Minimum_Elements.pdf"&gt;NTIA Minimum Elements&lt;/a&gt; and &lt;a href="https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TR03183/BSI-TR-03183-2_v2_1_0.pdf"&gt;BSI TR-03183&lt;/a&gt;, not file quality.&lt;/p&gt;
&lt;p&gt;Each SBOM:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lists first-party and third-party dependencies, including transitive dependencies.&lt;/li&gt;
&lt;li&gt;Includes a dependency graph for the package it describes.&lt;/li&gt;
&lt;li&gt;Lists corresponding NPM packages and their transitive dependencies when DevExpress .NET packages bundle client-side NPM assets.&lt;/li&gt;
&lt;li&gt;Marks NPM devDependencies (used during development but not shipped) with &lt;code&gt;&amp;quot;scope&amp;quot;: &amp;quot;excluded&amp;quot;&lt;/code&gt; for transparency.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These files can be consumed by standard SBOM analysis tools — including Dependency-Track, Trivy, and Grype.&lt;/p&gt;
&lt;h3 id="current-scope"&gt;Current Scope&lt;/h3&gt;
&lt;p&gt;This first release covers DevExpress .NET product packages (Blazor, WinForms, WPF, ASP.NET Core, Web Forms, MVC, and shared component libraries) published on NuGet.org for our current shipping version (v25.2.6). It does not yet cover VCL or DevExtreme product libraries, installers, demos, packages from our private NuGet feed, standalone assembly-level SBOMs, or earlier package versions. We are starting with this narrow scope so we can refine output based on customer requirements before broadening coverage.&lt;/p&gt;
&lt;div class="Note"&gt;For complete technical details — including known limitations, format specifics, and step-by-step guidance for Dependency-Track, Trivy, and Grype — see our &lt;a href="https://supportcenter.devexpress.com/ticket/details/t1312026/software-bill-of-materials-sbom-for-devexpress-net-assemblies-nuget-packages-javascript"&gt;SBOM discussion thread&lt;/a&gt;.&lt;/div&gt;
&lt;h2 id="your-feedback-matters"&gt;Your Feedback Matters&lt;/h2&gt;
&lt;p&gt;Our SBOM preview is now open to additional participants — particularly developers working on compliance, supply chain security, or vulnerability management for applications built with DevExpress components.&lt;/p&gt;
&lt;p&gt;If you are willing to test our SBOM files in your existing tooling and share what works (and what does not), please complete the survey below. After you submit, our team contacts you with download access and next steps. Survey participants also get a direct line to the product team. If you would prefer to discuss specifics outside the survey, you can also &lt;a href="https://www.devexpress.com/ask"&gt;open a private support ticket&lt;/a&gt;.&lt;/p&gt;
&lt;div data-survey-id="8bfc2c72-365b-4638-b3c5-c89875a66d49" data-survey-auth-required="true"&gt;&lt;/div&gt;</description>
      <pubDate>Thu, 07 May 2026 10:10:00 Z</pubDate>
      <dc:creator>Alex Chuev (DevExpress)</dc:creator>
      <dx:excerpt>If you ship apps to customers in the EU, the Cyber Resilience Act (CRA) will require an SBOM as part of your conformity documentation. SBOM generation and CRA compliance are top priorities for DevExpress, and CycloneDX SBOM files for our .NET NuGet packages are now available as a preview</dx:excerpt>
    </item>
    <item>
      <guid isPermaLink="false">bd716303-653c-428d-8b8a-a7d998cde032:388286</guid>
      <link>https://community.devexpress.com/Blogs/news/archive/2026/04/27/microsoft-build-2026-is-coming.aspx</link>
      <category domain="https://community.devexpress.com/Tags/build">build</category>
      <title>Microsoft Build 2026 is coming!</title>
      <description>&lt;p&gt;...And we shall be there! Not in Seattle this year, but, for a change, in San Francisco. To be more accurate, Microsoft Build will be&amp;nbsp;at&amp;nbsp;&lt;span style="color:#000000;"&gt;Fort Mason Center in San Francisco, CA. for two full days, June 2-3. As is usual,&amp;nbsp;sessions will also be broadcast&amp;nbsp;online.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The main emphasis of Microsoft Build 2026 is going to be&amp;nbsp;AI. Not only how to use AI workflows and agents to write code and applications, but also how to provide AI capabilities to end-users to help them&amp;nbsp;use&amp;nbsp;those apps.&amp;nbsp;Naturally sessions will also cover how developers &amp;quot;supervise&amp;quot; output from AI agents&amp;nbsp;through testing, checking outputs for security, applicability, and so on. For more details on the sessions that will occur at Build, please follow &lt;a href="https://build.microsoft.com/en-US/home" title="Microsoft Build 2026 website"&gt;this link&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;span style="color:#000000;"&gt;Like every year, DevExpress will have a booth in the Partner Hub, and we will be there to chat to attendees about what&amp;#39;s happening&amp;nbsp;with our next major releases coming up in late June, as well as how we&amp;#39;re supporting&amp;nbsp;the topics highlighted&amp;nbsp;in the Build sessions. We&amp;#39;ll talk about how we&amp;#39;re providing support for AI agents&amp;nbsp;when writing apps with our controls, as well as how we&amp;#39;re providing AI capabilities for end-users of the apps that use those&amp;nbsp;controls.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:#000000;"&gt;We look forward to seeing you at our booth if you&amp;#39;re going to Microsoft Build 2026. Do&amp;nbsp;please stop by and say hello!&lt;/span&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 27 Apr 2026 15:10:00 Z</pubDate>
      <dc:creator>Julian Bucknall (DevExpress)</dc:creator>
    </item>
    <item>
      <guid isPermaLink="false">bd716303-653c-428d-8b8a-a7d998cde032:388285</guid>
      <link>https://community.devexpress.com/Blogs/news/archive/2026/04/24/application-security-project-dependency-version-bumps-demystified-modern-security-realities-in-net-nuget-ecosystem.aspx</link>
      <category domain="https://community.devexpress.com/Tags/.NET">.NET</category>
      <category domain="https://community.devexpress.com/Tags/.net+core">.net core</category>
      <category domain="https://community.devexpress.com/Tags/JS">JS</category>
      <category domain="https://community.devexpress.com/Tags/npm">npm</category>
      <category domain="https://community.devexpress.com/Tags/NuGet">NuGet</category>
      <category domain="https://community.devexpress.com/Tags/security">security</category>
      <title>Application Security — Project Dependency "Version Bumps" Demystified or Modern Security Realities in .NET / NuGet Ecosystem</title>
      <description>&lt;p&gt;In this post, I want to show you how to effectively upgrade vulnerable third-party dependencies in your projects, highlight .NET industry best practices, and also clarify how DevExpress helps you mitigate security-related risks in general. For illustration purposes, I will use a System.Security.Cryptography.Xml-related security advisory, which Microsoft published in the GitHub Advisory database &lt;a href="https://github.com/advisories/GHSA-w3x6-4m5h-cxqf" target="_blank"&gt;last week&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;You probably already know about this report from NuGet, Visual Studio, or &lt;a href="https://supportcenter.devexpress.com/ticket/details/t1326802/vulnerable-system-security-cryptography-xml-nuget-package-versions-10-0-0-10-0-5-9-0-0-9" target="_blank"&gt;DevExpress Support Center&lt;/a&gt;. And if not, it&amp;#39;s important to note that &lt;b&gt;such reports impact every NuGet package, which has direct or transitive dependencies on the highlighted package version&lt;/b&gt; (it&amp;#39;s not specific to DevExpress directly). Ultimately, even if such external advisories do not originate from DevExpress, they may impact DevExpress packages and DevExpress customers via a chain of system or third-party sub-dependencies. Hence, it&amp;#39;s still our responsibility as a component vendor to inform our customers, improve transparency and awareness of the best practices, update problematic dependencies of affected DevExpress packages in our new releases.&lt;/p&gt;&lt;img src="https://community.devexpress.com/blogs/news/ghsa-fixed-versions.png" alt="" style="width:2009px;height:711px;border-width:1px;border-color:#c0c0c0;border-style:solid;"&gt;&lt;p&gt;As a result of this System.Security.Cryptography.Xml advisory, you might see warnings in your Solution Explorer, NuGet Package Manager or just build output (example for .NET 8 projects). Since we also build .NET projects and use the same development tools daily, we knew about this new report right after its publication in the GitHub Advisory database on April 13-14th 2026 &lt;strong&gt;(much like you, other vendors or anyone else)&lt;/strong&gt;. Fortunately for all, a general fix (upgrade to the latest package version) is also available for all affected DevExpress and other vendor packages that were &lt;strong&gt;released prior to publishing such advisories&lt;/strong&gt; (for example, DevExpress v25.2.6 released on 07 Apr 2026 - a week before this particular report).&lt;/p&gt;&lt;div class="Note"&gt;warning NU1901: Package &amp;#39;System.Security.Cryptography.Xml&amp;#39; 8.0.2 has a known low severity vulnerability, &lt;a href="https://github.com/advisories/GHSA-w3x6-4m5h-cxqf" rel="nofollow"&gt;https://github.com/advisories/GHSA-w3x6-4m5h-cxqf&lt;/a&gt;&lt;br&gt;DevExpress.Blazor imports the transitive package of System.Security.Cryptography.Xml&lt;/div&gt;&lt;img src="https://community.devexpress.com/blogs/news/image_9.png" alt=""&gt;&lt;h2&gt;General Fix Idea (Applicable to All Solutions)&lt;/h2&gt;&lt;p&gt;The beauty of such simple &amp;quot;version bump&amp;quot; vulnerabilities is that you can easily fix it yourself immediately - without awaiting anyone (vendors, new package versions, etc).&lt;/p&gt;&lt;p&gt;You can bump the version right in your project for affected third-party dependencies (such as Microsoft .NET System.XXX or others), as described in the &amp;quot;&lt;em&gt;How do I fix the issue?&lt;/em&gt;&amp;quot; section of the official advisory. Anyone can apply this fix at their convenience (even &amp;quot;within hours&amp;quot; of publication of the original security advisory in the CVE / GHSA database), because in this instance it&amp;#39;s literally one line of code in one or a few places only.&lt;/p&gt;&lt;img src="https://community.devexpress.com/blogs/news/ghsa-how-to-fix.png" alt="" style="width:2258px;height:1646px;border-width:1px;border-color:#c0c0c0;border-style:solid;"&gt;&lt;p&gt;I also want to emphasize that when a vulnerability occur in a system or core .NET library, many other dependent system, .NET BCL, and vendor libraries are impacted. For example, System.Security.Cryptography.Xml is used by System.ServiceModel.Http, System.ServiceModel.Primitives, System.ServiceModel and others. They are also used directly or indirectly in a dozen more packages - all are often used in many apps of even medium complexity (I am not even talking about complex apps). You will have to update those dependencies anyway, regardless DevExpress or any other impacted package vendor/third-party.&lt;/p&gt;&lt;p&gt;Notwithstanding the negative effects of dealing with a vulnerability, NuGet and its best practices such as &lt;a href="https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management"&gt;&lt;strong&gt;Central Package Management (CPM)&lt;/strong&gt;&lt;/a&gt; exist in the development world - all to deal with such incidents quickly and to address modern realities effectively.

&lt;/p&gt;&lt;h2&gt;Solution #1: You Have a Few Projects Only or Are NOT Using CPM&lt;/h2&gt;&lt;div class="Note"&gt;&lt;strong&gt;Applicability&lt;/strong&gt;: Simple applications (~1-3-5 projects in your solution) targeting any .NET version, no CPM.&lt;br&gt;&lt;strong&gt;Urgency&lt;/strong&gt;: High (apply immediately).&lt;br&gt;&lt;strong&gt;Complexity&lt;/strong&gt;: Medium - Copy and maintain one code line in &lt;strong&gt;X&lt;/strong&gt; files (the number of your projects).&lt;br&gt;&lt;strong&gt;Risks&lt;/strong&gt;: Low.&lt;/div&gt;&lt;p&gt;&lt;strong&gt;If you have no &lt;a href="https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management"&gt;CPM&lt;/a&gt;&lt;/strong&gt;, the standard Microsoft solution is to:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1. &lt;/strong&gt;Add a direct NuGet package reference&amp;nbsp;(&lt;strong&gt;&lt;a href="https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#adding-a-packagereference" target="_blank"&gt;PackageReference&lt;/a&gt;&lt;/strong&gt;)&amp;nbsp;to your required projects (CSPROJ/VBPROJ);&lt;br&gt;&lt;strong&gt;2.&lt;/strong&gt; Set the patched version (&lt;strong&gt;&lt;a href="https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#controlling-dependency-version" target="_blank"&gt;Version&lt;/a&gt;&lt;/strong&gt;) from the advisory (for example, 8.0.3&amp;nbsp;for&amp;nbsp;&lt;span&gt;System.Security.Cryptography.Xml and &lt;span&gt;.NET 8&amp;nbsp;&lt;/span&gt;in this case, but it can be another third-party package/version&lt;/span&gt;):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;.NET 8&lt;/strong&gt;:&amp;nbsp;&lt;code class="language-xml"&gt;&amp;lt;PackageReference Include=&amp;quot;System.Security.Cryptography.Xml&amp;quot; Version=&amp;quot;8.0.3&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;.NET 9&lt;/strong&gt;:&amp;nbsp;&lt;code class="language-xml"&gt;&amp;lt;PackageReference Include=&amp;quot;System.Security.Cryptography.Xml&amp;quot; Version=&amp;quot;9.0.15&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;.NET 10&lt;/strong&gt;:&amp;nbsp;&lt;code class="language-xml"&gt;&amp;lt;PackageReference Include=&amp;quot;System.Security.Cryptography.Xml&amp;quot; Version=&amp;quot;10.0.6&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;As you can see, this is a one-line solution, which you can copy into required projects where problematic direct or transitive dependencies were detected. In my example, I copied it into 1 project&amp;nbsp;only (so, 1 code line&amp;nbsp;in total to maintain).&lt;/p&gt;&lt;img src="https://community.devexpress.com/blogs/news/image_10.png" alt=""&gt;&lt;h2&gt;Solution&amp;nbsp;#2: You Have Multiple Projects or Are Using CPM&lt;/h2&gt;&lt;div class="Note"&gt;&lt;strong&gt;Applicability&lt;/strong&gt;: Medium to complex applications (more than 5&amp;nbsp;projects in your solution) targeting any .NET version, CPM configured.&lt;br&gt;&lt;strong&gt;Urgency&lt;/strong&gt;: High (apply immediately).&lt;br&gt;&lt;strong&gt;Complexity&lt;/strong&gt;: Low - Copy and maintain one code line in one file.&lt;br&gt;&lt;strong&gt;Risks&lt;/strong&gt;: Low.&lt;br&gt;&lt;/div&gt;&lt;p&gt;If you have too many projects so that even the one-line solution is not practical to copy/maintain, then you must seriously consider using &lt;strong&gt;&lt;a href="https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management"&gt;CPM&lt;/a&gt;&lt;/strong&gt;&amp;nbsp;with the Directory.Packages.props file&amp;nbsp;&lt;span&gt;(&lt;/span&gt;&lt;code&gt;&amp;lt;ManagePackageVersionsCentrally&amp;gt;true&amp;lt;/ManagePackageVersionsCentrally&amp;gt;&lt;/code&gt;&lt;span&gt;)&lt;/span&gt;. CPM is the best or recommended development practice regardless this vulnerability discussion anyway.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Regardless how many projects you have in your .NET solution (5, 100, 200, etc.), this is always a one-line solution to maintain - that is the beauty of CPM in action.&lt;/span&gt;&lt;span&gt;CPM is nowadays also super-fast to add to your non-CPM solution with AI assistants.&lt;/span&gt;&lt;/p&gt;&lt;img src="https://community.devexpress.com/blogs/news/image_8.png" alt="" style="width:3524px;height:1594px;border-width:1px;border-color:#c0c0c0;border-style:solid;"&gt;&lt;h3&gt;&lt;span style="font-weight:normal;"&gt;Solution #2.1 (&lt;span&gt;PackageVersion)&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;If CPM&amp;nbsp;is enabled and&amp;nbsp;you need &lt;strong&gt;common dependencies for many different projects (not all) &lt;/strong&gt;in a repository&lt;span&gt;, the&amp;nbsp;&lt;/span&gt;&lt;span&gt;standard Microsoft solution is to:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;strong&gt;1. &lt;/strong&gt;Define a&amp;nbsp;&lt;/span&gt;&lt;strong&gt;&lt;a href="https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#adding-a-packagereference" target="_blank"&gt;PackageReference&lt;/a&gt;&lt;/strong&gt;element&amp;nbsp;&lt;span&gt;&lt;span style="color:#161616;"&gt;&lt;strong&gt;without the&amp;nbsp;&lt;/strong&gt;&lt;strong style="color:#404040;"&gt;&lt;a href="https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#controlling-dependency-version" target="_blank"&gt;Version&lt;/a&gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="color:#161616;"&gt;attribute in&amp;nbsp;&lt;/span&gt;your required projects (CSPROJ/VBPROJ):&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;&lt;code class="language-xml"&gt;&amp;lt;PackageReference Include=&amp;quot;System.Security.Cryptography.Xml&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;2.&lt;/strong&gt; In your&amp;nbsp;&lt;strong&gt;&lt;a href="https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management#enabling-central-package-management" target="_blank"&gt;Directory.Packages.props&lt;/a&gt;&lt;/strong&gt; file,&amp;nbsp;add a&amp;nbsp;package version entry (&lt;strong&gt;&lt;a href="https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management#enabling-central-package-management" target="_blank"&gt;PackageVersion&lt;/a&gt;&lt;/strong&gt;)&amp;nbsp;and&amp;nbsp;set the patched version (&lt;strong&gt;&lt;a href="https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#controlling-dependency-version" target="_blank"&gt;Version&lt;/a&gt;&lt;/strong&gt;) from the advisory (for example, 8.0.3&amp;nbsp;for&amp;nbsp;System.Security.Cryptography.Xml and&amp;nbsp;.NET 8&amp;nbsp;in this case, but it can be another third-party package/version):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;.NET 8&lt;/strong&gt;:&amp;nbsp;&lt;code class="language-xml"&gt;&amp;lt;PackageVersion Include=&amp;quot;System.Security.Cryptography.Xml&amp;quot; Version=&amp;quot;8.0.3&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;.NET 9&lt;/strong&gt;:&amp;nbsp;&lt;code class="language-xml"&gt;&amp;lt;PackageVersion Include=&amp;quot;System.Security.Cryptography.Xml&amp;quot; Version=&amp;quot;9.0.15&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;.NET 10&lt;/strong&gt;:&amp;nbsp;&lt;code class="language-xml"&gt;&amp;lt;PackageVersion Include=&amp;quot;System.Security.Cryptography.Xml&amp;quot; Version=&amp;quot;10.0.6&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;img src="https://community.devexpress.com/blogs/news/image_11.png" alt=""&gt;&lt;h3&gt;Solution #2.2 (GlobalPackageReference)&lt;/h3&gt;&lt;p&gt;&lt;span&gt;If CPM&amp;nbsp;is enabled and&amp;nbsp;&lt;/span&gt;you need to&amp;nbsp;&lt;span style="color:#161616;"&gt;specify a &lt;strong&gt;package&amp;nbsp;&lt;/strong&gt;&lt;span&gt;&lt;strong&gt;to be used by every project&lt;/strong&gt; in a repository, the&amp;nbsp;&lt;/span&gt;&lt;/span&gt;standard Microsoft solution is to:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1.&lt;/strong&gt; Add a global package reference (&lt;strong&gt;&lt;a href="https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management#global-package-references" target="_blank"&gt;GlobalPackageReference&lt;/a&gt;&lt;/strong&gt;) to your Directory.Packages.props file.&lt;br&gt;&lt;strong&gt;2.&lt;/strong&gt;&lt;span&gt;Set the patched version (&lt;/span&gt;&lt;strong&gt;&lt;a href="https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#controlling-dependency-version" target="_blank"&gt;Version&lt;/a&gt;&lt;/strong&gt;&lt;span&gt;) from the advisory (for example, 8.0.3&amp;nbsp;for&amp;nbsp;&lt;/span&gt;&lt;span&gt;System.Security.Cryptography.Xml and&amp;nbsp;.NET 8&amp;nbsp;in this case, but it can be another third-party package/version&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;.NET 8&lt;/strong&gt;:&amp;nbsp;&lt;code class="language-xml"&gt;&amp;lt;GlobalPackageReference Include=&amp;quot;System.Security.Cryptography.Xml&amp;quot; Version=&amp;quot;8.0.3&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;.NET 9&lt;/strong&gt;:&amp;nbsp;&lt;code class="language-xml"&gt;&amp;lt;GlobalPackageReference Include=&amp;quot;System.Security.Cryptography.Xml&amp;quot; Version=&amp;quot;9.0.15&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;.NET 10&lt;/strong&gt;:&amp;nbsp;&lt;code class="language-xml"&gt;&amp;lt;GlobalPackageReference Include=&amp;quot;System.Security.Cryptography.Xml&amp;quot; Version=&amp;quot;10.0.6&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;img src="https://community.devexpress.com/blogs/news/image_6.png" alt="" style="width:558px;height:507px;"&gt;&lt;p&gt;If you already maintain a Directory.Packages.props file, replacing &amp;quot;PackageVersion&amp;quot; with &amp;quot;GlobalPackageReference&amp;quot; is fast too with or without AI.&lt;/p&gt;&lt;img src="https://community.devexpress.com/blogs/news/image_5.png" alt=""&gt;&lt;h3 id="additional-information"&gt;Solution #2.3 (VersionOverride)&lt;/h3&gt;&lt;p&gt;&lt;span&gt;If CPM&amp;nbsp;is enabled and&amp;nbsp;&lt;/span&gt;&lt;span&gt;you need to&amp;nbsp;&lt;strong&gt;ignore the centrally defined package version&amp;nbsp;&lt;/strong&gt;&lt;strong&gt;in a&amp;nbsp;specific project &lt;/strong&gt;of your repository,&amp;nbsp;&lt;/span&gt;&lt;span style="color:#161616;"&gt;the&amp;nbsp;&lt;/span&gt;standard Microsoft solution is to:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1.&amp;nbsp;&lt;/strong&gt;Add a direct NuGet package reference&amp;nbsp;(&lt;strong&gt;&lt;a href="https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#adding-a-packagereference" target="_blank"&gt;PackageReference&lt;/a&gt;&lt;/strong&gt;)&amp;nbsp;to your required projects (CSPROJ/VBPROJ);&lt;br&gt;&lt;strong&gt;2.&lt;/strong&gt;&amp;nbsp;Set the patched version (&lt;strong&gt;&lt;a href="https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management#overriding-package-versions" target="_blank"&gt;VersionOverride&lt;/a&gt;&lt;/strong&gt;) from the advisory (for example, 8.0.3&amp;nbsp;for&amp;nbsp;System.Security.Cryptography.Xml and&amp;nbsp;.NET 8&amp;nbsp;in this case, but it can be another third-party package/version):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;.NET 8&lt;/strong&gt;:&amp;nbsp;&lt;code&gt;&amp;lt;PackageReference Include=&amp;quot;System.Security.Cryptography.Xml&amp;quot; VersionOverride=&amp;quot;8.0.3&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;.NET 9&lt;/strong&gt;:&amp;nbsp;&lt;code&gt;&amp;lt;PackageReference Include=&amp;quot;System.Security.Cryptography.Xml&amp;quot; VersionOverride=&amp;quot;9.0.15&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;.NET 10&lt;/strong&gt;:&amp;nbsp;&lt;code&gt;&amp;lt;PackageReference Include=&amp;quot;System.Security.Cryptography.Xml&amp;quot; VersionOverride=&amp;quot;10.0.6&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;You can disable this feature in your&amp;nbsp;project or&amp;nbsp;Directory.Packages.props /&amp;nbsp;Directory.Build.props&amp;nbsp;files:&amp;nbsp;&lt;code class="language-xml"&gt;&amp;lt;CentralPackageVersionOverrideEnabled&amp;gt;false&amp;lt;/CentralPackageVersionOverrideEnabled&amp;gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt;(in that case VersionOverride causes error NU1009).&lt;/p&gt;&lt;p&gt;&lt;img src="https://community.devexpress.com/blogs/news/image_12.png" alt=""&gt;&lt;br&gt;&lt;/p&gt;&lt;h2 id="additional-information"&gt;Solution #3: Await &amp;amp; Install a New/Fixed DevExpress Build&amp;nbsp;&lt;/h2&gt;&lt;div class="Note"&gt;&lt;strong&gt;Applicability&lt;/strong&gt;: Applications of any complexity targeting the&amp;nbsp;minimally&amp;nbsp;supported .NET version (like .NET 8), with or without CPM.&lt;br&gt;&lt;strong&gt;Urgency&lt;/strong&gt;: Low (await a few weeks).&lt;br&gt;&lt;strong&gt;Complexity&lt;/strong&gt;: Medium - Download a new version and re-test your application completely.&lt;br&gt;&lt;strong&gt;Risks&lt;/strong&gt;: Low - for the official maintenance update; High - for a hot-fix/intermediate build.&lt;/div&gt;&lt;p&gt;Affected DevExpress packages are typically updated in the next minor release according to our &lt;a href="https://docs.devexpress.com/GeneralInformation/403365/security/security?utm_source=SupportCenter&amp;amp;utm_medium=website&amp;amp;utm_campaign=docs-feedback&amp;amp;utm_content=T1326802#security-advisories-and-product-update-process"&gt;Security Advisories and Product Update Process&lt;/a&gt;. This usually takes a few weeks or so.&amp;nbsp;&lt;span&gt;If you wish, you can request a hot-fix/intermediate build as well. For example, for this particular System.Security.Cryptography.Xml vulnerability we updated our packages and published a fixed night build at&amp;nbsp;&lt;/span&gt;&lt;a href="https://downloads.devexpress.com/HotFixes/DXP/v25.2" style="color:#337ab7;"&gt;https://downloads.devexpress.com/HotFixes/DXP/v25.2&lt;/a&gt;&lt;span&gt;(review our&amp;nbsp;&lt;/span&gt;&lt;a href="https://www.devexpress.com/support/eulas/hotfix-policy.xml" style="color:#337ab7;"&gt;hot-fix policy&lt;/a&gt;&lt;span&gt;&amp;nbsp;first&amp;nbsp;before applying).&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:#333333;"&gt;.NET 8 is the minimally supported modern .NET / .NET Core version for DevExpress v25.2 and v26.1 NuGet libs.&amp;nbsp;Due to various reasons, we currently publish only a single .NET 8&amp;nbsp;package set, which is compatible with multiple .NET frameworks (.NET 9 and .NET 10).&lt;/span&gt;&lt;/p&gt;&lt;h3&gt;&lt;span style="color:#333333;"&gt;.NET 8-based Projects&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;&lt;span style="color:#333333;"&gt;&lt;strong&gt;If your project targets&amp;nbsp;&lt;/strong&gt;&lt;strong&gt;.NET 8&lt;/strong&gt;: our&amp;nbsp;&lt;/span&gt;&lt;span style="color:#333333;"&gt;DevExpress.Printing.Core (v25.2.7+) and other affected DevExpress packages will use a non-vulnerable&amp;nbsp;&lt;/span&gt;&lt;a href="https://www.nuget.org/packages/System.Security.Cryptography.Xml/" style="color:#337ab7;"&gt;System.Security.Cryptography.Xml&lt;/a&gt;&lt;span style="color:#333333;"&gt;&amp;nbsp;dependency (&amp;gt;= 8.0.3 for .NET 8) after the official fix &lt;strong&gt;automatically&lt;/strong&gt;. &lt;a href="https://docs.devexpress.com/GeneralInformation/2529/updates/project-converter" target="_blank"&gt;Once you upgrade&lt;/a&gt; your DevExpress dependencies, &lt;span&gt;the previous Solutions #1 or #2 (manual version pinning) are no longer required - remove them from your projects.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:#333333;"&gt;&lt;img src="https://community.devexpress.com/blogs/news/image_13.png" alt="" style="width:927px;height:873px;border-width:1px;border-color:#c0c0c0;border-style:solid;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;h3&gt;.NET 9/10-based Projects&lt;/h3&gt;&lt;p&gt;&lt;span style="color:#333333;"&gt;&lt;strong&gt;If your project targets .NET 9/10,&lt;/strong&gt; your solutions depend on the target project SDK and target framework:&lt;/span&gt;&lt;strong style="color:#333333;"&gt;&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong style="color:#333333;"&gt;&lt;a href="https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview#available-sdks" target="_blank"&gt;Microsoft.NET.Sdk&lt;/a&gt;&amp;nbsp;&lt;/strong&gt;&lt;span style="color:#333333;"&gt;(the base SDK for .NET without additional targets like&amp;nbsp;net10.0-windows):&amp;nbsp;&lt;strong&gt;Implement&amp;nbsp;&lt;/strong&gt;&lt;span&gt;&lt;strong&gt;the  Solutions #1 or #2&lt;/strong&gt; (manual version pinning), because they&amp;nbsp;are still&amp;nbsp;required and recommended &lt;span&gt;due to how NuGet resolution operates.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;How NuGet/IDE restores third-party dependencies or which versions are used eventually in your project on your target machine are out of DevExpress&amp;nbsp;control. NuGet has its own rules where in a dependency tree with multiple parents, the &amp;quot;lowest wins&amp;quot; for the target framework of your end app. For example, DevExpress path → System.Security.Cryptography.Xml (&amp;gt;= 8.0.0) and ServiceModel path → System.Security.Cryptography.Xml (&amp;gt;= 10.0.0), then the&amp;nbsp;&lt;span&gt;result for net10 is &amp;gt;= 10.0.0 → choose 10.0.0 - lowest.&amp;nbsp;&lt;/span&gt;&lt;p style="color:#333333;"&gt;When it comes to built-in .NET dependencies (a part of the distributed .NET runtime on your machine), another &amp;quot;framework&amp;quot; layer is also considered (see this&amp;nbsp;&lt;a href="https://community.devexpress.com/blogs/news/archive/2024/07/18/dot-net-nuget-package-audit-and-false-positive-security-warnings.aspx" style="color:#337ab7;"&gt;example situation&lt;/a&gt;). It&amp;#39;s even more interesting when it comes to your third-party dependencies, which are unique for each customer app - there will be numerous dependency trees with System.ServiceModel.Http, Microsoft.Identity.Web, and other libs, for which it will be necessary to find a common denominator or override package versions.&amp;nbsp;&lt;span&gt;Ultimately, third-party dependencies and .NET runtimes are unique for each customer app and environment - this falls under the responsibility of the app developer eventually.&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview#available-sdks" target="_blank"&gt;Microsoft.NET.Sdk.Web,&amp;nbsp;Microsoft.NET.Sdk.Razor&lt;/a&gt;, or&amp;nbsp;Microsoft.NET.Sdk +&amp;nbsp;net10.0-windows&lt;/strong&gt;: No manual action needed, because&amp;nbsp;&lt;span style="color:#333333;"&gt;the System.Security.Cryptography.Xml is correctly resolved to a non-vulnerable version from the SDK bundle&amp;nbsp;&lt;strong&gt;automatically&lt;/strong&gt;. This version&amp;nbsp;(for example, v10.0.9, not 9.0.15) is bundled in&amp;nbsp;your installed .NET 9/10 runtime for&amp;nbsp;your build environment/machine (of course,&amp;nbsp;&lt;/span&gt;&lt;span style="color:#333333;"&gt;if your .NET 9/10 is updated properly&lt;/span&gt;&lt;span style="color:#333333;"&gt;).&amp;nbsp;&lt;img src="https://community.devexpress.com/blogs/news/image_14.png" alt=""&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Frequently Asked Questions (FAQ)&lt;/h2&gt;&lt;h3&gt;Does DevExpress release builds when it already &amp;quot;knows&amp;quot; about a vulnerability such as System.Security.Cryptography.Xml 8.0.2?&lt;/h3&gt;&lt;p&gt;No. In this instance, DevExpress v25.2.6 was released on 07 Apr 2026, many days before the aforementioned vulnerability was even published/known to the world. &lt;/p&gt;&lt;p&gt;DevExpress uses a multi-layered scanning strategy for every PR (code repositories and container images are continuously and automatically scanned for vulnerabilities during the CI/CD process) &lt;strong&gt;prior to release&lt;/strong&gt;. This includes Static Application Security Testing (SAST) for product source code, Software Composition Analysis (SCA) for vulnerable third-party libraries/license compliance, antiviral software installation and artifact scanning. High-risk vulnerabilities trigger an automatic &amp;#39;Build Fail&amp;#39;. DevExpress employs a combination of commercial and internally managed security tools (including, but not limited to Veracode, Dependabot, CodeQL, NuGet Audit, VirusTotal, etc).&lt;/p&gt;&lt;p&gt;For more information, please review &lt;a href="https://www.devexpress.com/support/information-security.xml" style="color:#337ab7;"&gt;Information Security&lt;/a&gt; and &lt;a href="https://docs.devexpress.com/GeneralInformation/403365/security/security" style="color:#337ab7;"&gt;Security - What You Need to Know&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;How often similar security advisories for system/core or popular 3rd-party packages are reported?&lt;/h3&gt;&lt;p&gt;Quite many every day - it&amp;#39;s best to estimate it for yourself at &lt;a href="https://github.com/advisories" target="_blank"&gt;https://github.com/advisories&lt;/a&gt; (filter by NuGet, NPM, or other keywords). This is also not the first and not the last vulnerability in a system/core library. For example, 3 security advisories were published for System.Security.Cryptography.Xml alone in less than 2 years. And I am not even referring to others in popular SQL Client, JSON, OData, and other libraries with even more dependencies.&lt;/p&gt;&lt;p&gt;To better understand the situation, let&amp;#39;s make a thought experiment: imagine that a vendor started publishing new official builds in response to each and every security advisory immediately. For this (in theory), one would need the previous official build, bump the affected NuGet package version (such as System.Security.Cryptography.Xml), re-build, re-run automatic tests and security checks, and publish a new official build. As a result of this experiment, customers would need to deal with 3-5 new minors a week. That rough number is only considering the current CVE/GHSA update rate for .NET - for JS/NPM it would be even more frequent. As you may understand, not many customers or businesses would want such an update carousel.&lt;/p&gt;&lt;img src="https://community.devexpress.com/blogs/news/image_4.png" alt="" style="border-width:1px;border-color:#c0c0c0;border-style:solid;"&gt;&lt;h3&gt;How often DevExpress &amp;quot;bumps versions&amp;quot; of their .NET packages internally in response to security advisories for external NuGet packages?&lt;/h3&gt;&lt;p&gt;Multiple times every month or so. To give you a full picture, DevExpress v25.2 .NET packages depend on over 150+ system/core .NET packages (based on our &amp;quot;c:\Program Files\DevExpress 25.2\Components\Sources\Directory.Packages.props&amp;quot; file or our public &lt;a href="https://supportcenter.devexpress.com/ticket/details/t1312026/software-bill-of-materials-sbom-for-devexpress-net-assemblies-nuget-packages-javascript" target="_blank"&gt;SBOM artifacts&lt;/a&gt;, which you can check for yourself). Our .NET packages often include our JS packages as assets, these JS packages depend on external JS/NPM packages, and so on - you got the idea or the high chances of a &amp;quot;version bump&amp;quot; at such a scale.&lt;/p&gt;&lt;p&gt;Good news is that we heavily rely on CPM, so this &amp;quot;version bumping&amp;quot; itself is now a mechanical routine - it just takes time and discipline from our product teams. This is basically what every developer of any serious or complex application/solution is doing nowadays, because security matters.&lt;/p&gt;&lt;h3&gt;Why does not DevExpress release a new/fixed build within hours after a security advisory is published?&lt;/h3&gt;&lt;p&gt;As noted in Method #3, we follow our &lt;a href="https://docs.devexpress.com/GeneralInformation/403365/security/security#security-advisories-and-product-update-process" style="color:#337ab7;"&gt;Security Advisories and Product Update Process&lt;/a&gt; and update affected DevExpress packages  in the next minor release (in a few weeks or so &lt;strong&gt;on purpose&lt;/strong&gt;). All our builds must pass standard testing procedures. We do our best to test our software and it takes time (for example, we intentionally did not release v25.2.7 &amp;quot;within hours&amp;quot;). We simply do not want our customers rely on poorly tested software (and potentially experience bigger issues with the upgrade). &lt;/p&gt;&lt;p&gt;Fortunately, the current release cadence suits the majority of our customers and proved itself over the years well. In urgent cases, customers can either apply a one-line solution in their projects or request a hot-fix/intermediate build. That is also why Microsoft has Patch Tuesday &lt;strong style="color:#333333;"&gt;monthly &lt;/strong&gt;and NOT &amp;quot;hourly&amp;quot;, and many other vendors follow similar security and testing protocols. Otherwise, it would be a mess for all vendors and customers in the .NET ecosystem, for JS ecosystem it would be even worse due to a different NPM package update strategies and the number of updated packages. &lt;strong&gt;In other words, the solution should never be worse than the original problem.&lt;/strong&gt;&lt;/p&gt;&lt;h2 id="additional-information" style="color:#505050;font-weight:600;"&gt;See Also&lt;/h2&gt;&lt;p&gt;Microsoft clarified this general pattern in their blogs and docs, because this version upgrade is needed regularly:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://devblogs.microsoft.com/dotnet/nugetaudit-2-0-elevating-security-and-trust-in-package-management/#how-to-upgrade-transitive-packages" rel="nofollow"&gt;NuGetAudit 2.0: Elevating Security and Trust in Package Management&lt;/a&gt; (see the &amp;quot;How to upgrade transitive packages&amp;quot; section)&lt;/li&gt;&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management#overriding-package-versions" rel="nofollow"&gt;Overriding Package Versions&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;We also described how to fix this and similar customer issues at &lt;a href="https://community.devexpress.com/blogs/news/archive/2024/07/18/dot-net-nuget-package-audit-and-false-positive-security-warnings.aspx"&gt;.NET — About NuGet Package Audit and &amp;quot;False-Positive&amp;quot; Security Warnings&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Please let me know if you have any DevExpress-related questions or suggestions.&lt;/p&gt;&lt;p&gt;&lt;span&gt;Thanks,&lt;/span&gt;&lt;br&gt;&lt;span&gt;Dennis Garavsky&lt;/span&gt;&lt;br&gt;&lt;span&gt;Principal Product Manager&lt;/span&gt;&lt;br&gt;&lt;a href="mailto:dennis@devexpress.com" title="Email me if you have questions or suggestions"&gt;dennis@devexpress.com&lt;/a&gt;&lt;br&gt;&lt;/p&gt;</description>
      <pubDate>Fri, 24 Apr 2026 09:44:00 Z</pubDate>
      <dc:creator>Dennis Garavsky (DevExpress)</dc:creator>
    </item>
  </channel>
</rss>