Handling ASP.NET MVC Routing in External JavaScrip

2019-07-21 09:40发布

What's the best way to avoid hardcoding URL's in JavaScript (primarily used when making AJAX calls)?

In the past:

  1. Render JavaScript variable with result of @Url.Action or @Url.RouteUrl
  2. Pass result of @Url.Action or @Url.RouteUrl to JavaScript in init/ctor.

Is there a better way?

It would be good to do something like this:

var url = $.routes("actionName", "controllerName") // or "routeName" for named routes
$.post(url, { id = 1 }, function() { //.. });

Which of course isn't really possible (JavaScript doesn't have direct access the to the ViewContext and thus doesn't have access to the route tables).

But i'm wondering if there's a way i can kind of setup my own "route table" for JavaScript, with only the ones i know it would need? (e.g i set it up in the View)

How do people handle this?

4条回答
混吃等死
2楼-- · 2019-07-21 09:56

Implementing a Javascript routing engine wouldn't be too difficult. First, serialize the Routes from C# to Javascript. Second, recreate the Url.Action method.

However, that's a bit overkill for any of the projects I've worked on. My team's projects have always rendered a common Javascript variable that holds all necessary URL's.
This approach ensures strongly-typed action methods and lends better to refactoring too.

查看更多
一纸荒年 Trace。
3楼-- · 2019-07-21 09:58

This is easier said than achieved in practice, but your website should be fully functional with JavaScript turned off. When this is achieved, you should be able to add AJAX support to your website and re-use existing HREF attributes in your anchor tags or action attributes in your FORM tags. The website will be easier to maintain as you won't need to update links in your JavaScript files.

查看更多
女痞
4楼-- · 2019-07-21 10:02

I've decided to implement my own UrlFactory, using ASP.NET helpers directly (Html/Url) in my code, now I don't have the src with me, I'll post'em tomorrow.

Pros on this: I can track each and every url easily and perform some rewriting in a centralized fashion.

Example of usage:

@{
  string myAjaxUrl = UrlFactory.GetUrl (ActionName, ControllerName, new { query-params });
}

Then using 'em in javascript with

var jsUrl = '@myAjaxUrl';

Once you've defined your own Factory, you can hijack "important" urls (eg. for rewriting), and leave common to the Url helper implementation.

However for having this fully client side, there's an extra step of rendering a Js routing context, for accessing client side variables.

EDIT: As promised my very simple Url class builder:

public static class UrlFactory
{
    public static string GetUrl(string Action, string Controller, object RouteValues)
    {
        UrlHelper Url = new UrlHelper(HttpContext.Current.Request.RequestContext);
        return Url.Action(Action, Controller, RouteValues);
    }

    // Common URLS for Denied et similars.
    public static string GetDeniedUrl(PEDUtenti Utente, object RouteValues)
    {
        return GetUrl(Utente, "Denied", "Errors", RouteValues);
    }
    public static string GetDeniedUrl(object RouteValues)
    {
        return GetUrl("Denied", "Errors", RouteValues);
    }
}
查看更多
走好不送
5楼-- · 2019-07-21 10:06

in-spite of injecting javascript in views i rather prefer - let HTML do its job and javascript do its. Below is the pattern.

For Links

/*A cssclass=ajaxlink is added to all those links which we want to ajaxify*/

//html in view
<a class='ajaxlink' href='@Url.Action("Action","Controller")'>I am An Ajax Link</a>

//generated clean html
<a class='ajaxlink' href='/controller/action'>I am An Ajax Link</a>


//Js


jQuery('.ajaxlink').live('click',function(e){
    e.preventDefault();    /*Prevent default behavior of links*/
    var url= $(e.target).attr('href');
   /*
          Now u have url, do post or get: 
          then append received data in some DOM element.
   */
});

//Controller

public ActionResult()
{
       if(Request.IsAjax())
       {    
            /*Return partial content*/
            return View(); 
       }
       else
       {
             return View("SomeOther_View.cshtml");

             /*
                At this point you may reject this request or return full view
                whatever you feel is okie.
             */
       }
}

This way both type of users can be handled javascript enabled and javascript disabled.

Same can be done for forms.

查看更多
登录 后发表回答