Skip to content

How to use Vue with ASP.NET Razor

TLDR

  • Architectural Integration: Initialize the Vue instance globally via _Layout.cshtml and use mixins to inject page-specific logic for modular management.
  • Preventing FOUC: Use v-cloak combined with CSS [v-cloak] { display: none; } to resolve template flashing during page load.
  • Avoiding Conflicts: Do not use <script> tags within Vue templates; use @@ to escape Razor syntax when it conflicts with Vue syntax (e.g., @).
  • Ajax Security: Use axios interceptors to automatically add the RequestVerificationToken to headers to comply with ASP.NET Core anti-forgery requirements.
  • Validation Mechanism: Use custom Tag Helpers to convert C# Model Validation attributes into VeeValidate rules, enabling real-time frontend feedback while maintaining backend validation.

Architectural Integration: Collaboration between Vue and Razor

When integrating Vue into ASP.NET Razor Pages, it is recommended to centralize the initialization logic of the Vue instance in _Layout.cshtml and use the mixins mechanism to inject data and methods for each page.

Core Implementation

  1. Root Node Setup: Define a container with v-cloak in _Layout.cshtml to ensure content remains hidden until Vue compilation is complete.
  2. Mixin Injection: Declare a global mixins array in _Layout.cshtml, and have each page push its specific logic into this array via the @section Scripts block.
  3. Initialization: Finally, perform new Vue({ el: '#vueApp', mixins: mixins }) at the bottom of _Layout.cshtml.

Common Development Notes

1. Avoiding Template Compilation Errors

When this occurs: Writing <script> tags directly within the Vue mounting scope.

  • Reason: Vue templates are only responsible for UI mapping and do not allow tags with side effects.
  • Recommendation: Move all JavaScript logic to the @section Scripts block.

2. Razor and Vue Syntax Conflicts

When this occurs: Using Vue's @ shorthand syntax (e.g., @click) in a Razor page.

  • Reason: @ is a reserved keyword in Razor, which will cause compilation errors.
  • Recommendation: Use @@ to escape it (e.g., @@click). If used within a Tag Helper, ensure the @ only appears within attribute values; otherwise, the Tag Helper may fail to parse.

Alternatives to jQuery

Ajax Requests and XSRF Protection

Since ASP.NET Core Razor Pages automatically perform anti-forgery validation, you must ensure that axios includes the correct token in the header.

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

Frontend Validation: Integrating VeeValidate with Model Validation

When this occurs: You want to implement real-time frontend validation without abandoning native ASP.NET validation attributes like [Required] or [EmailAddress].

  • Solution: Write a custom TagHelper to convert C# ModelMetadata into VeeValidate HTML attributes (e.g., v-validate).
  • Validation Results:
    • Automatically generate validation rules via VeeValidationInputTagHelper.
    • Bind v-show and error message displays via VeeValidationMessageTagHelper.
    • In the Vue created hook, inject backend ModelState error messages into this.$validator.errors to ensure the frontend displays errors synchronously when backend validation fails.

Change Log

  • 2022-10-24 Initial documentation created.