<rss version="2.0">
  <channel>
    <title>Orchard Core</title>
    <link>http://crestapps.com/orchardcore</link>
    <description><![CDATA[]]></description>
    <item>
      <title>The AI Agent Skills</title>
      <link>http://crestapps.com/orchard-core/the-ai-agent-skills</link>
      <description><![CDATA[<h1 id="introducing-crestapps.agentskills-a-structured-foundation-for-ai-skills-in.net">Introducing CrestApps.AgentSkills: A Structured Foundation for AI Skills in .NET</h1>
<p>AI integration in .NET applications is evolving rapidly. But without structure, it can easily become a collection of scattered prompts, hardcoded tool calls, and tightly coupled logic.</p>
<p>The <strong>CrestApps.AgentSkills</strong> ecosystem provides a clean, layered architecture for defining, organizing, and exposing AI skills in .NET — with first-class support for the Model Context Protocol (MCP) and OrchardCore.</p>
<p>This post walks through the projects in the repository and explains how they fit together — based strictly on their actual structure and purpose.</p>
<hr />
<h2 id="crestapps.agentskills-the-foundation">1. CrestApps.AgentSkills — The Foundation</h2>
<p>At the core of the ecosystem is:</p>
<p><strong>CrestApps.AgentSkills</strong></p>
<p>This is the foundational .NET project that defines reusable AI skills and the infrastructure to work with them.</p>
<p>It provides:</p>
<ul>
<li>A structured way to define AI agent skills</li>
<li>Common abstractions for skill execution</li>
<li>A shared engine that other packages build upon</li>
</ul>
<p>This project is not OrchardCore-specific. It is designed for general .NET applications and acts as the base layer for everything else in the ecosystem.</p>
<p>If you are building AI-capable .NET applications and want a standardized way to define and organize skills, this is the starting point.</p>
<h3 id="installation">📦 Installation</h3>
<p>Using the .NET CLI:</p>
<pre><code class="language-bash">dotnet add package CrestApps.AgentSkills
</code></pre>
<p>Or using the Package Manager Console:</p>
<pre><code class="language-powershell">Install-Package CrestApps.AgentSkills
</code></pre>
<hr />
<h2 id="crestapps.agentskills.mcp-mcp-integration-for.net">2. CrestApps.AgentSkills.Mcp — MCP Integration for .NET</h2>
<p>Once skills are defined, they need to be discoverable and callable by external AI systems.</p>
<p>That is the role of:</p>
<p><strong>CrestApps.AgentSkills.Mcp</strong></p>
<p>This project integrates the core skill engine with the <strong>Model Context Protocol (MCP)</strong>.</p>
<p>It enables:</p>
<ul>
<li>Exposure of registered skills through MCP</li>
<li>Skill discovery by MCP-compatible clients</li>
<li>Invocation of .NET skills via protocol calls</li>
</ul>
<p>In practical terms, this allows your .NET application to act as an MCP server. External AI agents and tools that support MCP can inspect available skills and call them in a structured way.</p>
<p>This shifts AI integration from prompt-based guessing to protocol-driven interaction.</p>
<h3 id="installation-1">📦 Installation</h3>
<p>Using the .NET CLI:</p>
<pre><code class="language-bash">dotnet add package CrestApps.AgentSkills.Mcp
</code></pre>
<p>Or using the Package Manager Console:</p>
<pre><code class="language-powershell">Install-Package CrestApps.AgentSkills.Mcp
</code></pre>
<blockquote>
<p><strong>Note:</strong> This package depends on <code>CrestApps.AgentSkills</code> and will install it automatically if it is not already referenced.</p>
</blockquote>
<hr />
<h2 id="crestapps.agentskills.orchardcore-orchardcore-specific-skills">3. CrestApps.AgentSkills.OrchardCore — OrchardCore-Specific Skills</h2>
<p>For developers working with OrchardCore, the repository includes:</p>
<p><strong>CrestApps.AgentSkills.OrchardCore</strong></p>
<p>This project extends the core skill engine with OrchardCore-specific functionality.</p>
<p>It provides:</p>
<ul>
<li>OrchardCore-aware skill definitions</li>
<li>Extensions tailored to CMS concepts</li>
<li>Conventions for working with OrchardCore entities and structures</li>
</ul>
<p>While the base package works for any .NET application, this project brings domain knowledge specific to OrchardCore into the skill system.</p>
<p>It enables AI skills that understand OrchardCore constructs rather than treating the CMS as a generic application.</p>
<h3 id="installation-2">📦 Installation</h3>
<p>Using the .NET CLI:</p>
<pre><code class="language-bash">dotnet add package CrestApps.AgentSkills.OrchardCore
</code></pre>
<p>Or using the Package Manager Console:</p>
<pre><code class="language-powershell">Install-Package CrestApps.AgentSkills.OrchardCore
</code></pre>
<blockquote>
<p><strong>Note:</strong> This package requires an OrchardCore application and depends on <code>CrestApps.AgentSkills</code>.</p>
</blockquote>
<hr />
<h2 id="crestapps.agentskills.mcp.orchardcore-orchardcore-mcp-runtime">4. CrestApps.AgentSkills.Mcp.OrchardCore — OrchardCore MCP Runtime</h2>
<p>Finally, the ecosystem includes:</p>
<p><strong>CrestApps.AgentSkills.Mcp.OrchardCore</strong></p>
<p>This package combines:</p>
<ul>
<li>OrchardCore-specific skills</li>
<li>MCP server capabilities</li>
</ul>
<p>It allows a running OrchardCore application to expose its skills through MCP at runtime.</p>
<p>With this in place, an OrchardCore instance can:</p>
<ul>
<li>Publish its available skills</li>
<li>Respond to MCP calls from external agents</li>
<li>Participate in a broader AI tooling ecosystem</li>
</ul>
<p>This creates a bridge between a live CMS environment and AI agents that can interact with it programmatically.</p>
<h3 id="installation-3">📦 Installation</h3>
<p>Using the .NET CLI:</p>
<pre><code class="language-bash">dotnet add package CrestApps.AgentSkills.Mcp.OrchardCore
</code></pre>
<p>Or using the Package Manager Console:</p>
<pre><code class="language-powershell">Install-Package CrestApps.AgentSkills.Mcp.OrchardCore
</code></pre>
<blockquote>
<p><strong>Note:</strong> This package depends on:</p>
<ul>
<li><code>CrestApps.AgentSkills</code></li>
<li><code>CrestApps.AgentSkills.Mcp</code></li>
<li><code>CrestApps.AgentSkills.OrchardCore</code></li>
</ul>
</blockquote>
<p>All dependencies will be installed automatically by NuGet.</p>
<hr />
<h2 id="how-the-projects-fit-together">How the Projects Fit Together</h2>
<p>The ecosystem is layered by design:</p>
<ol>
<li><p><strong>CrestApps.AgentSkills</strong><br />
Core engine for defining and executing AI skills in .NET.</p>
</li>
<li><p><strong>CrestApps.AgentSkills.Mcp</strong><br />
Adds MCP protocol support to expose skills externally.</p>
</li>
<li><p><strong>CrestApps.AgentSkills.OrchardCore</strong><br />
Adds OrchardCore-specific skill definitions.</p>
</li>
<li><p><strong>CrestApps.AgentSkills.Mcp.OrchardCore</strong><br />
Hosts OrchardCore skills through MCP at runtime.</p>
</li>
</ol>
<p>Each project builds directly on the previous layer, creating a clean separation of concerns.</p>
<hr />
<h2 id="why-this-architecture-matters">Why This Architecture Matters</h2>
<p>This ecosystem enables:</p>
<ul>
<li>Structured AI skill definitions instead of ad-hoc prompts</li>
<li>Reusable skills across multiple projects</li>
<li>Protocol-based integration using MCP</li>
<li>Domain-aware AI capabilities for OrchardCore</li>
<li>Runtime exposure of application capabilities to AI agents</li>
</ul>
<p>For .NET developers, this means moving from experimental AI integrations to maintainable, discoverable, and extensible AI systems.</p>
<hr />
<h2 id="final-thoughts">Final Thoughts</h2>
<p>The CrestApps.AgentSkills ecosystem provides a practical foundation for building AI-capable .NET and OrchardCore applications using structured skills and the Model Context Protocol.</p>
<p>Instead of embedding AI logic directly into application code in an ad-hoc way, you get:</p>
<ul>
<li>A reusable skill engine</li>
<li>A protocol bridge for external agents</li>
<li>Domain-specific extensions</li>
<li>A runtime hosting model</li>
</ul>
<p>If you're building AI-driven .NET systems — especially with OrchardCore — this architecture offers a clean and scalable approach.</p>
]]></description>
      <pubDate>Tue, 24 Feb 2026 05:38:48 GMT</pubDate>
      <guid isPermaLink="true">http://crestapps.com/orchard-core/the-ai-agent-skills</guid>
    </item>
    <item>
      <title>Enhancing OrchardCore AI with the Model Context Protocol (MCP)</title>
      <link>http://crestapps.com/orchard-core/enhancing-orchardcore-ai-with-the-model-context-protocol-mcp</link>
      <description><![CDATA[<p>Artificial Intelligence has come a long way — from simple autocomplete suggestions to powerful, conversational agents. But here’s the catch: even the smartest AI model can’t read your mind.</p>
<p><strong>Context is everything.</strong></p>
<p>Give an LLM a vague prompt, and you’ll get a vague response. But give it <strong>rich, structured, real-time context</strong> — and it becomes capable of surprising intelligence.</p>
<p>That’s the promise behind the <strong>Model Context Protocol (MCP)</strong> — and now, thanks to the <strong>CrestApps MCP Module</strong>, this power is available directly inside your OrchardCore applications.</p>
<p>Whether you're building a chatbot, a content assistant, or a smart dashboard, this new module makes it easy to extend AI behavior by plugging in external tools, services, and even your own backend logic — all without reinventing the wheel.</p>
<p>Let’s explore how MCP is changing the game for AI integrations and how you can get started today.</p>
<hr />
<h2 id="what-is-model-context-protocol-mcp-and-why-its-a-game-changer">🤖 What is Model Context Protocol (MCP) and Why It’s a Game Changer</h2>
<p>At its core, <strong>MCP is a simple but powerful idea</strong>: what if there was a universal way for AI models to talk to external systems?</p>
<p>Think of it like the <strong>USB-C for AI</strong>. With USB-C, you can connect your laptop to power, displays, or storage — no matter the brand. MCP works the same way for AI: it defines a standard protocol that lets large language models connect to <strong>tools</strong>, <strong>data</strong>, and <strong>services</strong>, no matter where they live.</p>
<h3 id="so-what-does-mcp-actually-enable">So, what does MCP actually enable?</h3>
<ul>
<li>🧩 <strong>Pluggable Tools</strong>: Attach prebuilt tools like <code>mcp/time</code>, <code>mcp/calc</code>, or <code>mcp/shell</code> that run locally or in containers.</li>
<li>🌐 <strong>Real-Time Context</strong>: Provide your AI with live data from internal APIs, databases, or system commands.</li>
<li>🧠 <strong>Cross-Model Compatibility</strong>: Use the same tools across OpenAI, Ollama, Claude, and more.</li>
<li>🔒 <strong>Privacy &amp; Control</strong>: Run tools locally or behind your firewall — no need to send data to the cloud.</li>
</ul>
<p>It’s not just about better responses — it’s about making AI <strong>feel integrated</strong> into your app’s ecosystem, aware of your user, your data, and your environment.</p>
<blockquote>
<p>Learn more: <a href="https://modelcontextprotocol.io/introduction">modelcontextprotocol.io/introduction</a></p>
</blockquote>
<hr />
<h2 id="extending-orchardcore-ai-with-mcp">🧩 Extending OrchardCore AI with MCP</h2>
<p>With the CrestApps AI Chat module, you already have a great foundation for building AI-powered experiences in OrchardCore. You can create profiles, hook into your preferred LLM provider, and start chatting with your model right away.</p>
<p>But let’s imagine a common scenario.</p>
<hr />
<h3 id="real-world-example-why-static-ai-isnt-enough">🧪 Real-World Example: Why Static AI Isn’t Enough</h3>
<p>Let’s say you’ve created an AI profile that connects to your favorite LLM provider — great! Now you type something like:</p>
<blockquote>
<p><em>“What is the current time in Bethlehem, Palestine?”</em></p>
</blockquote>
<p>The model, however, responds with:</p>
<blockquote>
<p><em>“I’m not sure — I don’t have access to real-time data.”</em></p>
</blockquote>
<p>That’s because most language models — even the smartest ones — aren’t connected to the real world. They’re like extremely well-read introverts: lots of knowledge, no access to what’s happening right now.</p>
<p>This is where <strong>MCP comes to the rescue.</strong></p>
<p>By connecting your OrchardCore AI profile to a <strong>remote or local MCP server</strong> — such as one that runs the <code>mcp/time</code> tool — your AI gains the ability to fetch <strong>real-time timezone information</strong>. The server does the lookup, returns the current time for Palestine, and the model weaves it into its answer naturally.</p>
<p>It feels like magic — but it’s just <strong>structured context delivered through MCP.</strong></p>
<hr />
<h2 id="getting-started-with-the-crestapps-mcp-module">⚙️ Getting Started with the CrestApps MCP Module</h2>
<p>The <code>CrestApps.OrchardCore.AI.Mcp</code> module extends the AI Chat capabilities by allowing your OrchardCore site to interact with MCP servers via:</p>
<ul>
<li>🌐 <strong>Remote MCP Servers</strong> using <strong>Server-Sent Events (SSE)</strong></li>
<li>🖥 <strong>Local MCP Tools</strong> via <strong>Standard Input/Output (Stdio)</strong></li>
</ul>
<p>To get started:</p>
<ol>
<li>Install the <code>CrestApps.OrchardCore.AI.Mcp</code> NuGet package in your web project.</li>
<li>In the OrchardCore dashboard, go to <strong>Tools → Features</strong></li>
<li>Enable one or both of:
<ul>
<li><code>Model Context Protocol (MCP) Client</code></li>
<li><code>Model Context Protocol (Local MCP) Client</code></li>
</ul>
</li>
</ol>
<hr />
<h2 id="connecting-to-a-remote-mcp-server-sse-transport">🌐 Connecting to a Remote MCP Server (SSE Transport)</h2>
<p>You can integrate any external MCP Server using <strong>Server-Sent Events (SSE)</strong>, a lightweight, real-time communication method.</p>
<h3 id="step-by-step">🛠 Step-by-Step:</h3>
<ol>
<li>Go to <strong>Artificial Intelligence → MCP Connections</strong></li>
<li>Click <strong>Add Connection</strong></li>
<li>Under <strong>SSE Source</strong>, click <strong>Add</strong></li>
<li>Fill in details like:</li>
</ol>
<pre><code>Display Text: Remote AI Time Server
Endpoint: https://localhost:1234/
Additional Headers: (optional)
</code></pre>
<ol start="5">
<li>Click <strong>Save</strong></li>
</ol>
<p>🎯 Then go to <strong>AI Profiles</strong> and create a new profile using this connection.</p>
<hr />
<h3 id="alternative-recipe-based-setup-for-remote-server">🧾 Alternative: Recipe-Based Setup for Remote Server</h3>
<p>You can also define the connection via a recipe file:</p>
<pre><code class="language-json">{
  &quot;steps&quot;: [
    {
      &quot;name&quot;: &quot;McpConnection&quot;,
      &quot;connections&quot;: [
        {
          &quot;DisplayText&quot;: &quot;Remote AI Tools&quot;,
          &quot;Properties&quot;: {
            &quot;SseMcpConnectionMetadata&quot;: {
              &quot;Endpoint&quot;: &quot;https://localhost:1234/&quot;,
              &quot;AdditionalHeaders&quot;: {}
            }
          }
        }
      ]
    }
  ]
}
</code></pre>
<p>This is handy for multi-tenant solutions, automation, or CI/CD pipelines.</p>
<hr />
<h2 id="using-the-local-mcp-client-stdio-transport">🖥 Using the Local MCP Client (Stdio Transport)</h2>
<p>Want your AI to work <strong>offline</strong> or integrate with <strong>local tools</strong>? Use the <code>Local MCP Client</code>, which runs tools via standard input/output — especially useful with Dockerized tools like:</p>
<ul>
<li>🕒 <code>mcp/time</code> (returns current time with time zone awareness)</li>
<li>➕ <code>mcp/calc</code> (evaluates math)</li>
<li>🖥 <code>mcp/shell</code> (secure command runner)</li>
</ul>
<hr />
<h3 id="example-use-mcptime-via-docker">🧭 Example: Use <code>mcp/time</code> via Docker</h3>
<h4 id="step-1-install-docker-desktop">Step 1: Install Docker Desktop</h4>
<p>Download and install Docker Desktop if you haven't already.</p>
<h4 id="step-2-pull-the-image">Step 2: Pull the Image</h4>
<pre><code class="language-bash">docker pull mcp/time
</code></pre>
<h4 id="step-3-add-the-connection-in-orchardcore">Step 3: Add the Connection in OrchardCore</h4>
<ul>
<li>Go to <strong>AI → MCP Connections</strong></li>
<li>Click <strong>Add Connection</strong></li>
<li>Choose <strong>Stdio Source</strong> and click <strong>Add</strong></li>
<li>Enter:</li>
</ul>
<pre><code>Display Text: Global Time Capabilities
Command: docker
Arguments: [&quot;run&quot;, &quot;-i&quot;, &quot;--rm&quot;, &quot;mcp/time&quot;]
</code></pre>
<p>Click <strong>Save</strong>, and you’re ready to create a profile that uses this connection.</p>
<hr />
<h3 id="recipe-based-setup-for-local-tools">🧾 Recipe-Based Setup for Local Tools</h3>
<p>Prefer automation? Here's how to configure the same connection via a recipe:</p>
<pre><code class="language-json">{
  &quot;steps&quot;: [
    {
      &quot;name&quot;: &quot;McpConnection&quot;,
      &quot;connections&quot;: [
        {
          &quot;DisplayText&quot;: &quot;Global Time Capabilities&quot;,
          &quot;Properties&quot;: {
            &quot;StdioMcpConnectionMetadata&quot;: {
              &quot;Command&quot;: &quot;docker&quot;,
              &quot;Arguments&quot;: [
                &quot;run&quot;,
                &quot;-i&quot;,
                &quot;--rm&quot;,
                &quot;mcp/time&quot;
              ]
            }
          }
        }
      ]
    }
  ]
}
</code></pre>
<hr />
<h2 id="more-creative-use-cases">🧠 More Creative Use Cases</h2>
<p>Once MCP is connected, you can get creative with your AI tooling. Here are a few ideas:</p>
<ul>
<li><p>🧮 <strong>Natural Language Calculator</strong> with <code>mcp/calc</code><br />
Evaluate math queries like “What’s 25% of 480?”</p>
</li>
<li><p>📂 <strong>File Search Assistant</strong> using <code>mcp/shell</code><br />
Help users locate files on disk using AI-generated search commands.</p>
</li>
<li><p>🕵️ <strong>Internal Monitoring Bot</strong><br />
Connect to internal logs, status scripts, or diagnostic tools.</p>
</li>
</ul>
<p>All of these can be exposed to your AI model using MCP’s consistent, secure protocol.</p>
<hr />
<h2 id="where-to-find-mcp-compatible-tools">🌎 Where to Find MCP-Compatible Tools</h2>
<p>MCP is growing fast. Explore these hubs for tools and servers:</p>
<ul>
<li><a href="https://hub.docker.com/search?q=mcp&amp;type=image">Docker Hub: MCP Tools</a></li>
<li><a href="https://mcp.so">MCP.so</a></li>
<li><a href="https://glama.ai">Glama.ai</a></li>
<li><a href="https://mcpservers.org">MCPServers.org</a></li>
</ul>
<hr />
<h2 id="wrapping-up">✅ Wrapping Up</h2>
<p>The <strong>Model Context Protocol</strong> is redefining how AI applications get their context — and with the <strong>CrestApps MCP Module</strong>, that power is now available to OrchardCore developers with minimal setup and maximum flexibility.</p>
<p>Whether you're looking to <strong>add intelligence to your CMS</strong>, build <strong>AI-powered assistants</strong>, or just give your model access to real-world data — MCP offers a clean, scalable, and secure path forward.</p>
<blockquote>
<p>Want to try it? 👉 <a href="https://github.com/CrestApps/CrestApps.OrchardCore/tree/main/src/Modules/CrestApps.OrchardCore.AI.Mcp#readme">Get started with the CrestApps MCP Module</a></p>
</blockquote>
<hr />
<p>Let me know if you'd like the Markdown version for publishing or want to add a diagram or code demo!</p>
]]></description>
      <pubDate>Mon, 14 Apr 2025 17:08:57 GMT</pubDate>
      <guid isPermaLink="true">http://crestapps.com/orchard-core/enhancing-orchardcore-ai-with-the-model-context-protocol-mcp</guid>
    </item>
    <item>
      <title>Extending AI Models with Custom Functions in Orchard Core</title>
      <link>http://crestapps.com/orchard-core/extending-ai-models-with-custom-functions-in-orchard-core</link>
      <description><![CDATA[<h1 id="extending-ai-models-with-custom-functions-in-orchard-core">Extending AI Models with Custom Functions in Orchard Core</h1>
<p>Artificial Intelligence (AI) is revolutionizing web applications by providing dynamic, intelligent interactions. In <strong>Orchard Core</strong>, AI capabilities can be extended beyond basic interactions by implementing <strong>custom functions</strong> that provide tailored responses and actions. This guide will walk you through extending AI models with functions using the <strong>CrestApps.OrchardCore.AI</strong> package.</p>
<hr />
<h2 id="why-extend-ai-models-with-custom-functions">Why Extend AI Models with Custom Functions?</h2>
<p>AI models provide a strong foundation for chatbot interactions, but often, applications require specialized logic to fetch external data, perform calculations, or integrate with third-party services. By creating <strong>custom functions</strong>, developers can extend the AI's capabilities while keeping control over its behavior.</p>
<p>Some use cases for extending AI models with functions include:</p>
<ul>
<li><strong>Retrieving real-time data</strong> (e.g., weather, stock prices, news updates).</li>
<li><strong>Integrating with APIs</strong> (e.g., CRM, inventory systems, support tickets).</li>
<li><strong>Performing complex computations</strong> (e.g., financial calculations, analytics processing).</li>
</ul>
<hr />
<h2 id="creating-a-custom-ai-function">Creating a Custom AI Function</h2>
<p>The <strong>CrestApps.OrchardCore.AI</strong> package allows you to register custom functions that AI profiles can call when interacting with users. Here’s how you can create a simple function to fetch weather information based on a user’s location.</p>
<h3 id="step-1-define-the-function">Step 1: Define the Function</h3>
<p>To create a custom AI function, inherit from <code>AIFunction</code> and override its behavior:</p>
<pre><code class="language-csharp">public sealed class GetWeatherFunction : AIFunction
{
    private const string _locationProperty = &quot;Location&quot;;
    public const string TheName = &quot;get_weather&quot;;

    public GetWeatherFunction()
    {
        Name = TheName;
        Description = &quot;Retrieves weather information for a specified location.&quot;;

        var metadata = new JsonObject()
        {
            {&quot;type&quot;, &quot;object&quot;},
            {&quot;properties&quot;, new JsonObject()
                {
                    { _locationProperty, new JsonObject()
                        {
                            {&quot;type&quot;, &quot;string&quot; },
                            {&quot;description&quot;, &quot;The geographic location for which the weather information is requested.&quot; },
                        }
                    }
                }
            },
            {&quot;required&quot;, new JsonArray(_locationProperty)},
            {&quot;return_type&quot;, new JsonObject()
                {
                    {&quot;type&quot;, &quot;string&quot;},
                    {&quot;description&quot;, &quot;The weather condition at the specified location.&quot;},
                }
            },
        };

        JsonSchema = JsonSerializer.Deserialize&lt;JsonElement&gt;(metadata);
    }

    public override string Name { get; }

    public override string Description { get; }

    public override JsonElement JsonSchema { get; }

    protected override Task&lt;object&gt; InvokeCoreAsync(IEnumerable&lt;KeyValuePair&lt;string, object&gt;&gt; arguments, CancellationToken cancellationToken)
    {
        var prompt = arguments.First(x =&gt; x.Key == _locationProperty).Value;

        string location = null;

        if (prompt is JsonElement jsonElement)
        {
            location = jsonElement.GetString();
        }
        else if (prompt is JsonNode jsonNode)
        {
            location = jsonNode.ToJsonString();
        }
        else if (prompt is string str)
        {
            location = str;
        }
        else
        {
            location = prompt?.ToString();
        }

        var weather = Random.Shared.NextDouble() &gt; 0.5 ? $&quot;It's sunny in {location}.&quot; : $&quot;It's raining in {location}.&quot;;

        return Task.FromResult&lt;object&gt;(weather);
    }
}
</code></pre>
<h3 id="step-2-register-the-function">Step 2: Register the Function</h3>
<p>To make the function available in your AI setup, register it as a service in your <strong>Startup</strong> class:</p>
<pre><code class="language-csharp">services.AddAITool&lt;GetWeatherFunction&gt;(GetWeatherFunction.Name, options =&gt;
{
    options.Title = &quot;Weather Getter&quot;;
    options.Description = &quot;Retrieves weather information for a specified location.&quot;;
});
</code></pre>
<p>This ensures that the AI service can access and use your custom function when processing user requests.</p>
<hr />
<h2 id="using-custom-functions-in-ai-profiles">Using Custom Functions in AI Profiles</h2>
<p>Once a function is registered, it can be used in AI profiles to extend chatbot capabilities.</p>
<ol>
<li><strong>Navigate to the AI Profiles Section</strong> in the Orchard Core dashboard.</li>
<li><strong>Create or edit an existing AI profile</strong>.</li>
<li><strong>Enable the custom function</strong> in the function list.</li>
<li><strong>Test the function</strong> to ensure it responds correctly.</li>
</ol>
<p>This allows AI-powered chatbots and automation workflows to utilize external data and provide smarter responses.</p>
<hr />
<h2 id="example-use-case-ai-driven-customer-support">Example Use Case: AI-Driven Customer Support</h2>
<p>Consider a scenario where a chatbot needs to provide real-time shipping status updates. By creating a custom function that fetches shipment details from an API, the AI can offer instant support to customers.</p>
<p>Example function:</p>
<pre><code class="language-csharp">public sealed class GetShippingStatusFunction : AIFunction
{
    private const string _trackingNumberProperty = &quot;TrackingNumber&quot;;
    public const string TheName = &quot;get_shipping_status&quot;;

    public GetShippingStatusFunction()
    {
        Name = TheName;
        Description = &quot;Retrieves the current status of a shipment.&quot;;

        var metadata = new JsonObject()
        {
            {&quot;type&quot;, &quot;object&quot;},
            {&quot;properties&quot;, new JsonObject()
                {
                    { _trackingNumberProperty, new JsonObject()
                        {
                            {&quot;type&quot;, &quot;string&quot; },
                            {&quot;description&quot;, &quot;The tracking number of the shipment.&quot; },
                        }
                    }
                }
            },
            {&quot;required&quot;, new JsonArray(_trackingNumberProperty)},
            {&quot;return_type&quot;, new JsonObject()
                {
                    {&quot;type&quot;, &quot;string&quot;},
                    {&quot;description&quot;, &quot;The current shipment status.&quot;},
                }
            },
        };

        JsonSchema = JsonSerializer.Deserialize&lt;JsonElement&gt;(metadata);
    }

    public override string Name { get; }

    public override string Description { get; }

    public override JsonElement JsonSchema { get; }

    protected override async Task&lt;object&gt; InvokeCoreAsync(IEnumerable&lt;KeyValuePair&lt;string, object&gt;&gt; arguments, CancellationToken cancellationToken)
    {
        var prompt = arguments.First(x =&gt; x.Key == _trackingNumberProperty).Value;

        string trackingNumber = prompt?.ToString();
        string status = await FetchShippingStatusFromAPI(trackingNumber);

        return status;
    }

    private async Task&lt;string&gt; FetchShippingStatusFromAPI(string trackingNumber)
    {
        await Task.Delay(500);
        return $&quot;Shipment {trackingNumber} is in transit.&quot;;
    }
}
</code></pre>
<p>Register the function as before and integrate it into your AI profile. Now, the chatbot can provide instant tracking updates!</p>
<hr />
<h2 id="conclusion">Conclusion</h2>
<p>Extending AI models with <strong>custom functions</strong> in <strong>Orchard Core</strong> enables developers to create more intelligent, data-driven chatbots and applications. By implementing and registering functions tailored to your needs, you can:</p>
<ul>
<li>Integrate AI with external APIs and data sources.</li>
<li>Customize responses for specific business needs.</li>
<li>Enhance chatbot functionalities with real-time insights.</li>
</ul>
<p>Start extending your AI models today and unlock the full potential of AI-driven interactions in Orchard Core!</p>
<hr />
<h2 id="additional-resources">Additional Resources</h2>
<ul>
<li><a href="https://github.com/CrestApps/CrestApps.OrchardCore">CrestApps.OrchardCore.AI Repository</a></li>
<li><a href="https://docs.orchardcore.net/">Orchard Core Documentation</a></li>
</ul>
]]></description>
      <pubDate>Thu, 06 Mar 2025 01:20:56 GMT</pubDate>
      <guid isPermaLink="true">http://crestapps.com/orchard-core/extending-ai-models-with-custom-functions-in-orchard-core</guid>
    </item>
    <item>
      <title>Integrating AI Features into Your Orchard Core Project: A Guide for .NET Developers</title>
      <link>http://crestapps.com/orchard-core/integrating-ai-features-into-your-orchard-core-project-a-guide-for-net-developers</link>
      <description><![CDATA[<h1 id="integrating-ai-into-orchard-core-with-crestapps">Integrating AI into Orchard Core with CrestApps</h1>
<p>Artificial Intelligence (AI) is transforming how web applications are developed and interacted with. As a .NET developer working with Orchard Core, you can enhance your applications by incorporating AI-driven functionalities. In this guide, we’ll walk you through integrating AI features into Orchard Core CMS using the <strong>CrestApps.OrchardCore.AI</strong> package and its implementations.</p>
<hr />
<h2 id="prerequisites">Prerequisites</h2>
<p>Before you begin, ensure you have the following:</p>
<ul>
<li>An <strong>Orchard Core CMS</strong> project set up and running.</li>
<li>A basic understanding of <strong>NuGet</strong> and <strong>Orchard Core’s module system</strong>.</li>
<li>Access to <strong>Azure OpenAI</strong>, <strong>DeepSeek</strong>, or another supported AI provider.</li>
</ul>
<hr />
<h2 id="step-1-install-the-ai-services-module">Step 1: Install the AI Services Module</h2>
<p>The <strong>AI Services</strong> module provides the foundational infrastructure for AI integration in Orchard Core.</p>
<h3 id="installation-steps-with-user-interface">Installation Steps (With User Interface)</h3>
<ol>
<li>Open your Orchard Core web project in Visual Studio or your preferred IDE.</li>
<li>Install the <strong>CrestApps.OrchardCore.AI.Chat</strong> package using NuGet:
<pre><code class="language-bash">Install-Package CrestApps.OrchardCore.AI.Chat
</code></pre>
</li>
<li>Once installed, a new <strong>Artificial Intelligence</strong> menu item will appear in Orchard Core, along with a <strong>Profiles</strong> submenu.</li>
</ol>
<h5 id="here-is-a-sneek-peak-of-the-chat-ui-using-the-backend">Here is a sneek peak of the Chat-UI using the backend</h5>
<p>&lt;img src=&quot;https://github.com/CrestApps/CrestApps.OrchardCore/blob/main/docs/images/admin-ui-sample.gif&quot; class=&quot;img-fluid&quot; alt=&quot;AI Chat using the OrchardCore's backend&quot; /&gt;</p>
<h5 id="here-is-a-sneek-peak-of-the-chat-ui-using-the-frontend-widget">Here is a sneek peak of the Chat-UI using the frontend Widget</h5>
<p>&lt;img src=&quot;https://github.com/CrestApps/CrestApps.OrchardCore/blob/main/docs/images/admin-ui-sample.gif&quot; class=&quot;img-fluid&quot; alt=&quot;AI Chat using the OrchardCore's frontend widget&quot; /&gt;</p>
<h3 id="installation-steps-with-no-user-interface">Installation Steps (With no User Interface)</h3>
<ol>
<li>Open your Orchard Core web project in Visual Studio or your preferred IDE.</li>
<li>Install the <strong>CrestApps.OrchardCore.AI</strong> package using NuGet:
<pre><code class="language-bash">Install-Package CrestApps.OrchardCore.AI
</code></pre>
</li>
<li>Once installed, a new <strong>Artificial Intelligence</strong> menu item will appear in Orchard Core, along with a <strong>Profiles</strong> submenu.</li>
</ol>
<hr />
<h2 id="step-2-understanding-ai-profiles">Step 2: Understanding AI Profiles</h2>
<p>An <strong>AI Profile</strong> defines how the chatbot interacts with users. The module supports three profile types:</p>
<ul>
<li><strong>Chat</strong>: A fully interactive chatbot for multi-turn conversations.</li>
<li><strong>Utility</strong>: Provides one-time responses, useful for workflow automation.</li>
<li><strong>Template Generated Prompt</strong>: Uses <strong>Liquid syntax</strong> to create dynamic prompts, ideal for content summarization and structured responses.</li>
</ul>
<p>You can configure AI Profiles within the Orchard Core Dashboard to customize chatbot behavior according to your needs.</p>
<hr />
<h2 id="step-3-choose-your-ai-implementation">Step 3: Choose Your AI Implementation</h2>
<p>The <strong>CrestApps.OrchardCore.AI</strong> module is flexible and supports multiple AI providers, including:</p>
<ul>
<li><strong>Azure OpenAI</strong></li>
<li><strong>DeepSeek</strong></li>
<li><strong>OpenAI</strong></li>
<li><strong>Ollama</strong> (for local testing)</li>
<li><strong>Azure AI Inference</strong></li>
</ul>
<p>Below, we explore the primary implementations and their configurations.</p>
<h3 id="azure-openai-integration">Azure OpenAI Integration</h3>
<h4 id="install-the-module">Install the Module</h4>
<p>Use NuGet to install the Azure OpenAI module:</p>
<pre><code class="language-bash">Install-Package CrestApps.OrchardCore.OpenAI.Azure
</code></pre>
<h4 id="configure-azure-openai">Configure Azure OpenAI</h4>
<p>Modify <code>appsettings.json</code> to establish a connection with Azure OpenAI:</p>
<pre><code class="language-json">{
  &quot;OrchardCore&quot;: {
    &quot;CrestApps_AI&quot;: {
      &quot;Providers&quot;: {
        &quot;Azure&quot;: {
          &quot;DefaultConnectionName&quot;: &quot;your-connection-name&quot;,
          &quot;DefaultDeploymentName&quot;: &quot;your-deployment-name&quot;,
          &quot;Connections&quot;: {
            &quot;your-connection-name&quot;: {
              &quot;Endpoint&quot;:&quot;https://&lt;!-- Your Azure Resource Name --&gt;.openai.azure.com/&quot;,
              &quot;AuthenticationType&quot;: &quot;ApiKey&quot;,
              &quot;ApiKey&quot;:&quot;&lt;!-- API Key to connect to your Azure AI instance --&gt;&quot;,
              &quot;DefaultDeploymentName&quot;: &quot;the default deployment name for this connection&quot;
            }
          }
        }
      }
    }
  }
}
</code></pre>
<h4 id="enable-azure-openai-features">Enable Azure OpenAI Features</h4>
<ol>
<li>Enable the <strong>Azure OpenAI Chat</strong> feature in the Orchard Core Dashboard.</li>
<li>Create an AI Profile and select <strong>Azure OpenAI</strong> as the provider.</li>
<li>If using <strong>Chat with Your Data</strong>, configure <strong>Azure AI Search</strong> for custom datasets.</li>
</ol>
<p>With Azure OpenAI, you can create intelligent chatbots, automate customer support, and enhance user interactions effortlessly.</p>
<hr />
<h3 id="openai-integration">OpenAI Integration</h3>
<h4 id="install-the-module-1">Install the Module</h4>
<pre><code class="language-bash">Install-Package CrestApps.OrchardCore.OpenAI
</code></pre>
<h4 id="configure-openai">Configure OpenAI</h4>
<p>Configure the settings using any settings provider. To configure the service with DeepSeek credentials using <code>appsettings.json</code>:</p>
<pre><code class="language-json">{
  &quot;OrchardCore&quot;: {
    &quot;CrestApps_AI&quot;: {
      &quot;Providers&quot;: {
        &quot;OpenAI&quot;: {
          &quot;DefaultConnectionName&quot;: &quot;openai-cloud&quot;,
          &quot;DefaultDeploymentName&quot;: &quot;gpt-4o-mini&quot;,
          &quot;Connections&quot;: {
            &quot;openai-cloud&quot;: {
              &quot;ApiKey&quot;: &quot;your-openai-api-key&quot;,
              &quot;DefaultDeploymentName&quot;: &quot;gpt-4o-mini&quot;,
            }
          }
        }
      }
    }
  }
}
</code></pre>
<p>To obtain an API key, visit the <a href="https://platform.openai.com/">OpenAI Platform</a>.</p>
<h4 id="enable-openai-in-orchard-core">Enable OpenAI in Orchard Core</h4>
<ol>
<li>Enable <strong>OpenAI Chat</strong> feature in the Orchard Core Dashboard.</li>
<li>Navigate to <strong>Artificial Intelligence &gt; Profiles</strong> and create a new AI Profile.</li>
<li>Select <strong>OpenAI</strong> as the AI provider, configure the settings, and save.</li>
</ol>
<p>Once set up, your DeepSeek AI chatbot will be available in Orchard Core.</p>
<h4 id="deepseek-integration">DeepSeek Integration</h4>
<p>The AI module allows seamless integration with any provider that follows OpenAI standards. DeepSeek is one such provider, offering an API compatible with OpenAI. This compatibility enables effortless connection using OpenAI's interface. First be sure to following &quot;OpenAI Integration&quot; section above. Then to configure the settings using any settings provider. To configure the service with DeepSeek credentials using <code>appsettings.json</code>:</p>
<pre><code class="language-json">{
  &quot;OrchardCore&quot;: {
    &quot;CrestApps_AI&quot;: {
      &quot;Providers&quot;: {
        &quot;OpenAI&quot;: {
          &quot;DefaultConnectionName&quot;: &quot;deepseek-cloud&quot;,
          &quot;DefaultDeploymentName&quot;: &quot;deepseek-chat&quot;,
          &quot;Connections&quot;: {
            &quot;deepseek&quot;: {
              &quot;Endpoint&quot;: &quot;https://api.deepseek.com/v1&quot;,
              &quot;ApiKey&quot;: &quot;your-deepseek-api-key&quot;,
              &quot;DefaultDeploymentName&quot;: &quot;deepseek-chat&quot;
            }
          }
        }
      }
    }
  }
}
</code></pre>
<hr />
<h3 id="other-ai-implementations">Other AI Implementations</h3>
<p>CrestApps also provides implementations for:</p>
<ul>
<li><strong>Azure AI Inference</strong></li>
<li><strong>Ollama</strong> (for local testing)</li>
</ul>
<p>You may look at the documentation in the repository for more info: <a href="https://github.com/CrestApps/CrestApps.OrchardCore">https://github.com/CrestApps/CrestApps.OrchardCore</a></p>
<hr />
<h3 id="managing-provider-connections">Managing Provider Connections</h3>
<p>The AI module includes an <strong>AI Connection Management</strong> feature that allows you to manage provider connections through the user interface at the tenant level, instead of relying on the <code>appsettings.json</code> file, which applies to all tenants.</p>
<p>To get started, first enable the <strong>AI Connection Management</strong> feature, then follow these steps:</p>
<h4 id="enabling-ai-connection-management">Enabling AI Connection Management</h4>
<ol>
<li>In the Orchard Core Dashboard, enable the <strong>AI Connection Management</strong> feature.</li>
<li>Navigate to <strong>Artificial Intelligence &gt; Connections</strong> and create a new provider connection.</li>
<li>Choose your preferred provider, configure the necessary settings, and save.</li>
</ol>
<p>Once set up, the connection will be available for use with any of your AI profiles.</p>
<hr />
<h2 id="extending-ai-models-with-custom-functions-in-orchard-core">Extending AI Models with Custom Functions in Orchard Core</h2>
<p>Want to see how easy it is to add custom functions? <a href="https://crestapps.com/orchard-core/extending-ai-models-with-custom-functions-in-orchard-core">Click here</a> to read the full article.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Integrating AI into Orchard Core is now easier than ever with the <strong>CrestApps AI</strong> package. Whether you opt for <strong>Azure OpenAI</strong> for enterprise-grade AI services or <strong>DeepSeek</strong> for flexible AI interactions, you can enhance your CMS with intelligent chatbot solutions and AI-driven workflows.</p>
<p>By following this guide, you can quickly configure AI services in Orchard Core and unlock innovative functionalities for your applications. Start exploring AI capabilities today and transform how users interact with your platform!</p>
<hr />
<h2 id="additional-resources">Additional Resources</h2>
<ul>
<li><a href="https://github.com/CrestApps/CrestApps.OrchardCore/">CrestApps GitHub</a></li>
<li><a href="https://crestapps.com/orchard-core/extending-ai-models-with-custom-functions-in-orchard-core">Extending AI Models with Custom Functions</a></li>
<li><a href="https://docs.orchardcore.net/">Orchard Core Documentation</a></li>
<li><a href="https://learn.microsoft.com/en-us/azure/ai-services/openai/">Azure OpenAI Documentation</a></li>
<li><a href="https://platform.deepseek.com">DeepSeek Platform</a></li>
<li><a href="https://platform.openai.com/">OpenAI Platform</a></li>
</ul>
]]></description>
      <pubDate>Fri, 07 Mar 2025 22:05:48 GMT</pubDate>
      <guid isPermaLink="true">http://crestapps.com/orchard-core/integrating-ai-features-into-your-orchard-core-project-a-guide-for-net-developers</guid>
    </item>
    <item>
      <title>Unlocking the Power of DeepSeek with C# and .NET</title>
      <link>http://crestapps.com/orchard-core/unlocking-the-power-of-deepseek-with-c-and-net</link>
      <description><![CDATA[<p>Artificial Intelligence (AI) is transforming the way we build software, and DeepSeek is at the forefront of this revolution. As a C# or .NET developer, you now have the tools to seamlessly integrate cutting-edge AI capabilities into your applications. In this blog post, we’ll explore what DeepSeek is, how it can benefit developers, and how you can interact with it using C#.</p>
<hr />
<h2 id="what-is-deepseek">What is DeepSeek?</h2>
<p>DeepSeek is a powerful AI platform that provides developers with access to advanced language models, enabling them to build intelligent applications with ease. Whether you’re looking to enhance your app with natural language processing, reasoning capabilities, or conversational AI, DeepSeek has you covered.</p>
<p>What sets DeepSeek apart is its compatibility with OpenAI’s API standards, making it incredibly easy for developers to integrate into their existing workflows. With DeepSeek, you can leverage state-of-the-art AI models like <code>deepseek-chat</code> and <code>deepseek-reasoner</code> to create smarter, more responsive applications.</p>
<hr />
<h2 id="how-can-we-benefit-from-it">How Can We Benefit from It?</h2>
<p>DeepSeek empowers developers to build AI-driven features without needing to dive deep into the complexities of machine learning. Here are some ways you can benefit from using DeepSeek:</p>
<ol>
<li><strong>Enhanced User Experiences</strong>: Integrate conversational AI into your apps to provide users with intuitive, natural language interactions.</li>
<li><strong>Improved Productivity</strong>: Automate repetitive tasks like code generation, documentation, or data analysis using AI-powered tools.</li>
<li><strong>Cost-Effective AI Solutions</strong>: DeepSeek offers competitive pricing and flexible models, making advanced AI accessible to developers of all levels.</li>
<li><strong>OpenAI Compatibility</strong>: If you’re already familiar with OpenAI’s API, integrating DeepSeek into your projects will feel like second nature.</li>
</ol>
<p>By leveraging DeepSeek, you can focus on building innovative features while leaving the heavy lifting of AI to the platform.</p>
<hr />
<h2 id="how-can-we-interact-with-it-using-c">How Can We Interact with It Using C#?</h2>
<p>Thanks to Microsoft’s efforts, interacting with AI services like DeepSeek is incredibly straightforward. If you’re a C# developer, you can use the <code>Microsoft.Extensions.AI.OpenAI</code> library to interact with DeepSeek’s API. Here’s how you can get started:</p>
<h3 id="step-1-create-an-api-key">Step 1: Create an API Key</h3>
<p>To begin, you’ll need an API key from DeepSeek. Visit <a href="https://platform.deepseek.com/api_keys">https://platform.deepseek.com/api_keys</a>, create an account, and generate a new API key.</p>
<h3 id="step-2-install-the-required-nuget-package">Step 2: Install the Required NuGet Package</h3>
<p>Install the <code>Microsoft.Extensions.AI.OpenAI</code> package using the NuGet Package Manager or run the following command in the Package Manager Console:</p>
<pre><code class="language-bash">Install-Package Microsoft.Extensions.AI.OpenAI
</code></pre>
<h3 id="step-3-set-up-the-chat-client">Step 3: Set Up the Chat Client</h3>
<p>Once you’ve installed the package, you can create a chat client to interact with DeepSeek’s models. Here’s an example of how to set it up:</p>
<pre><code class="language-csharp">private IChatClient GetChatClient(string apiKey, string modelId)
{
    var client = new OpenAIClient(new ApiKeyCredential(apiKey), new OpenAIClientOptions()
    {
        Endpoint = new Uri(&quot;https://api.deepseek.com/v1&quot;),
    });

    var builder = new ChatClientBuilder(client.AsChatClient(modelId));

    if (modelId != &quot;deepseek-reasoner&quot;)
    {
        // The 'deepseek-reasoner' model does not support tool calling.
        builder.UseFunctionInvocation(null, (r) =&gt;
        {
            // Set the maximum number of iterations per request to 1 to prevent infinite function calling.
            r.MaximumIterationsPerRequest = 1;
        });
    }

    return builder.Build();
}
</code></pre>
<h3 id="step-4-call-the-deepseek-api">Step 4: Call the DeepSeek API</h3>
<p>With the chat client set up, you can now call the DeepSeek API to generate responses. Here’s an example:</p>
<pre><code class="language-csharp">var chatClient = GetChatClient(&quot;your-api-key&quot;, &quot;deepseek-chat&quot;);

var prompts = new List&lt;ChatMessage&gt;
{
    new(ChatRole.User, &quot;What is Orchard Core?&quot;),
};

var result = await chatClient.CompleteAsync(prompts);

foreach (var choice in result.Choices)
{
    Console.WriteLine(choice.Text);
}
</code></pre>
<h3 id="supported-models">Supported Models</h3>
<p>As of this blog post, DeepSeek supports two models:</p>
<ul>
<li><strong><code>deepseek-chat</code></strong>: Ideal for conversational AI and natural language interactions.</li>
<li><strong><code>deepseek-reasoner</code></strong>: Designed for more complex reasoning tasks.</li>
</ul>
<hr />
<h2 id="unlock-the-power-of-ai-in-your.net-project-using-orchardcore-cms">Unlock the Power of AI in Your .NET Project Using OrchardCore CMS</h2>
<p>Looking for an easy way to integrate AI into your ASP.NET project using the amazing OrchardCore CMS? Visit <a href="https://crestapps.com/orchard-core/integrating-ai-features-into-your-orchard-core-project-a-guide-for-net-developers">Integrating AI Features into Your Orchard Core Project: A Guide for .NET Developers</a> for a step-by-step guide to unlocking the power of AI in your own .NET project.</p>
<h2 id="its-that-simple">It’s That Simple!</h2>
<p>Integrating DeepSeek into your C# and .NET applications is a breeze, thanks to its compatibility with OpenAI’s API standards and the <code>Microsoft.Extensions.AI.OpenAI</code> library. Whether you’re building a chatbot, automating tasks, or enhancing your app with AI, DeepSeek provides the tools you need to succeed.</p>
]]></description>
      <pubDate>Fri, 07 Feb 2025 23:52:00 GMT</pubDate>
      <guid isPermaLink="true">http://crestapps.com/orchard-core/unlocking-the-power-of-deepseek-with-c-and-net</guid>
    </item>
    <item>
      <title>The Orchard Core Journey </title>
      <link>http://crestapps.com/orchard-core/the-orchard-core-journey</link>
      <description><![CDATA[<h1 id="are-you-an-asp.net-mvc-developer-looking-to-learn-orchard-core">Are you an ASP.NET MVC Developer Looking to Learn Orchard Core?</h1>
<p>In this series of posts, I’ll guide you through key concepts in Orchard Core, helping you understand how to excel as an Orchard Core developer. We'll compare how things are done in a standard MVC project and how to achieve the same results using Orchard Core. By the end of the series, you should be comfortable with Orchard Core's unique concepts and how to navigate its UI.</p>
<hr />
<h2 id="create-read-update-and-delete-crud-operations-from-an-mvc-developers-perspective">Create, Read, Update, and Delete (CRUD) Operations from an MVC Developer's Perspective</h2>
<p>CRUD operations are essential in any application. In an ASP.NET MVC app, we typically:</p>
<ol>
<li>Create a model to represent the data.</li>
<li>Define actions for each operation (Create, Read, Update, Delete).</li>
<li>Add views and view-models for each action.</li>
</ol>
<h3 id="example-creating-a-person-model">Example: Creating a Person Model</h3>
<p>For instance, let's assume we want to build a small app to capture basic information about people. We would start by creating a <code>Person</code> model like this:</p>
<pre><code class="language-csharp">public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Biography { get; set; }
    public string AddressLine1 { get; set; }
    public string AddressLine2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string PostalCode { get; set; }
}
</code></pre>
<p>Next, we add actions (such as <code>Create</code>, <code>Edit</code>, <code>Delete</code>) to the <code>PersonController</code> and create the corresponding views and view-models.</p>
<h4 id="example-personviewmodel">Example: <code>PersonViewModel</code></h4>
<p>To allow users to select a state from a dropdown, we might create a view-model:</p>
<pre><code class="language-csharp">public class PersonViewModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Biography { get; set; }
    public string AddressLine1 { get; set; }
    public string AddressLine2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string PostalCode { get; set; }

    // A collection to render a list of states the user can select from.
    [BindNever]
    public IEnumerable&lt;SelectListItem&gt; States { get; set; }
}
</code></pre>
<p>Creating and maintaining such an app can be time-consuming. Now, let’s explore how to achieve the same functionality using Orchard Core.</p>
<hr />
<h2 id="content-types-in-orchard-core">Content Types in Orchard Core</h2>
<p>A foundational element of Orchard Core is <strong>content types</strong>. These are customizable data structures that define how content is organized and displayed. Content types allow you to create different kinds of content, such as blog posts, pages, or products, with specific fields and behaviors.</p>
<p>Think of a <strong>model class</strong> in standard development as a <strong>Content Type</strong> in Orchard Core, and each property of the class as a <strong>Content Field</strong>.</p>
<h3 id="creating-a-content-type-in-orchard-core">Creating a Content Type in Orchard Core</h3>
<p>To create a <code>Person</code> content type:</p>
<ol>
<li>Ensure the <strong>Content Types</strong> feature is enabled.</li>
<li>In the dashboard, go to <strong>Content</strong> → <strong>Content Types</strong>.</li>
<li>Click <strong>Add</strong> to create a new content type.</li>
<li>Name it <code>Person</code> (the technical name will be generated automatically).</li>
</ol>
<p>Once created, you can edit the content type and add fields to it.</p>
<hr />
<h2 id="content-fields">Content Fields</h2>
<p>In Orchard Core, we use <strong>content fields</strong> to define the data we want to collect. To add fields to the <code>Person</code> content type:</p>
<ol>
<li>Enable the <strong>Content Fields</strong> feature (if not already enabled).</li>
<li>Navigate to the <strong>Person</strong> content type and click <strong>Edit</strong>.</li>
<li>Add the necessary fields (e.g., <code>FirstName</code>, <code>LastName</code>, <code>Biography</code>, etc.) by selecting the appropriate field types (e.g., <code>TextField</code> for string data).</li>
</ol>
<p>For a detailed list of available content fields, check out the <a href="https://docs.orchardcore.net/en/latest/reference/modules/ContentFields/#available-fields">Orchard Core Documentation on Content Fields</a>.</p>
<hr />
<h2 id="content-items">Content Items</h2>
<p>In a standard MVC app, once we create a model class, we instantiate it and save it to the database. In Orchard Core, the equivalent of a model instance is a <strong>content item</strong>.</p>
<p>To create a content item:</p>
<ol>
<li>Ensure the <strong>Contents</strong> feature is enabled.</li>
<li>In the dashboard, go to <strong>Content</strong> → <strong>Content Items</strong>.</li>
<li>Click the <strong>Add</strong> button and select the <code>Person</code> content type.</li>
<li>Fill out the form with the data and click <strong>Publish</strong>.</li>
</ol>
<p>This process completes the basic CRUD operation in Orchard Core, which is simple and elegant.</p>
<hr />
<h2 id="configuring-content-fields">Configuring Content Fields</h2>
<p>If the default field appearance doesn’t meet your needs, you can configure the field settings. For example:</p>
<ul>
<li>Make a field <strong>required</strong>.</li>
<li>Change a field to a <strong>dropdown</strong> or <strong>multi-line</strong> input.</li>
</ul>
<h3 id="configuring-the-firstname-field-as-required">Configuring the <code>FirstName</code> Field as Required</h3>
<p>To make the <code>FirstName</code> field required:</p>
<ol>
<li>Go to <strong>Content</strong> → <strong>Content Types</strong>.</li>
<li>Edit the <code>Person</code> content type.</li>
<li>In the fields section, click <strong>Edit</strong> next to <code>FirstName</code>.</li>
<li>Check the <strong>Required</strong> box and save the changes.</li>
</ol>
<p>Now, if you try to publish a content item without providing a first name, Orchard Core will show an error message.</p>
<hr />
<h2 id="field-editors">Field Editors</h2>
<p>Field editors allow you to change the way data is captured in the UI. For example:</p>
<ul>
<li>The <code>TextField</code> can have different editors, such as <strong>single-line</strong>, <strong>multi-line</strong>, or a <strong>picklist</strong>.</li>
</ul>
<h3 id="changing-the-biography-field-editor">Changing the Biography Field Editor</h3>
<ol>
<li>Go to the <strong>Biography</strong> field in the <code>Person</code> content type.</li>
<li>Change the editor to <strong>Multi-Line</strong> and save the settings.</li>
</ol>
<p>Similarly, you can change the <code>State</code> field editor to <strong>PickList</strong>, allowing users to select from predefined values.</p>
<hr />
<h2 id="content-parts-reusable-data-structures">Content Parts: Reusable Data Structures</h2>
<p>What if your business needs change? For example, you might want to create a <code>Customer</code> content type that only requires <code>FirstName</code> and <code>LastName</code> but not the address fields. Instead of adding these fields manually to each content type, you can use <strong>content parts</strong>.</p>
<p>A <strong>content part</strong> is a reusable set of fields. For instance, you could create a <code>PersonInfoPart</code> containing <code>FirstName</code> and <code>LastName</code> and attach it to multiple content types (e.g., <code>Person</code>, <code>Employee</code>, <code>Customer</code>).</p>
<h3 id="creating-a-content-part">Creating a Content Part</h3>
<ol>
<li>Go to <strong>Content</strong> → <strong>Content Parts</strong>.</li>
<li>Click <strong>Add</strong> and name the part <code>PersonInfoPart</code>.</li>
<li>Add <code>FirstName</code> and <code>LastName</code> fields and configure them as required.</li>
<li>Save the content part.</li>
</ol>
<p>Now, to attach this part to the <code>Person</code> content type, simply:</p>
<ol>
<li>Edit the <code>Person</code> content type.</li>
<li>Remove the existing <code>FirstName</code> and <code>LastName</code> fields.</li>
<li>Under <strong>Fields</strong>, click <strong>Add Part</strong> and select <code>PersonInfoPart</code>.</li>
<li>Save the changes.</li>
</ol>
<p>Now, you have a reusable part that can be attached to any content type. If you modify the part, the changes will be reflected across all content types it’s attached to.</p>
<h3 id="making-content-parts-reusable">Making Content Parts Reusable</h3>
<p>By checking the <strong>Reusable</strong> checkbox when creating a content part, you allow it to be attached multiple times to the same content type. This is useful if, for example, you need to capture both an employee’s and their spouse’s information.</p>
<hr />
<h2 id="conclusion">Conclusion</h2>
<p>In this post, we learned about <strong>Content Types</strong>, <strong>Content Fields</strong>, and <strong>Content Parts</strong> in Orchard Core. We covered how to use these components, configure them, and navigate the UI to create a simple CRUD application.</p>
<p>If you found this post helpful, please share it to help others discover Orchard Core!</p>
]]></description>
      <pubDate>Thu, 06 Mar 2025 00:16:44 GMT</pubDate>
      <guid isPermaLink="true">http://crestapps.com/orchard-core/the-orchard-core-journey</guid>
    </item>
  </channel>
</rss>