Back to "ASP के साथ HTMX"

This is a viewer only at the moment see the article on how this works.

To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk

This is a preview from the server running through my markdig pipeline

ASP.NET Core HTMX HTMX.NET Web Development

ASP के साथ HTMX

Friday, 28 November 2025

परिचय

यदि आपने पारंपरिक ASP निर्मित किया है, तो आप समस्या को जानते हैं। अनुभव करना आधुनिक

सर्वर से आंशिक एचटीएमएल खंडों को वापस करने की तकनीक और उन्हें डोम में बदलने के लिए यह हल करता है - और यह नहीं है'नई है XMLHttpRequest. क्या changed is how अलंकृत यह HTMX के साथ हो गया है

हम जो कर रहे हैं उसे करने के लिए HTMX हमें एक घोषणात्मक तरीका देता है।

अनुषंगी अनुच्छेद इस लेख में ASP पर ध्यान केंद्रित है। एचटीएमएस एक्सटेंशनों का एक Whistle-stop टूर और ASP के साथ HTMX का उपयोग.

इस लेख में HTMX ASP के साथ सुंदर रूप से एकीकृत करता है कैसे मैं दिखाता हूँ HTMX.NET लाइब्रेरी इसे और बेहतर बनाता है mostlylucid.pagingtaghelper पैकेज HTMX का उपयोग करता है और न्यूनतम कॉन्फ़िगरेशन के साथ शक्तिशाली पृष्ठांकन उपलब्ध कराता है

यह दृष्टिकोण फ्रेमवर्क है।

क्या है HTMX?

HTMX एक लाइब्रेरी है जो आपको जावास्क्रिप्ट लिखने के बजाय HTML से सीधे आधुनिक ब्राउज़र सुविधाओं तक पहुँच देता है।

कुंजी विशेषताओं को आप सबसे अधिक प्रयोग करेंगे

  • hx-get, hx-post, hx-put, hx-delete - HTTP अनुरोध करें
  • hx-target - निर्दिष्ट करें जहाँ प्रतिक्रिया डालना है
  • hx-swap नियंत्रण कैसे विषयवस्तु swapped किया जाता है
  • hx-trigger - परिभाषित करें कि क्या अनुरोध को ट्रिगर करता है
  • hx-push-url - ब्राउज़र यूआरएल को पूरा पृष्ठ पुनः लोड किए बिना अद्यतन करें

यहाँ-'-इसकी सुंदरता है। :-आप-'-आप अभी भी सर्वर लिख रहे हैं।

एक पैटर्न जो स्वयं AJAX के रूप में पुराना है

से पहले HTMX, हम काफी अधिक समारोह के साथ एक ही प्रभाव प्राप्त किया।

// jQuery circa 2010
$('#load-more').click(function() {
    $.ajax({
        url: '/posts/page/' + currentPage,
        success: function(html) {
            $('#posts-container').append(html);
            currentPage++;
        }
    });
});

और इससे पहले भी

// Vanilla JS circa 2005
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && xhr.status === 200) {
        document.getElementById('content').innerHTML = xhr.responseText;
    }
};
xhr.open('GET', '/partial-content', true);
xhr.send();

सर्वर---साइड पैटर्न एक ही था. . -- return HTML fragments- ,- swap them into the DOM- HTMX just moves this logic from JavaScript to HTML attributes.

ASP.NET विकासकर्ता वर्षों से ऐसा कर रहे हैं PartialView() पहले दिन से एमवीसी में Html.RenderAction() कम्पोसेबल टुकड़ों के लिए - क्षमता हमेशा वहाँ रही है

व्यापक उद्योग भी इन पैटर्नों को पुनः खोज रहा है।

ASP.NET कोर में HTMX सेटअप करना

पहला, अपने सजावट में HTMX को शामिल करें. आप एक सीडीएन का उपयोग कर सकते हैं या इसे स्थानीय रूप से सेवा कर सकते है

<script src="https://unpkg.com/[email protected]"></script>

यह है कि-' यह है-. कोई निर्माण चरण नहीं-M SK2 कोई npm इंस्टॉल नहीं है। , कोई वेब पैक कॉन्फ़िगरेशन नहीं।

Alpine.js: क्लाइंट

क्लाइंट के लिए-साइड रिआक्टिविटी |( |देखाता है | / | अवयवों को छुपाता है एल्पीन HTMX पूर्ण रूप से संपूरित करता है. केवल M SK1KB gzipped, यह बिना ब्लॉट के वीयू उपलब्ध कराता है

<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"></script>

यह है कैसे वे एक साथ काम करते हैं

<div x-data="{ open: false }">
    <button x-on:click="open = !open">Toggle</button>
    <div x-show="open" x-transition>
        <button hx-get="/api/data" hx-target="#results">Load Data</button>
    </div>
</div>

Alpine स्थानीय यूआई ह्यान्डल करता है ( टगल करता है), एचटीएमएस सर्वर कॉल का ह्याण्डल करता हैं & #44; (\डेटा फ़ैच करता है।

HTMX.NET लाइब्रेरी

खलीद अबुहाकमे's HTMX.NET लाइब्रेरी प्रथम ऍसपी0 वर्ग ASP Htmx और Htmx.TagHelpers NuGet पैकेजों, यह नेट के लिए मूल feels and makes working with HTMX an absolute pleasure जिटहब.

संस्थापन

dotnet add package Htmx
dotnet add package Htmx.TagHelpers

अपने _ViewImports.cshtml:

@addTagHelper *, Htmx.TagHelpers

IsHtmx() विस्तार विधि

सबसे उपयोगी विशेषता है Request.IsHtmx() विस्तार विधि, जो आपको बताता है कि क्या अनुरोध HTMX से आया था

[HttpGet]
public async Task<IActionResult> Index(int page = 1, int pageSize = 20)
{
    var posts = await blogViewService.GetPagedPosts(page, pageSize);

    if (Request.IsHtmx())
        return PartialView("_BlogSummaryList", posts);

    return View("Index", posts);
}

यह पैटर्न बिल्कुल चमकीला है

  • पूरा पृष्ठ लोड करता है (जब उपयोगकर्ता सीधे नेविगेट या ताज़ा करते हैं
  • आंशिक अद्यतन जब HTMX अनुरोध करता है

कोई अलग API अंतबिंदु नहीं

एक सामान्य गलत धारणा बहुत से ASP.NET विकासकर्ताओं को लगता है कि आप की जरूरत है _ उपसर्ग (सदृश _BlogSummaryList.cshtmlआंशिक रेंडरिंग प्राप्त करने के लिए ) PartialView() विधि स्वयं ASP कहता है .NET Core लेआउट को छोड़ने के लिए कहती है return PartialView("SearchResults", model) एक नियमित दृश्य फ़ाइल के साथ और यह पूरी तरह से काम करता है। अभिप्रेत आंशिक रूप में

HTMX.NET टैग मददगार

HTMX.NET टैग सहायक प्रदान करता है जो नियंत्रकों के साथ काम करने को स्वच्छ बनाता है

<button
    hx-controller="Comment"
    hx-action="GetCommentForm"
    hx-post
    hx-target="#commentform">
    Reply
</button>

यह ASP का उपयोग करके सही रूट उत्पन्न करता है।

यहाँ यह एक वास्तविक उदाहरण है इस ब्लॉग से

<button
    class="btn btn-outline btn-sm mb-4"
    hx-action="Comment"
    hx-controller="Comment"
    hx-post
    hx-vals
    x-on:click.prevent="window.mostlylucid.comments.setValues($event)"
    hx-on="htmx:afterSwap: window.scrollTo({top: 0, behavior: 'smooth'})"
    hx-swap="outerHTML"
    hx-target="#commentform">
    Comment
</button>

ध्यान दें कि HTMX Alpine के साथ कैसे अच्छा खेलता हैx-on:click.preventग्राहक के उन आकस्मिक बिटों के लिए )

अन्य HTMX.NET सहायक

लाइब्रेरी को भी उपलब्ध कराता है

  • Request.IsHtmxNonBoosted() - जाँचें कि क्या यह HTMX निवेदन है लेकिन नहीं बढ़ाया
  • Request.IsHtmxRefresh() - जाँचें कि क्या यह एक इतिहास बहाल अनुरोध है
  • HTMX शीर्षिकाओं के लिए प्रतिक्रिया सहायक

Real-World Example: Search with Partials

यहाँ इस ब्लॉग से खोज नियंत्रक है

[HttpGet]
[OutputCache(Duration = 3600, VaryByHeaderNames = new[] { "hx-request", "pagerequest" })]
public async Task<IActionResult> Search(
    string? query,
    int page = 1,
    int pageSize = 10,
    [FromHeader] bool pagerequest = false)
{
    var searchModel = await BuildSearchModel(query, page, pageSize);

    if (pagerequest && Request.IsHtmx())
        return PartialView("_SearchResultsPartial", searchModel.SearchResults);

    if (Request.IsHtmx())
        return PartialView("SearchResults", searchModel);

    return View("SearchResults", searchModel);
}

तीन परिदृश्यों के लिए तीन वापसी पथ

  1. पृष्ठांकन अनुरोध - न्यूनतम आंशिक | ( | सिर्फ परिणाम सूची |)
  2. फ़िल्टर परिवर्तन - अनुभाग आंशिक
  3. प्रत्यक्ष नेविगेशन - पूरा पृष्ठ (लेआउट + सब कुछ

आंशिक दृश्य (_SearchResultsPartial.cshtmlपेजिंग टैग मददगार का उपयोग करता है

@model Mostlylucid.Models.Blog.PostListViewModel
<div class="pt-2" id="content">
    @if (Model.Data?.Any() is true)
    {
        <div class="inline-flex w-full items-center justify-center pb-4">
            @if (Model.TotalItems > Model.PageSize)
            {
                <pager
                    x-ref="pager"
                    link-url="@Model.LinkUrl"
                    hx-boost="true"
                    hx-target="#content"
                    hx-swap="show:none"
                    page="@Model.Page"
                    page-size="@Model.PageSize"
                    total-items="@Model.TotalItems"
                    hx-headers='{"pagerequest": "true"}'>
                </pager>
            }
        </div>
        @foreach (var post in Model.Data)
        {
            <partial name="_ListPost" model="post"/>
        }
    }
</div>

पेजर टैग मददगार को तोड़ना

  • hx-boost="true" - लिंक को अवरोधित करता है
  • hx-target="#content" - जहां प्रतिक्रिया इंजेक्शन करना है
  • hx-headers='{"pagerequest": "true"}' मनपसंद हेडर नियंत्रक को बताता है यह
  • नियंत्रक जाँच करता है Request.IsHtmx() && pagerequest सिर्फ न्यूनतम आंशिक वापस करने के लिए

mostlylucid.pagingtaghelper पैकेज

मैंने लिखा mostlylucid.pagingtaghelper बार-बार पृष्ठांकन कोड से बचने के लिए

संस्थापन

dotnet add package mostlylucid.pagingtaghelper

जोड़ें _ViewImports.cshtml:

@addTagHelper *, mostlylucid.pagingtaghelper

मुख्य विशेषताएँ

क्रियान्वयन IPagingModel<T> और आप कर रहे हैं

public class BasePagingModel<T> : IPagingModel<T> where T : class
{
    public int Page { get; set; }
    public int TotalItems { get; set; }
    public int PageSize { get; set; }
    public string LinkUrl { get; set; }
    public List<T> Data { get; set; }
}

क्या आप प्राप्त कर रहे हैं

  • शून्य विन्यास आवश्यक है
  • बहुविध यूआई फ्रेमवर्क (TailwindCSS
  • अँधेरे मोड समर्थन
  • बनाए गए भाषाएँ
  • क्रमबद्ध शीर्षिका, पृष्ठ आकार चयनक
  • प्रगतिशील वृद्धि (जावास्क्रिप्ट के बिना काम करता है
  • नोएसक्यूएल डाटाबेस के लिए जारी टोकन समर्थन

टैग मददगार लिंक उत्पन्न करता है जो क्वेरी स्ट्रिंगों को सुरक्षित रखता है, अनुकूल शीर्षिकाओं को समर्थन देता है

एचटीएमएस प्रवाह रेखाचित्र

यहाँ यह है कि पूरी प्रणाली कैसे एक साथ फिट करता है

graph TB
    A[Browser] -->|"Initial page load"| B[Controller Action]
    B -->|"Request.IsHtmx() = false"| C[Return Full View]
    C --> D[Render Layout + Partial]

    A -->|"User clicks pagination/filter"| E[HTMX Request]
    E -->|"hx-get with headers"| F[Same Controller Action]
    F -->|"Request.IsHtmx() = true"| G{Check Headers}
    G -->|"pagerequest header"| H[Return Minimal Partial]
    G -->|"No special header"| I[Return Section Partial]

    H --> J[Swap Content in Target]
    I --> J

    J -->|"User clicks another link"| E

    style B stroke:#333,stroke-width:2px
    style F stroke:#333,stroke-width:2px
    style C stroke:#0066cc,stroke-width:2px
    style H stroke:#00cc66,stroke-width:2px
    style I stroke:#00cc66,stroke-width:2px

अन्य फ्रेमवर्कों से तुलना

जंगो टेम्प्लेट खण्ड

Django ने संस्करण में उचित आंशिक टेम्प्लेट रेंडरिंग जोड़ा 6.0 | ( | दिसम्बर |2024) | टेम्पलेट खंडों के साथ | МSK3 | इससे पहले | , | Django डेवलपर्स आमतौर पर सम्मिलन टैग या तृतीयक का प्रयोग करते थे | m- | django जैसे पार्टी पैकेज |M- |render |m- |block | . | ASP | M. | Net Core के पास PartialView() संस्करण से 1.0 में | 2016 | \ - | भिन्न फ्रेमवर्क |, | अलग समयरेखा | МSK4 | लेकिन एक ही गंतव्य

रेल टर्बरो फ्रेम

रुबी पर रेलों में टर्बो फ्रेम है (Hotwire का एक भाग है), जो भावना में समान है

<%= turbo_frame_tag "posts" do %>
  <%= render @posts %>
<% end %>

अंतर यह है कि टर्बो को अनुरोध और प्रतिक्रिया दोनों पर विशिष्ट फ्रेम मार्कर की आवश्यकता होती है hx-target.

Phoenix LiveViewGenericName

एलिक्सर' Phoenix LiveView स्थायी वेबसॉकेट कनेक्शन और सर्वर के साथ एक अलग दृष्टिकोण लेता है

def handle_event("load_more", _params, socket) do
  {:noreply, assign(socket, posts: load_more_posts())}
end

लाइवव्यू वास्तविक अनुप्रयोगों के लिए उत्कृष्ट है।

निष्पादन विचार

आउटपुट कैशिंग: OutputCache गुण द्वारा भिन्न होता है hx-request शीर्षिका, पूरी पृष्ठों और भागों को अलग से कैशिंग

[OutputCache(Duration = 3600, VaryByHeaderNames = new[] { "hx-request", "pagerequest" })]

नेटवर्क दक्षतासर्वर

बंडल आकार: HTMX

उन्नत पैटर्न

आशावादी यूआई अद्यतन Instant feedback के लिए HTMX और Alpine को जोड़ें

<div x-data="{ count: @Model.CommentCount }">
    <button hx-post="/comment/like" x-on:click="count++" hx-on::after-request="count = $event.detail.xhr.response">
        Likes: <span x-text="count"></span>
    </button>
</div>

गणना तुरंत अद्यतन करता है (optimistic), फिर सर्वर प्रतिक्रिया के साथ समन्वयित करता है

आउट---of---Band Swaps एक प्रतिक्रिया से कई पृष्ठ खंड अद्यतन करें

<div id="main-content"><!-- Main response --></div>
<div id="notification-count" hx-swap-oob="true"><span>5 new</span></div>

अधिसूचना बैगों के लिए उपयुक्त है। HTMX के साथ टॉस्ट और स्वापिंग दिखा रहा है.

वेब एपीआई के साथ क्लाइंट कभी-कभी आप एक मध्य के लिए चाहते हैं क्लाइंट आपको ठीक से यह करने देता है

<script src="https://unpkg.com/[email protected]/client-side-templates.js"></script>
<script src="https://unpkg.com/mustache@latest"></script>

<div hx-ext="client-side-templates">
    <template id="post-template" type="text/mustache">
        {{#posts}}
        <div class="post">
            <h3>{{title}}</h3>
            <p>{{excerpt}}</p>
        </div>
        {{/posts}}
    </template>

    <button hx-get="/api/posts"
            hx-target="#post-list"
            mustache-template="post-template">
        Load Posts
    </button>
    <div id="post-list"></div>
</div>

यह दृष्टिकोण Mustache के साथ काम करता है। अनुषंगी लेख.

Gotchas & टिप

डिबगिंग औज़ार संस्थापित करें HTMX त्रुटिमोचक विस्तार यह प्रत्येक अनुरोध को दिखाता है

सीएसआरएफ टोकन

ASP.NET Core's antiforgery tokens need special handling with AJAX HtmxAntiforgeryScriptEndpoint:

// In Program.cs
app.MapHtmxAntiforgeryScript();
<!-- In your layout head -->
<script src="@HtmxAntiforgeryScriptEndpoints.Path" defer></script>

या टैग मददगार का उपयोग करें <meta name="htmx-config" includeAspNetAntiforgeryToken="true" />. देखें एचटीएमएस एन्टी-एमएसके-1 बनावटी टोकन पर Khalid' का लेख अधिक जानकारी के लिए

एल्पीन.js @ रजोर में छोटा हाथ

अल्पाइन @click Razor's के साथ छोटा-सा विरोध @ वाक्य संरचना. इसके बजाय स्पष्ट रूप का उपयोग करें

<button x-on:click="doSomething()">Click me</button>  <!-- Instead of @click -->
<div x-bind:class="isOpen ? 'block' : 'hidden'"></div>  <!-- Instead of :class -->

या इससे भागना @@click, लेकिन स्पष्ट वाक्य संरचना स्पष्ट है

इतिहास प्रबंधन

इतिहास प्रविष्टियों को नियंत्रित करना डिफ़ॉल्ट से, HTMX इतिहास में प्रत्येक अनुरोध को दबाता है. पृष्ठीकरण के लिएM SK2 फ़िल्टर जहाँ आप नहीं चाहते हैं

<paging model="@Model" hx-push-url="false">  <!-- Don't add history entries -->

या उपयोग करें hx-replace-url="true" बिना प्रविष्टियों जोड़े यूआरएल को अद्यतन करने के लिए

फ़ॉन्टम आंशिक समस्या ब्राउज़र वापस/फरवार्ड कोई सजावट नहीं के साथ केवल आंशिक खंड दिखाता है hx-history-elt अपने कंटेनर पर

<div class="container mx-auto" id="contentcontainer" hx-history-elt>
    @RenderBody()
</div>

यह HTMX को बताता है कि कौन सा तत्व स्न्यापसॉट करने के लिए है

सीडीएन कैशिंग (Cloudflare

लक्षण HTMX स्थानीय रूप से काम करता है लेकिन सीडीएन के पीछे टूटता है

मूल कारण सीडीएन HX-Request हेडर. आपका सर्वर इस हेडर के आधार पर भिन्न सामग्री को लौटाता है, लेकिन सीडीएन उन्हें समान रूप से कैश करता है

ASP.NET कोर फ़िक्स उपयोग करें VaryByHeaderNames:

[OutputCache(Duration = 3600, VaryByHeaderNames = new[] { "hx-request" })]

सीडीएन फिक्स शामिल करने के लिए कैश नियम कॉन्फ़िगर करें HX-Request कैश कुंजी में. क्लाउडफ्लेर के लिए: डैसबोर्ड M SK2 कैचिंग → कैश नियम Custom Cache key | → | Headers HX-Request.

hx-बड़े विवाद

hx-boost सामान्य लिंक को AJAX अनुरोधों में परिवर्तित करता है एचटीएमएल क्विक्स पृष्ठ कुछ कोर टीम सदस्य इस से बचने की सिफारिश करते हैं (discards <head> सामग्री, व्यवहार की स्थानीयता को प्रभावित करता है

<div hx-boost="true" hx-target="#contentcontainer">
    <a asp-action="Show" asp-route-slug="@post.Slug">Read More</a>
</div>

यह ब्लॉग इसे व्यापक रूप से उपयोग करता है hx-get अधिक स्पष्ट है hx-boost काम करता है यदि आप hx-boost="false" बाल तत्वों पर

निष्कर्ष

ASP के साथ HTMX

  • गतिशील
  • सर्वर-साइड रेंडरिंग
  • उचित HTTP कैचिंग
  • न्यूनतम जावास्क्रिप्ट
  • प्रगतिशील वृद्धि
  • प्रकार HTMX के साथ सुरक्षित रूटिंग
  • अधिकतर स्पष्ट के साथ Zero-config पृष्ठीकरण

सर्वर---प्रदत्त दृष्टिकोण समय की कसौटी पर खडा हुआ है।

इस ब्लॉग पर संबंधित लेख

सहयोगी अनुच्छेद

यह लेख ASP के साथ HTMX पर दोpart श्रृंखला का हिस्सा है

  1. इस लेख ASP पर ध्यान केंद्रित करता है
  2. एचटीएमएस एक्सटेंशन्स का एक विhistle-stop टूर - HTMX घटनाओं में गहराई से डायव

अधिक HTMX लेख

आगे पढ़ने

आधिकारिक दस्तावेज़

लाइब्रेरी

सामुदायिक संसाधन

logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.