Accesso alla proprietà del modello MVC da Javascript


147

Ho il seguente modello che è racchiuso nel mio modello di visualizzazione

public class FloorPlanSettingsModel
{
    public int Id { get; set; }
    public int? MainFloorPlanId { get; set; }
    public string ImageDirectory { get; set; }
    public string ThumbnailDirectory { get; set; }
    public string IconsDirectory { get; set; }
}

Come posso accedere a una delle proprietà sopra indicate da Javascript?

Ho provato questo, ma mi sono "indefinito"

var floorplanSettings = "@Model.FloorPlanSettings";
alert(floorplanSettings.IconsDirectory);

5
Per essere chiari, ciò che sta accadendo è che stai impostando il valore della variabile JavaScript sul valore della variabile C # "Model.FloorPlanSettings", che sarà il valore .ToString () di quella classe (una stringa). Quindi stai tentando di avvisare una proprietà JavaScript chiamata "IconsDirectory" sulla variabile stringa JavaScript appena creata. Non si definisce perché una stringa JavaScript non ha proprietà "IconsDirectory".
Joel Cochran

Fornito un caso di test completo e spiegato tutti gli scenari di assegnazione dei dati del modello alla variabile javascript,
Rajshekar Reddy,

Questo non funziona al di fuori della vista (cshtml). cioè in un file .js esterno a cui fa riferimento la vista.
Spencer Sullivan,

Risposte:


240

È possibile prendere l'intero modello lato server e trasformarlo in un oggetto Javascript nel modo seguente:

var model = @Html.Raw(Json.Encode(Model));

Nel tuo caso se vuoi solo l'oggetto FloorPlanSettings, passa semplicemente il Encodemetodo che proprietà:

var floorplanSettings = @Html.Raw(Json.Encode(Model.FloorPlanSettings));

1
Solo per confermare, non è necessario aggiungere un; alla fine? Perché ricevo un prompt da VS che afferma che l'istruzione non è terminata. Ma quando provo ad aggiungere; il codice non viene eseguito
Riferimento null

1
Cosa sai, ho lo stesso errore anche nei miei vari progetti. Ignoralo; è Visual Studio che cerca di aiutare, ma in questo caso è sbagliato. L'HTML e lo script risultanti che vengono inviati al browser sono corretti.
Justin Helgerson,

1
Per me questo ha funzionato: var myModel = @ {@ Html.Raw (Json.Encode (Model));}
nascosto

1
Non funziona se il modello è un valore iniziale (Crea pagina anziché Modifica pagina) e viene rilevato "RiferimentoErrore: modello non definito".
Jack,

2
In ASP.Net Core, Json.Serialize ()
Mohammed Noureldin

131

Contenuto della risposta

1) Come accedere ai dati del modello nel blocco di codice Javascript / Jquery nel .cshtmlfile

2) Come accedere ai dati del modello nel blocco di codice Javascript / Jquery nel .jsfile

Come accedere ai dati del modello nel blocco di codice Javascript / Jquery nel .cshtmlfile

Esistono due tipi di Modelassegnazioni di variabili c # ( ) alla variabile JavaScript.

  1. Assegnazione di proprietà - tipi di dati di base come int, string, DateTime(es: Model.Name)
  2. Assegnazione Object - personalizzato o classi incorporati (es: Model, Model.UserSettingsObj)

Vediamo nei dettagli di questi due incarichi.

Per il resto della risposta consideriamo il AppUsermodello seguente come esempio.

public class AppUser
{
    public string Name { get; set; }
    public bool IsAuthenticated { get; set; }
    public DateTime LoginDateTime { get; set; }
    public int Age { get; set; }
    public string UserIconHTML { get; set; }
}

E i valori che assegniamo questo modello sono

AppUser appUser = new AppUser
{
    Name = "Raj",
    IsAuthenticated = true,
    LoginDateTime = DateTime.Now,
    Age = 26,
    UserIconHTML = "<i class='fa fa-users'></i>"
};

Assegnazione della proprietà

Consente di utilizzare una sintassi diversa per l'assegnazione e osservare i risultati.

1) Senza racchiudere l'assegnazione della proprietà tra virgolette.

var Name = @Model.Name;  
var Age = @Model.Age;
var LoginTime = @Model.LoginDateTime; 
var IsAuthenticated = @Model.IsAuthenticated;   
var IconHtml = @Model.UserIconHTML;  

inserisci qui la descrizione dell'immagine

Come puoi vedere ci sono un paio di errori, Rajed Trueè considerato come variabili javascript e poiché non esistono è un variable undefinederrore. Laddove per quanto riguarda la variabile dateTime, l'errore è che i unexpected numbernumeri non possono avere caratteri speciali, i tag HTML vengono convertiti nei nomi delle entità in modo che il browser non mischi i valori e il markup HTML.

2) Concludere l'assegnazione della proprietà tra virgolette.

var Name = '@Model.Name';
var Age = '@Model.Age';
var LoginTime = '@Model.LoginDateTime';
var IsAuthenticated = '@Model.IsAuthenticated';
var IconHtml = '@Model.UserIconHTML'; 

inserisci qui la descrizione dell'immagine

I risultati sono validi, quindi racchiudendo l'assegnazione della proprietà tra virgolette si ottiene una sintassi valida. Ma nota che il numero Ageora è una stringa, quindi se non vuoi che possiamo semplicemente rimuovere le virgolette e verrà visualizzato come un tipo di numero.

3) Usando @Html.Rawma senza racchiuderlo tra virgolette

 var Name = @Html.Raw(Model.Name);
 var Age = @Html.Raw(Model.Age);
 var LoginTime = @Html.Raw(Model.LoginDateTime);
 var IsAuthenticated = @Html.Raw(Model.IsAuthenticated);
 var IconHtml = @Html.Raw(Model.UserIconHTML);

inserisci qui la descrizione dell'immagine

I risultati sono simili al nostro caso di test 1. Tuttavia l'utilizzo @Html.Raw()sulla HTMLstringa ci ha mostrato alcune modifiche. L'HTML viene mantenuto senza cambiare i nomi delle sue entità.

Dai documenti Html.Raw ()

Avvolge il markup HTML in un'istanza HtmlString in modo che venga interpretato come markup HTML.

Ma abbiamo ancora errori in altre righe.

4) Usando @Html.Rawe anche avvolgendolo tra virgolette

var Name ='@Html.Raw(Model.Name)';
var Age = '@Html.Raw(Model.Age)';
var LoginTime = '@Html.Raw(Model.LoginDateTime)';
var IsAuthenticated = '@Html.Raw(Model.IsAuthenticated)';
var IconHtml = '@Html.Raw(Model.UserIconHTML)';

inserisci qui la descrizione dell'immagine

I risultati sono buoni con tutti i tipi. Ma i nostri HTMLdati ora sono rotti e questo romperà gli script. Il problema è perché stiamo usando virgolette singole 'per racchiudere i dati e anche i dati hanno virgolette singole.

Possiamo superare questo problema con 2 approcci.

1) usa le virgolette doppie " "per avvolgere la parte HTML. Poiché i dati interni hanno solo virgolette singole. (Assicurati che dopo aver inserito le virgolette doppie non ci siano anche "dei dati)

  var IconHtml = "@Html.Raw(Model.UserIconHTML)";

2) Sfuggire al significato del carattere nel codice lato server. Piace

  UserIconHTML = "<i class=\"fa fa-users\"></i>"

Conclusione dell'assegnazione della proprietà

  • Utilizzare le virgolette per tipo di dati non numerico.
  • Non utilizzare le virgolette per dataType numerico.
  • Utilizzare Html.Rawper interpretare i dati HTML così come sono.
  • Prenditi cura dei tuoi dati HTML per sfuggire alle virgolette che significano sul lato server, oppure usa una citazione diversa rispetto ai dati durante l'assegnazione alla variabile javascript.

Assegnazione dell'oggetto

Consente di utilizzare una sintassi diversa per l'assegnazione e osservare i risultati.

1) Senza avvolgere l'assegnazione degli oggetti tra virgolette.

  var userObj = @Model; 

inserisci qui la descrizione dell'immagine

Quando si assegna un oggetto ac # alla variabile javascript, .ToString()verrà assegnato il valore di quell'espulsione. Da qui il risultato sopra.

2 Avvolgimento dell'assegnazione degli oggetti tra virgolette

var userObj = '@Model'; 

inserisci qui la descrizione dell'immagine

3) Utilizzo Html.Rawsenza virgolette.

   var userObj = @Html.Raw(Model); 

inserisci qui la descrizione dell'immagine

4) Utilizzo Html.Rawcon virgolette

   var userObj = '@Html.Raw(Model)'; 

inserisci qui la descrizione dell'immagine

Non ci è Html.Rawstato di grande utilità durante l'assegnazione di un oggetto alla variabile.

5) Utilizzo Json.Encode()senza virgolette

var userObj = @Json.Encode(Model); 

//result is like
var userObj = {&quot;Name&quot;:&quot;Raj&quot;,
               &quot;IsAuthenticated&quot;:true,
               &quot;LoginDateTime&quot;:&quot;\/Date(1482572875150)\/&quot;,
               &quot;Age&quot;:26,
               &quot;UserIconHTML&quot;:&quot;\u003ci class=\&quot;fa fa-users\&quot;\u003e\u003c/i\u003e&quot;
              };

Vediamo qualche cambiamento, vediamo che il nostro Modello viene interpretato come un oggetto. Ma abbiamo quei personaggi speciali cambiati in entity names. Anche racchiudere la suddetta sintassi tra virgolette non è di alcuna utilità. Otteniamo semplicemente lo stesso risultato tra virgolette.

Dai documenti di Json.Encode ()

Converte un oggetto dati in una stringa nel formato JSON (JavaScript Object Notation).

Poiché hai già riscontrato questo entity Nameproblema con l'assegnazione della proprietà e se ricordi che lo abbiamo superato con l'uso di Html.Raw. Quindi proviamolo. Consente di combinare Html.RaweJson.Encode

6) Utilizzo Html.Rawe Json.Encodesenza virgolette.

var userObj = @Html.Raw(Json.Encode(Model));

Il risultato è un oggetto Javascript valido

 var userObj = {"Name":"Raj",
     "IsAuthenticated":true,
     "LoginDateTime":"\/Date(1482573224421)\/",
     "Age":26,
     "UserIconHTML":"\u003ci class=\"fa fa-users\"\u003e\u003c/i\u003e"
 };

inserisci qui la descrizione dell'immagine

7) Utilizzo Html.Rawe Json.Encodetra virgolette.

var userObj = '@Html.Raw(Json.Encode(Model))';

inserisci qui la descrizione dell'immagine

Come vedi, il wrapping tra virgolette ci fornisce dati JSON

Conslusione sull'assegnazione degli oggetti

  • Utilizzare Html.Rawe Json.Encodein combinazione per assegnare l'oggetto alla variabile javascript come oggetto JavaScript .
  • Usa Html.Rawe Json.Encodeavvolgilo anche all'interno quotesper ottenere un JSON

Nota: se hai osservato che il formato dei dati DataTime non è corretto. Questo perché, come detto in precedenza, Converts a data object to a string that is in the JavaScript Object Notation (JSON) formatJSON non contiene un datetipo. Altre opzioni per risolvere questo problema sono l'aggiunta di un'altra riga di codice per gestire questo tipo da solo utilizzando l' oggetto Date () javascipt

var userObj.LoginDateTime = new Date('@Html.Raw(Model.LoginDateTime)'); 
//without Json.Encode


Come accedere ai dati del modello nel blocco di codice Javascript / Jquery nel .jsfile

La sintassi del rasoio non ha alcun significato nel .jsfile e quindi non possiamo usare direttamente il nostro modello insisde un .jsfile. Tuttavia, esiste una soluzione alternativa.

1) La soluzione utilizza variabili globali javascript .

Dobbiamo assegnare il valore a una variabile javascipt con ambito globale e quindi utilizzare questa variabile all'interno di tutti i blocchi di codice del tuo .cshtmle dei tuoi .jsfile. Quindi la sintassi sarebbe

<script type="text/javascript">
  var userObj = @Html.Raw(Json.Encode(Model)); //For javascript object
  var userJsonObj = '@Html.Raw(Json.Encode(Model))'; //For json data
</script>

Con questo in atto possiamo usare le variabili userObje userJsonObjcome e quando necessario.

Nota: personalmente non suggerisco di utilizzare le variabili globali in quanto diventa molto difficile per la manutenzione. Tuttavia, se non hai altra opzione, puoi usarla con una convenzione di denominazione adeguata ... qualcosa del genere userAppDetails_global.

2) Utilizzando la funzione () o closure avvolgere tutto il codice che dipende dai dati del modello in una funzione. E quindi eseguire questa funzione dal .cshtmlfile.

external.js

 function userDataDependent(userObj){
  //.... related code
 }

.cshtml file

 <script type="text/javascript">
  userDataDependent(@Html.Raw(Json.Encode(Model))); //execute the function     
</script>

Nota: è necessario fare riferimento al file esterno prima dello script precedente. Altrimenti la userDataDependentfunzione non è definita.

Si noti inoltre che la funzione deve essere anche nell'ambito globale. Pertanto, entrambe le soluzioni devono essere gestite da attori globali.


La proprietà del modello può essere aggiornata in javascript e inviata al metodo di azione del controller?

@sortednoun sì, è possibile, è possibile inviare nuovamente i dati modificati da un modulo, oppure se non si desidera ricaricare la pagina, è possibile utilizzare AJAX
Rajshekar Reddy,

Non stavo usando Ajax e ho appena provato a modificare la proprietà del modello in JavaScript. ma nel presentare il modulo questa modifica non si è riflessa nel modello. Stavo facendo qualcosa del tipo: var model = @ Html.Raw (Json.Encode (Model)); model.EventCommand = "updatedvalue"; Mi ha dato il modello corretto e il valore aggiornato, ma al momento dell'invio mancava la modifica nel metodo di azione. (Anche se ho fatto la stessa cosa usando il controllo Html nascosto e l'ho associato a EventCommand e ne ho aggiornato il valore in javascript. Ma mi chiedevo se potesse fare lo stesso direttamente al modello?)

@sortednoun Ho capito il tuo punto, var model = @Html.Raw(Json.Encode(Model));questo creerà un oggetto javascript model che non ha alcuna connessione con il modello C # che passi alla vista. Infatti non ci sarà più Modeldopo il rendering della vista. Quindi il modulo nell'interfaccia utente non avrà idea delle modifiche ai dati degli oggetti javascript. Ora è necessario passare l'intero modello modificato al controller tramite AJAX, oppure è necessario aggiornare il valore dei controlli di input con nel modulo utilizzando javascript.
Rajshekar Reddy,

Although I did the same thing using hidden Html control and bound it to EventCommand and updated it's value in javascript. But wondering if could do same directly to model?per questa affermazione .. non c'è EventCommand in MVC, è per Webforms dove c'è una connessione tra l'interfaccia utente e le azioni del server, in MVC è tutto separato. L'unico modo per interagire con il controller è tramite AJAX o Invio modulo o Richiesta nuova pagina (ricarica anche)
Rajshekar Reddy,

21

prova questo: (hai perso le virgolette singole)

var floorplanSettings = '@Html.Raw(Json.Encode(Model.FloorPlanSettings))';

1
@JuanPieterse con le virgolette ti dà una JSONvirgoletta senza virgolette ti dà un javascript Object. Controlla la mia risposta nella stessa discussione per maggiori dettagli. stackoverflow.com/a/41312348/2592042
Rajshekar Reddy

Non è vero, la soluzione di @danmbuen ha funzionato nel mio caso, ho avuto problemi e racchiudendola tra virgolette singole ha funzionato come un fascino, GRAZIE;)
Dimitri

4

Avvolgere la proprietà del modello attorno a parens ha funzionato per me. Hai ancora lo stesso problema con Visual Studio che si lamenta del punto e virgola, ma funziona.

var closedStatusId = @(Model.ClosedStatusId);

0

Se viene generato l'errore "RiferimentoErrore: modello non definito" , è possibile provare a utilizzare il seguente metodo:

$(document).ready(function () {

    @{  var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
         var json = serializer.Serialize(Model);
    }

    var model = @Html.Raw(json);
    if(model != null && @Html.Raw(json) != "undefined")
    {
        var id= model.Id;
        var mainFloorPlanId = model.MainFloorPlanId ;
        var imageDirectory = model.ImageDirectory ;
        var iconsDirectory = model.IconsDirectory ;
    }
});

Spero che questo ti aiuti...


0

So che è troppo tardi, ma questa soluzione funziona perfettamente sia per il framework .net che per il core .net:

@ System.Web.HttpUtility.JavaScriptStringEncode ()

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.