Creating uniform URLs using MVC .NET routing: a guide

While using ASP.Net MVC 5 in .NET Framework 4.8, I am constantly facing a 404 error due to inconsistent URL generation. For instance, when including the _PageNav.chstml partial at the top of each page and adding

@Url.Action("Index", new { controller = "Home" })
to redirect users back to the home page, it works fine within the navigation bar as
<a class="navbar-brand" href="/" />
.

However, if I use the same

@Url.Action("Index", new { controller = "Home" })
later on the same page for a button, the resulting URL is different:
<a id="doneButton" class="btn btn-secondary px-4" href="https://localhost:44337/smrt/">Done</a>

This inconsistency often leads to issues where AJAX JavaScript references to controllers end up with missing references like /create, causing URLs like https://localhost:44337/create instead of

https://localhost:44337/home/create
or /home/create, resulting in
https://localhost:44337/home/home/create
instead of
https://localhost:44337/home/create

Furthermore, I have limitations due to security restrictions, meaning I cannot include any JavaScript directly on the page itself. This restricts me from writing razor code in my .cshtml files that would generate JavaScript. Instead, I can only use JavaScript sourced externally in the page files.

Answer №1

@Url.Action("Index", "Home")
is typically sufficient for the job, but there have been instances where custom routing complicates things, especially when switching between levels. In some cases, I've had to add "../" to navigate to a different controller structure when one view calls another in a separate folder via AJAX. Additionally, the default URL structure can cause issues with relative URL calls by hiding /Index in the URL path.

  • localhost/site (defaults to Home/Index)
  • localhost/site/other (defaults to Index)

This difference in folder structure can disrupt URL navigation and lead to unexpected behavior.

In my experience, these challenges may be contributing to the issues you are encountering.

Answer №2

After experimenting with various approaches, I finally cracked the code and resolved my issue. Now, I effortlessly achieve consistent URLs exactly as I require them every single time.

To kick things off, I delved into the insightful article titled How to Build Absolute Action URLs Using the UrlHelper Class. This resource guided me in crafting a specific class along with an extension method based on the UrlHelper Class.

using System.Web.Mvc;

namespace MVCPages.Utilities
{
    public static class UrlHelperExtenions
    {
        /// <summary>
        /// Generates a fully qualified URL to an action method by using
        /// the specified action name, controller name, and route values.
        /// </summary>
        /// <param name="url">The URL helper.</param>
        /// <param name="actionName">The name of the action method.</param>
        /// <param name="controllerName">The name of the controller.</param>
        /// <param name="routeValues">The route values.</param>
        /// <returns>The absolute URL.</returns>        
        public static string AbsoluteAction(
            this UrlHelper url,
            string actionName,
            string controllerName,
            object routeValues = null
        )
        {
            var httpContext = url.RequestContext.HttpContext;
            string scheme = httpContext.Request.Url.Scheme;

            return url.Action(
                actionName,
                controllerName,
                routeValues,
                scheme
            );
        }
    }
}

This innovative method now dynamically provides me with the website's root regardless of its deployment location.

Subsequently, I employ the new method extension within the views requiring URL uniformity, passing the absolute root URL to the view through ViewBag.

public ActionResult Index()
{
   string rootUrl = Url.AbsoluteAction("Index", "Smrt");
   ViewBag.RootUrl = rootUrl;
}

Due to restrictions regarding Razor for generating JavaScript, I turn to Razor to construct a concealed HTML div tag containing the root URL information,

<div id="rootUrl">https://rooturl.com/</div>

Proceeding further, in JavaScript, I utilize the DOM to fetch the URL from the HTML tag and incorporate it into my ajax calls for forming comprehensive URLs during AJAX requests.

window.onload = function () { 
   var rootUrl = document.getElementById("rootUrl").innerHTML;
   var ajaxUrl = rootUrl + ajaxCall;
};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How to transition from using a CDN to NPM for implementing the Google Maps JavaScript MarkerClusterer?

Currently integrating Google Maps JavaScript MarkerClusterer from CDN, I am considering transitioning to the NPM version for Typescript checking in my JavaScript files. However, I am encountering difficulties understanding how to make this switch. The docu ...

Identifying the moment when the body scroll reaches the top or bottom of an element

I have been experimenting with javascript and jquery to determine when the window scroll reaches the top of a specific element. Although I have been trying different methods, I have yet to see any successful outcomes: fiddle: https://jsfiddle.net/jzhang17 ...

What are the steps to restrict a user from accessing a specific website?

In my Vue.js project, I've implemented a function that hides a specific menu item for users with insufficient permissions: <a :href="href" @click="navigate" v-if="hideMenuItem()"> // some code </a> hideMe ...

Jquery code is not functioning on elements that were not present during the initial page load

My web application includes javascript that is loaded on page load: $(function() { $('.modal-delete').click(function() { alert(); }); }); On my html page, I have a set of buttons that trigger blank message boxes when clicked: <butto ...

Tips for incorporating a set offset while utilizing the scrollTop() function

I have successfully implemented a code that sets a position:fixed to a div when it scrolls past the top of the screen. The code I used is as follows: var $window = $(window), $stickyEl = $('#the-sticky-div'), elTop = $stickyEl.o ...

All-in-One MVC Site

I came across a fascinating .net framework that enabled an exe to contain a complete website and server, making deployment as simple as stopping the exe and starting the new one. I am searching for this framework or any similar ones for the .net runtime. ...

Form that adjusts input fields according to the selected input value

I am in need of creating a dynamic web form where users can select a category and based on their selection, new input fields will appear. I believe this involves using JavaScript, but my searches on GitHub and Stack Overflow have not yielded a suitable sol ...

Javascript Using Promise to Await Ajax Content Loading

As a newcomer to JavaScript, I am exploring ways to traverse a DOM that utilizes Checkboxes for filtering results and displays them through Ajax. The checkboxes are organized in 4 levels: Grand Parent Parent Child Grand Child My goal is ...

Node.js/Express API Endpoint Ceases Functioning

In my Angular/Express.js app, there is a post method within my api.service.ts file: post(data: any, endpointUrl: string): Observable<T> { console.log("REACHED POST METHOD") return this.http.post<T>(`${this.apiUrl}/${endpoint ...

Login block for Episerver

I'm brand new to episerver cms and I'm trying to add a "login block" to the top right corner of my home page where front-end users can log in. I've created a “LoginBlock”, ”LoginBlockController” along with a class called “LoginForm ...

MUI Grid with Custom Responsive Ordering

Can I achieve a responsive grid layout like this example? Check out the image here I have already coded the desktop version of the grid: <Grid container spacing={2}> <Grid item sm={12} lg={6} order={{ sm: 2, lg: 1 }}> ...

Refresh content that was previously removed using ajax

Currently, I'm a bit unsure about the best approach to solving this particular challenge. When searching for information on loading and unloading Ajax, most results focus on unloading content before loading new content, rather than reloading previousl ...

Using AngularJS to send a $http.post request with Paypal integration

This form utilizes the standard PayPal format for making purchases. <form action="https://www.paypal.com/cgi-bin/webscr" method="post"> <input type="hidden" name="cmd" value="_xclick"> <input type="hidden" name="business" value="<a href= ...

What are the steps to use grunt for running a node.js application?

Directory Structure: myapp --public(directory) //contains files related to public (AngularJS, CSS, etc) --server(directory) //contains files related to server --server.js Code server.js //located at root directory ---------------------- ... var app = ...

Turn off error notifications from eslint parsing

Within my code, there is a conditional export that looks like this: if (process.env.NODE_ENV === 'testing') export myFunc; While in es6, this type of statement is typically not allowed due to the requirement for imports and exports to be top- ...

Attempted to utilize zipstatic but received no feedback

I attempted to utilize the Zipstatic API with jQuery in my code, as shown below. However, I am not receiving any response. Could there be something missing? jQuery(function() { jQuery("#form").hide(); jQuery("#postcode").keyup(function() { var c ...

Exploring methods to conduct testing on an AngularJS application using AngularJS end-to-end testing, specifically focusing on scenarios involving multiple inputs

Our program includes a directive that is repeated multiple times with an input field. The structure of our code resembles the following: <li> <label>AMI</label> <div class="searchbox" searchbox="" filter="search.ami"> ...

"Utilizing AngularJS event system through $broadcast and $on

I have recently started learning AngularJS and I am trying to send a message from one controller to another. I have looked at various examples and my code seems to be similar, but it is not working. Why is $rootScope.$on not working? Can anyone help me wit ...

Is there a way for me to dynamically decide whether to use the append or prepend function?

Utilizing jQuery to retrieve data from the controller and populate a calendar represented by a table with days in columns. Implementing functionality for navigating between previous week / next week, as well as previous day / next day. The four scenarios s ...

I am facing an issue with Angular reactive forms where the default values I set in ngOnInIt are not being reflected

Having some issues with setting default values in my Angular app using reactive forms. The defaults I set in ngOnInit are not showing up. I am also using the filter function within the map method. I am trying to select a value based on the URL and have it ...