Mengakses properti model MVC dari Javascript

147

Saya memiliki model berikut yang dibungkus dalam model tampilan saya

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

Bagaimana cara mengakses salah satu properti di atas dari Javascript?

Saya mencoba ini, tetapi saya "tidak terdefinisi"

var floorplanSettings = "@Model.FloorPlanSettings";
alert(floorplanSettings.IconsDirectory);
Referensi Null
sumber
5
Untuk lebih jelasnya, apa yang terjadi adalah Anda mengatur nilai variabel JavaScript ke nilai variabel C # "Model.FloorPlanSettings", yang akan menjadi nilai .ToString () dari kelas tersebut (string). Kemudian Anda mencoba untuk mengingatkan properti JavaScript yang disebut "IconsDirectory" pada variabel string JavaScript yang baru saja Anda buat. Anda tidak terdefinisi karena string JavaScript tidak memiliki properti "IconsDirectory".
Joel Cochran
Menyediakan kasus Uji lengkap dan menjelaskan semua skenario penetapan data Model ke variabel javascript,
Rajshekar Reddy
Ini tidak berfungsi di luar tampilan (cshtml). yaitu dalam file .js eksternal yang dirujuk oleh tampilan.
Spencer Sullivan

Jawaban:

240

Anda bisa mengambil seluruh model sisi server dan mengubahnya menjadi objek Javascript dengan melakukan hal berikut:

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

Dalam kasus Anda jika Anda hanya ingin objek FloorPlanSettings, cukup kirimkan Encodemetode properti itu:

var floorplanSettings = @Html.Raw(Json.Encode(Model.FloorPlanSettings));
Justin Helgerson
sumber
1
Hanya untuk mengonfirmasi, tidak perlu menambahkan; pada akhirnya? Karena saya mendapatkan prompt dari VS yang menyatakan pernyataan tidak dihentikan. Tetapi ketika saya mencoba menambahkan; kode tidak berjalan
Referensi Null
1
Apa yang Anda tahu, saya punya kesalahan yang sama di berbagai proyek saya juga. Abaikan saja; Visual Studio mencoba membantu, tetapi, ini salah dalam hal ini. HTML dan skrip yang dihasilkan yang dikirim ke browser sudah benar.
Justin Helgerson
1
Bagi saya ini berhasil: var myModel = @ {@ Html.Raw (Json.Encode (Model));}
disembunyikan
1
Tidak berfungsi jika model adalah nilai awal (Buat halaman alih-alih halaman Edit) dan "ReferenceError: Model tidak didefinisikan" ditemui.
Jack
2
Dalam ASP.Net Core, Json.Serialize ()
Mohammed Noureldin
131

Isi dari Jawabannya

1) Cara mengakses data Model dalam blok kode Javascript / Jquery dalam .cshtmlfile

2) Cara mengakses data Model dalam blok kode Javascript / Jquery dalam .jsfile

Cara mengakses data Model dalam blok kode Javascript / Jquery dalam .cshtmlfile

Ada dua jenis Modelpenugasan c # variable ( ) untuk variabel JavaScript.

  1. Tugas Properti - tipe data dasar seperti int, string, DateTime(ex: Model.Name)
  2. Penugasan objek - Kelas khusus atau bawaan (mis .: Model, Model.UserSettingsObj)

Mari kita melihat detail dari dua tugas ini.

Untuk sisa jawabannya, mari pertimbangkan AppUserModel di bawah ini sebagai contoh.

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

Dan nilai yang kami berikan pada Model ini adalah

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

Penugasan properti

Mari kita gunakan sintaks yang berbeda untuk penugasan dan amati hasilnya.

1) Tanpa membungkus penugasan properti dalam tanda kutip.

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

masukkan deskripsi gambar di sini

Seperti yang Anda lihat ada beberapa kesalahan, Rajdan Truedianggap sebagai variabel javascript dan karena mereka tidak ada variable undefinedkesalahan. Sedangkan untuk varialble dateTime kesalahannya adalah unexpected numberangka tidak dapat memiliki karakter khusus, Tag HTML dikonversi menjadi nama entitasnya sehingga browser tidak mencampurkan nilai Anda dan markup HTML.

2) Membungkus tugas properti dalam Quotes.

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

masukkan deskripsi gambar di sini

Hasilnya valid, Jadi membungkus penugasan properti dalam tanda kutip memberi kita sintaks yang valid. Tetapi perhatikan bahwa Bilangan Agesekarang menjadi string, Jadi jika Anda tidak ingin kami hanya dapat menghapus tanda kutip dan itu akan diberikan sebagai tipe angka.

3) Menggunakan @Html.Rawtetapi tanpa membungkusnya dengan tanda kutip

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

masukkan deskripsi gambar di sini

Hasilnya mirip dengan uji kasus kami 1. Namun penggunaan @Html.Raw()pada HTMLstring memang menunjukkan kepada kami beberapa perubahan. HTML dipertahankan tanpa mengubah nama entitasnya.

Dari dokumen Html.Raw ()

Membungkus markup HTML dalam instance HtmlString sehingga ditafsirkan sebagai markup HTML.

Tapi kami masih memiliki kesalahan di jalur lain.

4) Menggunakan @Html.Rawdan juga membungkusnya dengan tanda kutip

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

masukkan deskripsi gambar di sini

Hasilnya bagus dengan semua tipe. Tetapi HTMLdata kami sekarang rusak dan ini akan merusak skrip. Masalahnya adalah karena kami menggunakan tanda kutip tunggal 'untuk membungkus data dan bahkan data memiliki tanda kutip tunggal.

Kami dapat mengatasi masalah ini dengan 2 pendekatan.

1) menggunakan tanda kutip ganda " "untuk membungkus bagian HTML. Karena data dalam hanya memiliki kutipan tunggal. (Pastikan bahwa setelah membungkus dengan tanda kutip ganda tidak ada "dalam data juga)

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

2) Menghindari makna karakter dalam kode sisi server Anda. Suka

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

Kesimpulan penugasan properti

  • Gunakan kutipan untuk tipe data non numerik.
  • Jangan gunakan kutipan untuk tipe data numerik.
  • Gunakan Html.Rawuntuk menafsirkan data HTML Anda apa adanya.
  • Jaga data HTML Anda untuk menghindari makna kutipan di sisi server, Atau gunakan kutipan berbeda dari pada data selama penugasan ke variabel javascript.

Tugas objek

Mari kita gunakan sintaks yang berbeda untuk penugasan dan amati hasilnya.

1) Tanpa membungkus penugasan objek dalam tanda kutip.

  var userObj = @Model; 

masukkan deskripsi gambar di sini

Ketika Anda menetapkan objek ac # ke variabel javascript nilai dari .ToString()objek tersebut akan ditetapkan. Maka hasil di atas.

2 Membungkus penugasan objek dalam tanda kutip

var userObj = '@Model'; 

masukkan deskripsi gambar di sini

3) Menggunakan Html.Rawtanpa tanda kutip.

   var userObj = @Html.Raw(Model); 

masukkan deskripsi gambar di sini

4) Menggunakan Html.Rawbersama dengan kutipan

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

masukkan deskripsi gambar di sini

Itu Html.Rawtidak banyak berguna bagi kami saat menetapkan objek ke variabel.

5) Menggunakan Json.Encode()tanpa tanda kutip

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

Kami melihat beberapa perubahan, Kami melihat Model kami ditafsirkan sebagai objek. Tetapi kami memiliki karakter khusus yang diubah menjadi entity names. Juga membungkus sintaks di atas dalam tanda kutip tidak banyak berguna. Kami hanya mendapatkan hasil yang sama dalam kutipan.

Dari dokumen Json.Encode ()

Mengonversi objek data ke string yang dalam format JavaScript Object Notation (JSON).

Karena Anda telah mengalami entity Namemasalah ini dengan penetapan properti dan jika Anda ingat kami mengatasinya dengan penggunaan Html.Raw. Jadi mari kita coba itu. Mari kita gabungkan Html.RawdanJson.Encode

6) Menggunakan Html.Rawdan Json.Encodetanpa tanda kutip.

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

Hasil adalah Obyek Javascript yang valid

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

masukkan deskripsi gambar di sini

7) Menggunakan Html.Rawdan Json.Encodedalam kutipan.

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

masukkan deskripsi gambar di sini

Seperti yang Anda lihat, pembungkus dengan kutipan memberi kita data JSON

Kesimpulan pada penugasan Objek

  • Gunakan Html.Rawdan Json.Encodedalam kombinasi untuk menetapkan objek Anda ke variabel javascript sebagai objek JavaScript .
  • Gunakan Html.Rawdan Json.Encodebungkus juga quotesuntuk mendapatkan JSON

Catatan: Jika Anda telah mengamati format data DataTime tidak benar. Ini karena seperti yang dikatakan sebelumnya Converts a data object to a string that is in the JavaScript Object Notation (JSON) formatdan JSON tidak mengandung datetipe. Pilihan lain untuk memperbaiki ini adalah dengan menambahkan baris lain kode untuk menangani jenis ini saja menggunakan javascipt Tanggal () objek

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


Cara mengakses data Model dalam blok kode Javascript / Jquery dalam .jsfile

Sintaks Razor tidak memiliki arti dalam .jsfile dan karenanya kami tidak dapat secara langsung menggunakan Model kami sebagai .jsfile. Namun ada solusinya.

1) Solusi menggunakan variabel Global javascript .

Kami harus menetapkan nilai ke variabel javascipt lingkup global dan kemudian menggunakan variabel ini dalam semua blok kode Anda .cshtmldan .jsfile. Jadi sintaksnya adalah

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

Dengan ini di tempat kita dapat menggunakan variabel userObjdan userJsonObjsebagai dan bila diperlukan.

Catatan: Saya pribadi tidak menyarankan menggunakan variabel global karena sangat sulit untuk pemeliharaan. Namun jika Anda tidak memiliki pilihan lain maka Anda dapat menggunakannya dengan memiliki konvensi penamaan yang tepat .. sesuatu seperti userAppDetails_global.

2) Menggunakan fungsi () atau closure Bungkus semua kode yang tergantung pada data model dalam suatu fungsi. Dan kemudian jalankan fungsi ini dari .cshtmlfile.

external.js

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

.cshtml mengajukan

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

Catatan: File eksternal Anda harus dirujuk sebelum skrip di atas. Lain yang userDataDependentfungsi tidak terdefinisi.

Perhatikan juga bahwa fungsi tersebut harus berada dalam lingkup global juga. Jadi salah satu solusi kita harus berurusan dengan pemain yang memiliki cakupan global.

Rajshekar Reddy
sumber
Bisakah properti Model diperbarui dalam javascript dan dikirim ke metode tindakan pengontrol?
@sortnoun ya Anda bisa, Anda dapat mengirim kembali data yang dimodifikasi dari formulir, Atau jika Anda tidak ingin memuat ulang halaman maka Anda dapat menggunakan AJAX
Rajshekar Reddy
Saya tidak menggunakan ajax, dan hanya mencoba memodifikasi properti model di javascript. tetapi saat mengirimkan formulir, perubahan ini tidak tercermin dalam model. Saya melakukan sesuatu seperti: var model = @ Html.Raw (Json.Encode (Model)); model.EventCommand = "updatedvalue"; Ini memberi saya model dengan benar dan nilai yang diperbarui, tetapi pada pengiriman perubahan tidak ada dalam metode tindakan. (Meskipun saya melakukan hal yang sama menggunakan kontrol Html tersembunyi dan mengikatnya ke EventCommand dan memperbarui nilainya dalam javascript. Tetapi bertanya-tanya apakah bisa melakukan hal yang sama secara langsung dengan model?)
@snoednoun Saya mengerti maksud Anda, var model = @Html.Raw(Json.Encode(Model));ini akan membuat objek javascript model yang tidak memiliki koneksi dengan C # Model yang Anda lewatkan . Infact tidak akan ada Modelsetelah tampilan telah diberikan. Jadi Formulir di UI tidak akan memiliki petunjuk tentang perubahan data objek javascript. Anda sekarang harus meneruskan seluruh model yang dimodifikasi ini ke controller melalui AJAX, Atau Anda perlu memperbarui nilai kontrol input Anda dalam bentuk menggunakan 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?untuk pernyataan ini .. tidak ada EventCommand di MVC, untuk Webforms di mana ada koneksi antara UI dan tindakan server, Dalam MVC semuanya terpisah. Satu-satunya cara bagi Anda untuk berinteraksi dengan pengontrol adalah melalui AJAX atau Formulir Kirim atau Permintaan halaman Baru (muat ulang juga)
Rajshekar Reddy
21

coba ini: (Anda melewatkan satu tanda kutip)

var floorplanSettings = '@Html.Raw(Json.Encode(Model.FloorPlanSettings))';
danmbuen
sumber
1
@JuanPieterse dengan kutipan memberi Anda JSONtanda kutip tanpa memberi Anda javascript Object. Periksa jawaban saya di utas yang sama untuk detail lebih lanjut. stackoverflow.com/a/41312348/2592042
Rajshekar Reddy
Itu tidak benar, solusi @danmbuen bekerja dalam kasus saya, saya punya masalah dan membungkusnya di antara tanda kutip tunggal bekerja seperti pesona, TERIMA KASIH;)
Dimitri
4

Membungkus properti model di sekitar parens bekerja untuk saya. Anda masih mendapatkan masalah yang sama dengan Visual Studio mengeluh tentang semi-colon, tetapi berhasil.

var closedStatusId = @(Model.ClosedStatusId);
FROgistics
sumber
0

Jika kesalahan "ReferenceError: Model tidak didefinisikan" dimunculkan, maka Anda dapat mencoba menggunakan metode berikut:

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

Semoga ini membantu...

Murat Yıldız
sumber
0

Saya tahu ini sudah terlambat tetapi solusi ini berfungsi sempurna untuk kedua kerangka .net dan .net inti:

@ System.Web.HttpUtility.JavaScriptStringEncode ()

Amer Jamaeen
sumber