Search code examples
c#asp.net-corerazorviewmodel

Is having variables for action URLs in a razor views a good practice? Can I put them in the ViewModel?


I'm trying to have cleaner views for readability and the ease of modification.

I usually have for each view a couple of variables that represents the action URLs used in it:

    @model IndexViewModel
    
    @{
        // controllers
        string newsControllerName = nameof(NewsController).ToName();
    
        // calls to actions
        string removeNewsActionUrl = Url.Action(nameof(NewsController.RemoveNews));
        string getNewsActionUrl = Url.Action(nameof(NewsController.GetNews));
        string indexActionUrl = Url.Action(nameof(NewsController.Index));
    } 

So I can use them inside the view's data attributes for ajax calls in JavaScript:

    <div id="newsContainer"
         data-remove-url="@removeNewsActionUrl"
         data-view-url="@getNewsActionUrl">
        ...
    </div>

Then a friend of mine suggested that I shouldn't declare variables in a view because it's a bad practice and why not declare them in the ViewModel of that view in this case the IndexViewModel.

I know that views shouldn't have complex logic and should have the minimum of C# code, but is what I'm doing a bad practice? If so why? and is there a disadvantage or an advantage to have variables declared in the ViewModel of that view for this purpose?

From Microsoft docs views and view model:

Views are responsible for presenting content through the user interface. They use the Razor view engine to embed .NET code in HTML markup. There should be minimal logic within views, and any logic in them should relate to presenting content. If you find the need to perform a great deal of logic in view files in order to display data from a complex model, consider using a View Component, ViewModel, or view template to simplify the view.

I couldn't find anything related to this on this site.


Solution

  • I wouldn't want this stuff in the view model. It's superfluous there as there is nothing to be communicated between model and controller.

    I don't see an issue with this - it's minimal logic and it is purely concerned with the view itself. Putting it anywhere else would be polluting another part of the codebase for no good reason.

    That said, I don't really see any good reason for the code block - why not just inline it in the HTML attributes?