2013-08-20 14 views
18

Ho la seguente situazione.URL relativo in JQuery Post Call

Ho sviluppato la mia prima applicazione MVC Asp.Net. gira sul mio server al seguente indirizzo

http://localhost:59441/ 

ho scritto alcuni JQuery sul post I metodi che si presentava così

$.ajax({ 
     type: "POST", 
     url: "/CeduleGlobale/UpdateCheckBox", ... 

CeduleGlobale è il mio NomeControllore e UpdateCheckBox è il mio nomeMetodo

Quando ho mettere l'applicazione sul testServer, è stato inserito in una directory virtuale

quindi l'ap plicatura è ora

http://testServer/JprApplication/ 

non più porta per specificare e anche una domanda Nome

Quando ho iniziato a testare, ho subito notato le mie chiamate JQuery postali non funzionano più ...

I li ha modificati così ora l'URL è

/JprMvc/CeduleGlobale/UpdateCheckBox 

il problema è di 2 volte.

  1. rende difficile eseguire il test sul mio computer di sviluppo perché IIS Express non mi consente di specificare una directory virtuale.
  2. Non mi piace hardCoding il nome della directory virtuale in JQuery perché non so quale nome avrà l'applicazione nell'ambiente di produzione e quindi dovrò modificare il mio script prima di poter installare l'applicazione in produzione.

sono sicuro che mi manca qualche cosa di base per semplificare questo.

Grazie

risposta

32

A seconda di dove si trova il tuo JavaScript (all'interno della vista o in un file JS separato), hai un paio di opzioni.

Opzione 1 - all'interno della vista

Basta usare i Helpers Html per generare i link per voi

<script type="text/javascript"> 
    $(function(){ 
     $.ajax({ 
      type: "POST", 
      url: "@Url.Action("UpdateCheckBox", "CeduleGlobale")" 
     }); 
    }); 
</script> 

Opzione 2 - Standalone File JS

Noi di solito abbiamo un funzione per pagina che imposta i gestori di quella pagina. Quindi, siamo in grado di fare qualcosa di simile al seguente:

View

<script type="text/javascript"> 
    $(function(){ 
     SetOrderPage('@Url.Action("UpdateCheckBox", "CeduleGlobale")'); 
    }); 
</script> 

Standalone JS file

function SetOrderPage(ajaxPostUrl){ 
     $.ajax({ 
      type: "POST", 
      url: ajaxPostUrl 
     )}; 
} 

Opzione 3 - file autonomo JS Metodo 2

Potresti avere una variabile globale in y il nostro nel tuo file JS che è il siteroot. Il richiamo qui è che dovrai creare manualmente ciascuno dei tuoi percorsi del metodo di azione. Su ogni pagina, è possibile impostare la variabile globale principale del sito in quanto tale: File

Standalone JS

var siteRoot; 

View

<script type="text/javascript"> 
    siteRoot = '@Request.ApplicationPath'; 
</script> 

Non dimenticare che non è possibile utilizzare la sintassi Razor in un file JS stand alone. Credo che sia meglio consentire a Razor/MVC/.NET di fornirti dinamicamente il percorso del sito o la rotta dell'URL, in quanto ridurrebbe davvero gli errori che potrebbero essere commessi quando si spostano tra siti/directory virtuali.

+0

Personalmente non sono un fan dell'uso dei nomi di percorso a meno che non siano davvero complicati, la maggior parte dei tempo mi interessa solo un semplice controller/azione, quindi uso Url.Action ("MyAction", "MyController") invece. – viggity

+1

Grazie, ma riguardo all'opzione 3: Piuttosto sicuro di non voler usare 'Server.MapPath' perché espone la directory fisica mappata a quel percorso virtuale. Probabilmente hai pensato di usare 'Request.ApplicationPath', che è solitamente utilizzato per generare una stringa di" approot "in fase di runtime per l'utilizzo da parte dei metodi JS (specialmente per i prodotti COTS, dove il nome dell'app non può essere codificato). – nothingisnecessary

+0

Opzione 3: invece di scrivere @ Request.ApplicationPath su ogni singola vista, è sufficiente scriverla una volta sul tuo _Layout.cshtml (o sulla qualsiasi pagina "master"). Ora hai una variabile globale disponibile per tutti i tuoi file JS. – Dimskiy

7

Per quanto ne so non c'è altro modo per aggirare questo. A meno che non si è disposti a cioè all'utente di URL relativo:

$.ajax({ 
     type: "POST", 
     url: "./CeduleGlobale/UpdateCheckBox", ... 

Ma che può ottenere disordinato per vari motivi, quando si refactoring del codice. In alternativa, si aggiunge l'URL che è globalmente definito e quindi è necessario modificarlo solo una volta prima di andare in produzione.

cioè

//Globally defined serverRoot 
serverRoot = "http://someaddress/somevirtualdirectory"; 

$.ajax({ 
     type: "POST", 
     url: serverRoot + "/CeduleGlobale/UpdateCheckBox", ... 

In questo modo se non hai bisogno di esso si può solo impostare serverRoot = ''; e tutto sarà di nuovo a come è ora.

+0

prima parte non funziona .. Seconda parte sembra funzionare. grazie – SerenityNow

+0

Sì, la prima opzione funzionerà solo se la pagina che la sta chiamando è relativa alla radice del server. Gli url relativi sono un mal di testa al massimo e quindi consiglierei solo il mio secondo suggerimento qui sopra per molte ragioni! –

+0

Invece di '"./CeduleGlobale' ... potresti aver bisogno di 'window.location.pathname +"/CeduleGlobale' ... se stai usando url privi di estensione –

1

Pass @ Url.Action ("azione", "controller") per javascript dalla vista. Ciò consentirà di essere aggiornato dinamicamente in fase di esecuzione.

<script> 
    myJavascriptfunction(@Url.Action("action","controller"),param1,param2); 
</script> 

Ci può essere una funzione per ottenere il percorso di root anche che si potrebbe usare per inizializzare le variabili radice nelle risposte precedenti.

1

So che questo è un vecchio post. Ma ho avuto lo stesso problema e sono finito qui. E riuscito a risolvere quel problema con il metodo UrlHelper.Action. Dovrebbe essere usato qualcosa di simile. (Si noti che questa soluzione specifica funzionerà all'interno della vista.)

url: "@Url.Action("UpdateCheckBox", "CeduleGlobale")", 

Spero che questo aiuti. :)

2

Ho avuto questo tipo di problema su MVC 5 utilizzando JQuery, quindi sono andato a questa soluzione che elimina il problema quando si è in Localhost e in qualsiasi Navigator anche quando si distribuisce l'app in una sottocartella.

var pathname = window.location.pathname; 
var VirtualDirectory; 
if (pathname.indexOf("localhost") >= 0 && pathname.indexOf(":") >= 0) { 
    VirtualDirectory = ""; 
} 
else { 
    if ((pathname.lastIndexOf('/')) === pathname.length + 1) { 
     VirtualDirectory = pathname.substring(pathname.indexOf('/'), pathname.lastIndexOf('/')); 
    } else { 
     VirtualDirectory = pathname; 
    } 
} 

E poi in ogni chiamata AJAX:

$.post(VirtualDirectory + "/Controller/Action", { data: data}, "html") 
      .done(function (result) { 
       //some code    
});