On this page

Skip to content

How to use Vue 3 with ASP.NET Razor

TLDR

  • It is recommended to use the Vue 3 Options API for development in lightweight or non-build tool environments.
  • Through custom TagHelpers, ASP.NET Core DataAnnotations can be automatically converted into vee-validate validation rules.
  • When integrating, be aware of conflicts between v-model and the native value attribute; it is recommended to use a TagHelper to automatically remove the value attribute.
  • Use axios interceptors to automatically inject the RequestVerificationToken to ensure the ValidateAntiForgeryToken mechanism functions correctly.
  • Warning: This architecture was found to have issues with asp-page-handler not functioning correctly and failing to properly parse DisplayName in subsequent tests. It is recommended to evaluate switching to Blazor or other more stable integration solutions.

Integration Architecture and Core Implementation

Integrating Vue 3 into ASP.NET Razor Pages primarily aims to leverage frontend packages (such as vee-validate) for validation while retaining Razor's server-side rendering capabilities.

Handling Vue and Razor Attribute Conflicts

When does this issue occur: When using asp-for to generate an input tag in a Razor page while simultaneously adding v-model, the native value attribute causes warnings or exceptions in Vue's data binding.

The solution is to create a VueInputTagHelper that automatically removes the value attribute when v-model is detected:

csharp
[HtmlTargetElement("input", Attributes = ForAttributeName, TagStructure = TagStructure.WithoutEndTag)]
public class VueInputTagHelper : TagHelper {
    private const string ForAttributeName = "asp-for";
    private const string VueModelAttributeName = "v-model";

    public override void Process(TagHelperContext context, TagHelperOutput output) {
        string[] excludeTypes = new string[] { "radio", "checkbox" };

        if (context.AllAttributes.ContainsName(VueModelAttributeName) && !excludeTypes.Contains(context.AllAttributes["type"].Value)) {
            output.Attributes.RemoveAt(output.Attributes.IndexOfName("value"));
        }
    }
}

Automating Frontend Validation Rules

When does this issue occur: When manually maintaining frontend validation rules that are inconsistent with backend DataAnnotations.

Through a custom VeeValidateInputTagHelper, attributes like Required and StringLength can be automatically converted into rules strings recognizable by vee-validate:

csharp
private string? GetRules() {
    List<string> items = new List<string>();
    // Iterate through and convert validation attributes in Metadata
    foreach (var validationAttribute in For.Metadata.ValidatorMetadata) {
        switch (validationAttribute) {
            case RequiredAttribute _:
                items.Add("required");
                break;
            case EmailAddressAttribute _:
                items.Add("email");
                break;
            // Other attribute conversion logic...
        }
    }
    return items.Any() ? $"{string.Join("|", items)}" : null;
}

Security and Ajax Requests

When does this issue occur: When sending POST requests using axios, failing to include the RequestVerificationToken will cause ASP.NET Core's ValidateAntiForgeryToken validation to fail.

Configure an axios interceptor in site.js to ensure that every request includes the token:

javascript
axios.interceptors.request.use(
    config => {
        let token = document.querySelector('input[name="__RequestVerificationToken"]');
        if (token !== null) {
            config.headers = {
                RequestVerificationToken: token.value
            }
        }
        return config;
    }
);

Pitfalls and Architectural Evaluation

WARNING

This architecture was found to have the following severe limitations during subsequent maintenance:

  • The <v-form> generated by VeeValidateFormTagHelper causes asp-page-handler to stop functioning correctly.
  • Error messages cannot correctly display field names set by attributes like DisplayName.
  • Due to frequent updates to frontend frameworks, this type of "hybrid" architecture is prone to compatibility issues.

Based on the reasons above, it is recommended that developers consider the following when choosing a technology stack:

  • For larger projects, it is recommended to adopt ASP.NET Core Blazor directly to avoid decoupling frontend and backend validation logic.
  • If Vue 3 must be used, consider making the frontend a completely independent SPA project and communicating via APIs, rather than forcing DOM-level integration with Razor Pages.

Change Log

  • 2023-01-30 Initial document creation.
  • 2024-04-07 Added issues not addressed by the article's architecture.