Zugriff auf die Modelleigenschaft von MVC über Javascript

147

Ich habe das folgende Modell, das in mein Ansichtsmodell eingeschlossen ist

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; }
}

Wie greife ich über Javascript auf eine der oben genannten Eigenschaften zu?

Ich habe es versucht, aber ich wurde "undefiniert"

var floorplanSettings = "@Model.FloorPlanSettings";
alert(floorplanSettings.IconsDirectory);
Nullreferenz
quelle
5
Um klar zu sein, setzen Sie den Wert der JavaScript-Variablen auf den Wert der C # -Variablen "Model.FloorPlanSettings", die der .ToString () -Wert dieser Klasse (eine Zeichenfolge) ist. Anschließend versuchen Sie, eine JavaScript-Eigenschaft namens "IconsDirectory" für die soeben erstellte JavaScript-Zeichenfolgenvariable zu benachrichtigen. Sie werden undefiniert, weil eine JavaScript-Zeichenfolge keine "IconsDirectory" -Eigenschaft hat.
Joel Cochran
Bereitstellung eines vollständigen Testfalls und Erläuterung aller Szenarien für die Zuweisung von
Modelldaten
Dies funktioniert nicht außerhalb der Ansicht (cshtml). dh in einer externen .js-Datei, auf die die Ansicht verweist.
Spencer Sullivan

Antworten:

240

Sie können Ihr gesamtes serverseitiges Modell wie folgt in ein Javascript-Objekt umwandeln:

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

Wenn Sie in Ihrem Fall nur das FloorPlanSettings-Objekt möchten, übergeben Sie einfach die EncodeMethode that property:

var floorplanSettings = @Html.Raw(Json.Encode(Model.FloorPlanSettings));
Justin Helgerson
quelle
1
Nur zur Bestätigung muss kein a hinzugefügt werden. am Ende? Weil ich von VS eine Aufforderung bekomme, dass die Anweisung nicht beendet wird. Aber wenn ich versuche hinzuzufügen; Der Code wird nicht ausgeführt
Null Reference
1
Was weißt du, ich habe den gleichen Fehler auch in meinen verschiedenen Projekten. Ignoriere es einfach; Es ist Visual Studio, das versucht zu helfen, aber in diesem Fall ist es falsch. Das resultierende HTML und Skript, das an den Browser gesendet wird, ist korrekt.
Justin Helgerson
1
Für mich hat das funktioniert: var myModel = @ {@ Html.Raw (Json.Encode (Model));}
versteckt am
1
Funktioniert nicht, wenn das Modell den Anfangswert hat (Seite erstellen statt Seite bearbeiten) und "ReferenceError: Modell ist nicht definiert" auftritt.
Jack
2
In ASP.Net Core, Json.Serialize ()
Mohammed Noureldin
131

Inhalt der Antwort

1) Zugriff auf Modelldaten im Javascript / Jquery-Codeblock in der .cshtmlDatei

2) Zugriff auf Modelldaten im Javascript / Jquery-Codeblock in der .jsDatei

Zugriff auf Modelldaten im Javascript / Jquery-Codeblock in der .cshtmlDatei

Es gibt zwei Arten von ModelZuweisungen von c # -Variablen ( ) zu JavaScript-Variablen.

  1. Objektzuordnung - Grunddatentypen wie int, string, DateTime(zB: Model.Name)
  2. Objektzuweisung - Benutzerdefinierte oder integrierte Klassen (Beispiel : Model, Model.UserSettingsObj)

Schauen wir uns die Details dieser beiden Aufgaben an.

Für den Rest der Antwort betrachten wir das folgende AppUserModell als Beispiel.

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; }
}

Und die Werte, die wir diesem Modell zuweisen, sind

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

Eigentumszuweisung

Verwenden wir eine andere Syntax für die Zuweisung und beobachten Sie die Ergebnisse.

1) Ohne die Zuweisung von Eigenschaften in Anführungszeichen zu setzen.

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

Geben Sie hier die Bildbeschreibung ein

Wie Sie es gibt einige Fehler sehen können, Rajund Truewird als JavaScript - Variablen sein und da sie ihren einen nicht existieren variable undefinedFehler. Wenn bei der Datumsangabe varialble der Fehler darin besteht, dass unexpected numberZahlen keine Sonderzeichen enthalten dürfen, werden die HTML-Tags in ihre Entitätsnamen konvertiert, damit der Browser Ihre Werte und das HTML-Markup nicht verwechselt.

2) Umschließen der Zuweisung von Eigenschaften in Anführungszeichen.

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

Geben Sie hier die Bildbeschreibung ein

Die Ergebnisse sind gültig. Wenn Sie also die Eigenschaftszuweisung in Anführungszeichen setzen, erhalten Sie eine gültige Syntax. Beachten Sie jedoch, dass die Zahl Agejetzt eine Zeichenfolge ist. Wenn Sie also nicht möchten, dass wir die Anführungszeichen entfernen können, wird sie als Zahlentyp gerendert.

3) Verwenden, @Html.Rawaber ohne es in Anführungszeichen zu setzen

 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);

Geben Sie hier die Bildbeschreibung ein

Die Ergebnisse ähneln unserem Testfall 1. Die Verwendung @Html.Raw()der HTMLZeichenfolge hat jedoch einige Änderungen gezeigt. Der HTML-Code wird beibehalten, ohne dass die Entitätsnamen geändert werden.

Aus den Dokumenten Html.Raw ()

Umschließt das HTML-Markup mit einer HtmlString-Instanz, sodass es als HTML-Markup interpretiert wird.

Trotzdem haben wir Fehler in anderen Zeilen.

4) Verwenden @Html.Rawund auch in Anführungszeichen setzen

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)';

Geben Sie hier die Bildbeschreibung ein

Die Ergebnisse sind bei allen Typen gut. Aber unsere HTMLDaten sind jetzt kaputt und dies wird die Skripte kaputt machen. Das Problem ist, dass wir einfache Anführungszeichen verwenden ', um die Daten zu verpacken, und sogar die Daten einfache Anführungszeichen haben.

Wir können dieses Problem mit zwei Ansätzen lösen.

1) Verwenden Sie doppelte Anführungszeichen " ", um den HTML-Teil zu verpacken. Da die inneren Daten nur einfache Anführungszeichen haben. (Stellen Sie sicher, dass nach dem Umschließen mit doppelten Anführungszeichen auch keine "Daten enthalten sind.)

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

2) Entfliehen Sie der Zeichenbedeutung in Ihrem serverseitigen Code. Mögen

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

Abschluss der Immobilienvergabe

  • Verwenden Sie Anführungszeichen für nicht numerische Datentypen.
  • Verwenden Sie keine Anführungszeichen für numerische Datentypen.
  • Verwenden Html.RawSie diese Option, um Ihre HTML-Daten so zu interpretieren, wie sie sind.
  • Achten Sie auf Ihre HTML-Daten, um entweder die Anführungszeichen auf der Serverseite zu umgehen, oder verwenden Sie bei der Zuweisung zur Javascript-Variablen ein anderes Anführungszeichen als in Daten.

Objektzuordnung

Verwenden wir eine andere Syntax für die Zuweisung und beobachten Sie die Ergebnisse.

1) Ohne die Objektzuweisung in Anführungszeichen zu setzen.

  var userObj = @Model; 

Geben Sie hier die Bildbeschreibung ein

Wenn Sie der Javascript-Variablen ein ac # -Objekt zuweisen, wird der Wert des .ToString()Objekts zugewiesen. Daher das obige Ergebnis.

2 Umschließen der Objektzuweisung in Anführungszeichen

var userObj = '@Model'; 

Geben Sie hier die Bildbeschreibung ein

3) Verwenden Html.Rawohne Anführungszeichen.

   var userObj = @Html.Raw(Model); 

Geben Sie hier die Bildbeschreibung ein

4) Verwenden Sie Html.Rawzusammen mit Anführungszeichen

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

Geben Sie hier die Bildbeschreibung ein

Das hat Html.Rawuns beim Zuweisen eines Objekts zur Variablen wenig geholfen.

5) Verwenden Json.Encode()ohne Anführungszeichen

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;
              };

Wir sehen einige Veränderungen. Wir sehen, dass unser Modell als Objekt interpretiert wird. Aber wir haben diese Sonderzeichen geändert entity names. Auch das Umschließen der obigen Syntax in Anführungszeichen nützt wenig. Wir erhalten einfach das gleiche Ergebnis in Anführungszeichen.

Aus den Dokumenten von Json.Encode ()

Konvertiert ein Datenobjekt in eine Zeichenfolge im JSON-Format (JavaScript Object Notation).

Da Sie dieses entity NameProblem bereits bei der Zuweisung von Eigenschaften festgestellt haben und wenn Sie sich erinnern, haben wir es mit der Verwendung von überwunden Html.Raw. Probieren wir das aus. Lasst uns kombinieren Html.RawundJson.Encode

6) Verwenden Html.Rawund Json.Encodeohne Anführungszeichen.

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

Ergebnis ist ein gültiges Javascript-Objekt

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

Geben Sie hier die Bildbeschreibung ein

7) Verwenden Html.Rawund Json.Encodeinnerhalb von Anführungszeichen.

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

Geben Sie hier die Bildbeschreibung ein

Wie Sie sehen, erhalten Sie beim Umschließen mit Anführungszeichen JSON-Daten

Schlussfolgerung zur Objektzuordnung

  • Verwenden Sie Html.Rawund Json.Encodein Kombination, um Ihr Objekt der Javascript-Variablen als JavaScript-Objekt zuzuweisen .
  • Verwenden Sie Html.Rawund Json.Encodewickeln Sie es auch ein quotes, um einen JSON zu erhalten

Hinweis: Wenn Sie festgestellt haben, dass das DataTime-Datenformat nicht richtig ist. Dies liegt daran, dass Converts a data object to a string that is in the JavaScript Object Notation (JSON) formatJSON wie bereits erwähnt keinen dateTyp enthält. Weitere Optionen, um dies zu beheben, sind das Hinzufügen einer weiteren Codezeile, um diesen Typ allein mit dem Objekt javascipt Date () zu behandeln

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


Zugriff auf Modelldaten im Javascript / Jquery-Codeblock in der .jsDatei

Die Rasierersyntax hat in der .jsDatei keine Bedeutung und daher können wir unser Modell nicht direkt in einer .jsDatei verwenden. Es gibt jedoch eine Problemumgehung.

1) Die Lösung verwendet globale Javascript-Variablen .

Wir müssen den Wert einer Javascipt-Variablen mit globalem Gültigkeitsbereich zuweisen und diese Variable dann in allen Codeblöcken Ihrer .cshtmlund Ihrer .jsDateien verwenden. Die Syntax wäre also

<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>

In diesem Ort können wir die Variablen verwenden , userObjund userJsonObjwie und wann erforderlich.

Hinweis: Ich persönlich empfehle nicht, globale Variablen zu verwenden, da die Wartung sehr schwierig wird. Wenn Sie jedoch keine andere Option haben, können Sie sie mit einer geeigneten Namenskonvention verwenden userAppDetails_global.

2) Verwenden Sie function () oder closure Wrap den gesamten Code, der von den Modelldaten in einer Funktion abhängig ist. Führen Sie diese Funktion dann aus der .cshtmlDatei aus.

external.js

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

.cshtml Datei

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

Hinweis: Auf Ihre externe Datei muss vor dem obigen Skript verwiesen werden. Sonst ist die userDataDependentFunktion undefiniert.

Beachten Sie auch, dass die Funktion auch im globalen Bereich sein muss. Bei beiden Lösungen müssen wir uns also mit globalen Akteuren befassen.

Rajshekar Reddy
quelle
Kann die Model-Eigenschaft in Javascript aktualisiert und an die Controller-Aktionsmethode gesendet werden?
@sortednoun Ja, Sie können, Sie können die geänderten Daten aus einem Formular zurücksenden, oder wenn Sie die Seite nicht neu laden möchten, können Sie AJAX
Rajshekar Reddy
Ich habe kein Ajax verwendet und nur versucht, die Modelleigenschaft in Javascript zu ändern. Beim Absenden des Formulars spiegelte sich diese Änderung jedoch nicht im Modell wider. Ich habe so etwas gemacht wie: var model = @ Html.Raw (Json.Encode (Model)); model.EventCommand = "aktualisierter Wert"; Es gab mir Modell korrekt und aktualisierten Wert, aber beim Senden fehlte die Änderung in der Aktionsmethode. (Obwohl ich das gleiche mit dem versteckten HTML-Steuerelement gemacht und es an EventCommand gebunden und seinen Wert in Javascript aktualisiert habe. Aber ich frage mich, ob ich dasselbe direkt für das Modell tun kann?)
@sortednoun Ich habe verstanden, var model = @Html.Raw(Json.Encode(Model));dass dadurch ein Javascript-Objekt erstellt wird, model das keine Verbindung mit dem C # -Modell hat, das Sie an die Ansicht übergeben. ModelNach dem Rendern der Ansicht wird keine angezeigt . Das Formular in der Benutzeroberfläche hat also keine Ahnung von den Änderungen der Javascript-Objektdaten. Sie müssen jetzt das gesamte modifizierte Modell über AJAX an den Controller übergeben. Oder Sie müssen den Wert Ihrer Eingabesteuerelemente im Formular mithilfe von Javascript aktualisieren.
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?Für diese Anweisung gibt es EventCommand in MVC keine , für Webforms, bei denen eine Verbindung zwischen der Benutzeroberfläche und den Serveraktionen besteht. In MVC ist alles getrennt. Sie können nur über AJAX oder Form Submit oder New Page Request (auch neu laden) mit dem Controller interagieren
Rajshekar Reddy
21

Versuchen Sie Folgendes: (Sie haben die einfachen Anführungszeichen verpasst)

var floorplanSettings = '@Html.Raw(Json.Encode(Model.FloorPlanSettings))';
danmbuen
quelle
1
@JuanPieterse mit Anführungszeichen gibt Ihnen eine JSONwihtout Anführungszeichen gibt Ihnen eine javascript Object. Überprüfen Sie meine Antwort im selben Thread für weitere Details. stackoverflow.com/a/41312348/2592042
Rajshekar Reddy
Das ist nicht wahr, @danmbuen Lösung hat in meinem Fall funktioniert, ich habe Probleme und es zwischen einzelnen Anführungszeichen zu wickeln, hat wie ein Zauber funktioniert, DANKE;)
Dimitri
4

Das Umwickeln der Modelleigenschaft um Parens hat bei mir funktioniert. Sie haben immer noch das gleiche Problem, wenn Visual Studio sich über das Semikolon beschwert, aber es funktioniert.

var closedStatusId = @(Model.ClosedStatusId);
FROgistik
quelle
0

Wenn der Fehler "ReferenceError: Modell ist nicht definiert" ausgelöst wird, können Sie versuchen, die folgende Methode zu verwenden:

$(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 ;
    }
});

Hoffe das hilft...

Murat Yıldız
quelle
0

Ich weiß, dass es zu spät ist, aber diese Lösung funktioniert perfekt sowohl für das .net-Framework als auch für den .net-Kern:

@ System.Web.HttpUtility.JavaScriptStringEncode ()

Amer Jamaeen
quelle