Domanda

Ho una domanda abbastanza semplice per tutti gli esperti di rasoio là fuori. Sto cercando di fare una chiamata a jQuery $ .ajax () a un URL, usando URL.Content () per tradurre il percorso relativo alla casa in un percorso relativo alla radice. In tal modo, Razor si sta confondendo un po 'su dove si trova la fine della mia @section. Preferirei essere in grado di specificare l'URL in linea, ma quando lo faccio, Razor pensa che la fine dell'elenco dei parametri $ .ajax () sia la fine della mia @section. Sto usando @Section perché voglio usare layout per posizionare il mio JavaScript nella parte inferiore di ogni file. Perché il rasoio si confonde così tanto? Ho anche provato a usare @(url.content (...)), ma non funziona neanche.

Inoltre, è il modo migliore per affrontare il problema? Sto usando l'anteprima ASP.NET MVC 4.

Questo funziona:

@section Scripts {
    <script type="text/javascript">        
        var getMessagesUrl = '@Url.Content("~/Logging/GetMessages")';

        $(document).ready(function () {
            $.ajax({
                url: getMessagesUrl,
                dataType: 'html',
                success: function (result) {
                    $('tbody').html(result);
                }
            });
        });
    </script>
}

Questo non lo fa:

@section Scripts {
    <script type="text/javascript">        
        $(document).ready(function () {
            $.ajax({
                url: '@Url.Content("~/Logging/GetMessages")',
                dataType: 'html',
                success: function (result) {
                    $('tbody').html(result);
                }
            }); //Razor thinks this is the curly-brace that ends the section!
        });
    </script>
}
È stato utile?

Soluzione 5

Grazie per tutto l'aiuto, gente.

Sembra che debba essere stato un bug nell'anteprima ASP.NET MVC 4. Ho appena aggiornato la beta ASP.NET MVC 4 che è uscita il 15 febbraio e il problema è ora completamente sparito.

Altri suggerimenti

Ciò dipende probabilmente al comportamento del parser. Quando incontra il @ simbolo, il parser passa alla modalità codice e leggerà l'espressione implicita Url.Content("~/Logging.GetMessages") (Beh, in realtà leggerà fino al ' simbolo, determinare che non è un carattere valido in un'espressione e trackback per tornare fino alla fine del ). È dopo questa fase che il parser si sta confondendo un po 'con la tua vista perché è probabile in modalità codice quando incontra la finale } carattere, e pensa che sia la fine di un intervallo di codice.

La realtà è che devi stare abbastanza attento quando usi JavaScript all'interno di una vista di rasoio con C#. Le transizioni al codice sono esplicite, ad esempio @ e dopo un {, ma le transizioni per il markup sono un po 'più difficili da determinare.

Razor a parte, la mia raccomandazione sarebbe quella di attaccare il codice dell'applicazione JavaScript in un file esterno e sfruttare i dati-* attributi per trasmettere informazioni di meta al codice applicazione, ad esempio:

<script id="messageScript" type="text/javascript"
    src="/Scripts/messages.js" 
    data-messages="@Url.Content("~/Logging/GetMessages")"></script>

A cui puoi accedere come:

(function($) {

    $(function() {
        var $this = $("#messageScript");
        $.ajax({
            url: $this.attr("data-messages"),
            type: "html",
            success: function(result) {
                $("tbody").html(result);
            }
        });
    });

})(window.jQuery);

Aggiornare: Il simbolo di Dave non stava causando il problema, lo ha aggiunto solo nella sua domanda per scopi illustrativi.

Su MVC4 sono stato in grado di isolare il problema. Questo non si compilerebbe:

<script type="text/javascript">
  $(document).ready(function () {
    $.ajax({
      url: '@Url.Content("~/Logging/GetMessages")',
      dataType: 'html',
      success: function (result) {
        $('tbody').html(result);
      }
    }); //<-- test
  });
</script>

Ma questo sarebbe:

<script type="text/javascript">
  $(document).ready(function () {
    $.ajax({
      url: '@Url.Content("~/Logging/GetMessages")',
      dataType: 'html',
      success: function (result) {
        $('tbody').html(result);
      }
    }); //-- test
  });
</script>

Sembra che fosse solo il < Nel commento che lo stava lanciando.

La risposta di Matthew spiega praticamente il comportamento (anche se, a dire il vero, non posso riprodurre il tuo problema - né capire perché non funzionerebbe - entrambi i tuoi esempi funzionano bene qui). Per un approccio diverso, è possibile dedicare un'azione/vista alle variabili JavaScript generate (URL, impostazioni, testi localizzati, qualunque cosa), cioè:

// Could/should be OutputCached depending on the scenario
public ActionResult Globals()
{
   var model = new ClientGlobalsModel();

   // ClientGlobalsModel has a single (could be more) Dictionary<string, string>
   // (Urls) and a ToJSON() method which uses JavaScriptSerializer to serialize 
   // the object:
   model.Urls.Add("GetMessages", Url.Content("~/Logging/GetMessages"));

   // I mostly use this method for e.g. actions:
   model.Urls.Add("UploadImage", Url.Action("Upload", "Image"));

   Response.ContentType = "text/javascript";

   return View(model);
}

Globals.cshtml:

@model ClientGlobalsModel
@{
    Layout = null; // If you have a layout supplied in e.g. _ViewStart
}
var GLOBALS = @Model.ToJSON()

Sì, questo avrebbe potuto essere un semplice Content() Risultato piuttosto che una vista - ma quando si dispone di più globali (EG Impostazioni + URL + testi), potresti voler un controllo più facile sull'output dello script e forse serializzare ogni dizionario individualmente. Potrebbe anche voler lo spazio dei nomi che "globali" variabili in alcuni nomi di applicazione condivisa per evitare di inquinare l'ambito globale.

(ad esempio) indice.cshtml:

<script src="@Url.Action("Globals", "Client")"></script>
<script src="@Url.Content("~/Scripts/main.js")"></script>

... che include semplicemente l'output da /client /globali. E "main.js", in cui ora abbiamo spostato il resto della tua sceneggiatura:

main.js (statico):

$(document).ready(function () {
   $.ajax({
      url: GLOBALS.Urls.GetMessages,
      dataType: 'html',
      success: function (result) {
         $('tbody').html(result);
      }
   });
});

Ovviamente è possibile utilizzare lo stesso tipo di approccio per emettere alcune impostazioni utente/contesto/visualizzazione direttamente nella vista. Per alcuni URL o dati, l'approccio degli attributi dati può essere migliore a seconda dei gusti. Non sono un fan del ripieno tonnellate Tuttavia, di ciò che è fondamentalmente impostazioni su attributi su ogni pagina HTML.

Sembra essere ancora un problema con MVC4 / Visual Studio 2010, ma ecco la mia soluzione:

@section jQueryDocumentReady
{
  @{
  <text>
     // All the javascript and bracers you want here
  </text>
  }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top