Configuración de ajax url para jQuery en un archivo JS utilizando ASP.NET MVC

Cuando realizo una llamada Ajax a una acción MVC actualmente tengo mi javascript dentro de la Vista, no dentro de su propio archivo JS.

Entonces es muy fácil hacer esto:

var xhr = $.ajax({ url: '/' + el1.siblings("input:hidden").val(), data: { ajax: "Y" }, cache: false, success: function(response) { displayMore(response, el1, xhr) } }); 

… luego es bastante fácil incluir la URL en la llamada ajax usando Url.Action() dentro del JS. ¿Cómo puedo mover este archivo JS propio cuando no se codifica correctamente la URL?

De esta manera, utiliza el enrutamiento MVC para que pueda aprovechar al máximo el marco MVC. Inspirado en la respuesta de stusmith.

Aquí tengo una acción en ApplicationController para javascript dynamic para esta URL:

  /application/js 

Incluyo archivos estáticos aquí porque quiero descargar solo un archivo maestro javascript. Puedes elegir devolver solo las cosas dinámicas si quieres:

  ///  /// Renders out javascript ///  ///  [OutputCache(CacheProfile = "Script")] [ActionName("js")] public ContentResult RenderJavascript() { StringBuilder js = new StringBuilder(); // load all my static javascript files js.AppendLine(IO.File.ReadAllText(Request.MapPath("~/Scripts/rr/cart.js"))); js.AppendLine(";"); // dynamic javascript for lookup tables js.AppendLine(GetLookupTables()); js.AppendLine(";"); return new ContentResult() { Content = js.ToString(), ContentType = "application/x-javascript" }; } 

Esta es la función auxiliar que crea nuestra tabla de búsqueda. Solo agregue una línea para cada RouteUrl que quiera usar.

  [NonAction] private string GetLookupTables() { StringBuilder js = new StringBuilder(); // list of keys that correspond to route URLS var urls = new[] { new { key = "updateCart", url = Url.RouteUrl("cart-route", new { action = "updatecart" }) }, new { key = "removeItem", url = Url.RouteUrl("cart-route", new { action = "removeitem" }) } }; // lookup table function js.AppendLine("// URL Lookuptable"); js.AppendLine("$.url=function(url) {"); js.AppendLine("var lookupTable = " + new JavaScriptSerializer().Serialize(urls.ToDictionary(x=>x.key, x=>x.url)) + ";"); js.AppendLine("return lookupTable[url];"); js.AppendLine("}"); return js.ToString(); } 

Esto genera el siguiente javascript dynamic, que es básicamente una tabla de búsqueda desde una clave arbitraria a la URL que necesito para mi método de acción:

 // URL Lookuptable $.url=function(url) { var lookupTable = {"updateCart":"/rrmvc/store/cart/updatecart","removeItem":"/rrmvc/store/cart/removeitem"}; return lookupTable[url]; } 

En cart.js puedo tener una función como esta. Tenga en cuenta que el parámetro url se toma de la tabla de búsqueda:

  var RRStore = {}; RRStore.updateCart = function(sku, qty) { $.ajax({ type: "POST", url: $.url("updateCart"), data: "sku=" + sku + "&qty=" + qty, dataType: "json" // beforeSend: function (){}, // success: function (){}, // error: function (){}, // complete: function (){}, }); return false; 

};

Puedo llamarlo desde cualquier lugar con solo:

  RRStore.updateCart(1001, 5); 

Esta parecía ser la única forma en la que podría encontrarla, ya que me permitiría utilizar el enrutamiento de una manera limpia. Crear dinámicamente URLS en javascript es difícil y difícil de probar. Los tipos de pruebas pueden agregarse en una capa en algún lugar aquí para facilitar las pruebas.

La forma en que lo hago es generar el lado del servidor de URL y almacenar en el HTML generado mediante un atributo de datos HTML5 , por ejemplo: (syntax de Razor)

 
  • ...
  • Luego puede usar la función jQuery attr () para recoger la url, por ejemplo:

     $(".customClass").click(function () { $.ajax({ url: $(this).attr("data-url"), success: function (data) { // do stuff } }); }); 

    Si está generando HTML del lado del cliente en respuesta a las llamadas AJAX, puede incluir las URL relevantes en su carga JSON y rellenar el atributo de datos de la misma manera.

    Envuelva la llamada AJAX en una función que toma la URL (y cualquier otro dato) como parámetro (s) y devuelve la respuesta. Luego, en su opinión, llame a la función en lugar de llamar a la llamada AJAX directamente.

     function doAjax( url, data, elem, callback ) { return $.ajax({ url: url, data: { ajax: data }, cache: false, success: function(response) { callback(response, elem, xhr); } }); } ... 
    

    Recomiendo leer http://jqfundamentals.com/book/index.html#N20D82 para obtener un mejor control sobre el patrón del módulo.

    Aquí hay otra manera:

    En su página maestra, incluya un área para scripts en línea:

      ...  ...  

    Luego, en la carga de la página, cree una función de utilidad:

     protected void Page_Load( object sender, EventArgs e ) { AddInlineScript( string.Format( "$.url=function(url){{return '{0}'+url;}}", GetBaseUri() ) ); ... } private Uri GetBaseUri() { var requestUrl = Request.Url.AbsoluteUri; var i = requestUrl.IndexOf( request.Path ); return new Uri( requestUrl.Substring( 0, i ) ); } private void AddInlineScript( string content ) { var script = new HtmlGenericControl( "script" ); script.Attributes.Add( "type", "text/javascript" ); script.InnerHtml = content; _inlineScripts.Controls.Add( script ); } 

    Ahora puedes usar esta función en tu ajax:

     $.ajax({ url: $.url('path/to/my-handler'), ... });