जावास्क्रिप्ट से एमवीसी की मॉडल संपत्ति तक पहुँचना


147

मेरे पास निम्नलिखित मॉडल है जो मेरे दृश्य मॉडल में लिपटे हुए हैं

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

मैं जावास्क्रिप्ट से उपरोक्त गुणों में से एक का उपयोग कैसे करूं?

मैंने यह कोशिश की, लेकिन मुझे "अपरिभाषित" मिला

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

5
बस स्पष्ट होने के लिए, कि आप क्या कर रहे हैं, आप जावास्क्रिप्ट चर का मान C # चर "Model.FloorPlanSettings" के मान पर सेट कर रहे हैं, जो उस वर्ग (एक स्ट्रिंग) का .ToString () मान होगा। फिर आप अपने द्वारा बनाए गए जावास्क्रिप्ट स्ट्रिंग चर पर "आइकन्सडायरेक्टरी" नामक एक जावास्क्रिप्ट संपत्ति को सचेत करने की कोशिश कर रहे हैं। आप अपरिभाषित हो जाते हैं क्योंकि एक जावास्क्रिप्ट स्ट्रिंग में "आईकॉनडायरेक्टरी" संपत्ति नहीं है।
जोएल कोचरन

एक पूरा परीक्षण मामला प्रदान किया और जावास्क्रिप्ट चर के लिए मॉडल डेटा असाइन करने के सभी परिदृश्यों को समझाया,
राजशेखर रेड्डी

यह दृश्य के बाहर काम नहीं करता है (cshtml)। बाहरी .js फ़ाइल में अर्थात दृश्य द्वारा संदर्भित।
स्पेंसर सुलिवन

जवाबों:


240

आप अपना संपूर्ण सर्वर-साइड मॉडल ले सकते हैं और इसे निम्न करके जावास्क्रिप्ट ऑब्जेक्ट में बदल सकते हैं:

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

अपने मामले में यदि आप केवल फ्लोरप्लेनसेटिंग ऑब्जेक्ट चाहते हैं, तो बस उस Encodeविधि को पास करें :

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

1
बस पुष्टि करने के लिए, कोई जोड़ने की आवश्यकता नहीं है; इसके अंत में? क्योंकि मुझे वीएस से एक संकेत मिलता है जिसमें कथन को समाप्त नहीं किया गया है। लेकिन जब मैं जोड़ने की कोशिश करता हूं; कोड नहीं चलता है
Null Reference

1
आप क्या जानते हैं, मुझे अपनी विभिन्न परियोजनाओं में भी यही त्रुटि मिली है। बस इसे नजरअंदाज करें; यह दृश्य स्टूडियो मदद करने की कोशिश कर रहा है, लेकिन, यह इस मामले में गलत है। परिणामी HTML और स्क्रिप्ट जो ब्राउज़र को भेजी जाती है वह सही है।
जस्टिन हेगर्सन

1
मेरे लिए यह काम किया: var myModel = @ {@ Html.Raw (Json.Encode (Model));}
छिपा हुआ

1
यदि मॉडल प्रारंभिक मूल्य है तो काम नहीं कर रहा है (एडिट पेज के बजाय पेज बनाएं) और "संदर्भError: मॉडल परिभाषित नहीं है" का सामना करना पड़ा है।
जैक

2
ASP.Net कोर, Json.Serialize ()
मोहम्मद नौरेल्डिन

131

उत्तर की सामग्री

1) जावास्क्रिप्ट / Jquery कोड ब्लॉक में मॉडल डेटा को .cshtmlफ़ाइल में कैसे एक्सेस करें

2) .jsफ़ाइल में जावास्क्रिप्ट / जक्वेरी कोड ब्लॉक में मॉडल डेटा का उपयोग कैसे करें

.cshtmlफ़ाइल में जावास्क्रिप्ट / जक्वेरी कोड ब्लॉक में मॉडल डेटा का उपयोग कैसे करें

Modelजावास्क्रिप्ट चर के लिए दो प्रकार के सी # चर ( ) असाइनमेंट हैं।

  1. संपत्ति काम - मूल डेटाटाइप्स चाहते int, string, DateTime(पूर्व: Model.Name)
  2. वस्तु काम - कस्टम या इनबिल्ट वर्गों (पूर्व: Model, Model.UserSettingsObj)

आइए इन दोनों असाइनमेंट के विवरण पर ध्यान दें।

शेष उत्तर के लिए नीचे दिए गए AppUserमॉडल को एक उदाहरण के रूप में मानें।

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

और जिन मूल्यों को हम इस मॉडल को निर्दिष्ट करते हैं वे हैं

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

संपत्ति का काम

असाइनमेंट के लिए विभिन्न सिंटैक्स का उपयोग करें और परिणाम देखें।

1) उद्धरण में संपत्ति असाइनमेंट को लपेटे बिना।

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

यहाँ छवि विवरण दर्ज करें

जैसा कि आप देख सकते हैं कि कुछ त्रुटियां हैं, Rajऔर Trueउन्हें जावास्क्रिप्ट चर माना जाता है और चूंकि वे एक variable undefinedत्रुटि मौजूद नहीं हैं । जहाँ तक डेटाइम वेरिएबल के लिए त्रुटि है, unexpected numberसंख्याओं में विशेष वर्ण नहीं हो सकते हैं, HTML टैग्स को इसके निकाय नामों में परिवर्तित किया जाता है ताकि ब्राउज़र आपके मूल्यों और HTML मार्कअप को न मिलाए।

2) कोट्स में संपत्ति असाइनमेंट लपेटना।

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

यहाँ छवि विवरण दर्ज करें

परिणाम मान्य हैं, इसलिए उद्धरणों में संपत्ति असाइनमेंट को लपेटने से हमें वैध वाक्यविन्यास मिलता है। लेकिन ध्यान दें कि संख्या Ageअब एक स्ट्रिंग है, इसलिए यदि आप नहीं चाहते हैं कि हम केवल उद्धरण हटा सकते हैं और इसे एक नंबर प्रकार के रूप में प्रदान किया जाएगा।

3) का उपयोग करना, @Html.Rawलेकिन उद्धरण में लपेटे बिना

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

यहाँ छवि विवरण दर्ज करें

परिणाम हमारे परीक्षण के मामले के समान हैं। 1. हालांकि स्ट्रिंग @Html.Raw()पर उपयोग करने से HTMLहमें कुछ बदलाव दिखा। HTML को उसके निकाय नामों में बदले बिना बरकरार रखा गया है।

डॉक्स से Html.Raw ()

HTML मार्कअप को एक HtmlString उदाहरण में लपेटता है ताकि इसे HTML मार्कअप के रूप में समझा जाए।

लेकिन फिर भी हमारे पास अन्य लाइनों में त्रुटियां हैं।

4) का उपयोग करना @Html.Rawऔर उद्धरण के भीतर भी लपेटना

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

यहाँ छवि विवरण दर्ज करें

परिणाम सभी प्रकार के साथ अच्छे हैं। लेकिन हमारा HTMLडेटा अब टूट गया है और इससे स्क्रिप्ट टूट जाएगी। मुद्दा यह है क्योंकि हम 'डेटा को लपेटने के लिए सिंगल कोट्स का उपयोग कर रहे हैं और यहां तक ​​कि डेटा के सिंगल कोट्स भी हैं।

हम 2 दृष्टिकोणों के साथ इस मुद्दे को दूर कर सकते हैं।

1) " "HTML भाग को लपेटने के लिए दोहरे उद्धरण चिह्नों का उपयोग करें । जैसा कि आंतरिक डेटा में केवल एकल उद्धरण हैं। (यह सुनिश्चित करें कि दोहरे उद्धरण चिह्नों के बाद "भी डेटा के भीतर नहीं हैं)

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

2) अपने सर्वर साइड कोड में वर्ण अर्थ से बच। पसंद

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

संपत्ति असाइनमेंट का निष्कर्ष

  • गैर-संख्यात्मक डेटाटाइप के लिए उद्धरणों का उपयोग करें।
  • संख्यात्मक डेटा टाइप के लिए उद्धरणों का उपयोग न करें।
  • Html.Rawअपने HTML डेटा की व्याख्या करने के लिए उपयोग करें ।
  • अपने HTML डेटा का ध्यान रखें या तो सर्वर साइड में दिए गए उद्धरणों से बच सकते हैं, या जावास्क्रिप्ट चर के असाइनमेंट के दौरान डेटा की तुलना में एक अलग उद्धरण का उपयोग करें।

वस्तु का काम

असाइनमेंट के लिए विभिन्न सिंटैक्स का उपयोग करें और परिणाम देखें।

1) उद्धरणों में ऑब्जेक्ट असाइनमेंट को लपेटे बिना।

  var userObj = @Model; 

यहाँ छवि विवरण दर्ज करें

जब आप जावास्क्रिप्ट चर को एसी # ऑब्जेक्ट असाइन करते .ToString()हैं तो उस ओजेक्ट का मान असाइन किया जाएगा। इसलिए उपरोक्त परिणाम।

2 कोट्स में रैपिंग ऑब्जेक्ट असाइनमेंट

var userObj = '@Model'; 

यहाँ छवि विवरण दर्ज करें

३)Html.Raw बिना उद्धरण के उपयोग करना ।

   var userObj = @Html.Raw(Model); 

यहाँ छवि विवरण दर्ज करें

4)Html.Raw उद्धरण के साथ उपयोग करना

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

यहाँ छवि विवरण दर्ज करें

Html.Rawहमारे लिए कोई ज्यादा उपयोग की थी चर करने के लिए एक वस्तु बताए हैं।

5)Json.Encode() बिना उद्धरण के उपयोग करना

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

हम कुछ बदलाव देखते हैं, हम देखते हैं कि हमारे मॉडल को एक वस्तु के रूप में व्याख्यायित किया जा रहा है। लेकिन हमारे पास उन विशेष पात्रों को बदल दिया गया है entity names। इसके अलावा उद्धरण में उपरोक्त वाक्य रचना को लपेटने से कोई फायदा नहीं है। हम बस उद्धरण के भीतर एक ही परिणाम मिलता है।

Json.Encode () के डॉक्स से

एक डेटा ऑब्जेक्ट को एक स्ट्रिंग में जोड़ता है जो जावास्क्रिप्ट ऑब्जेक्ट नोटेशन (JSON) प्रारूप में है।

जैसा कि आप पहले से ही entity Nameसंपत्ति के असाइनमेंट के साथ इस मुद्दे का सामना कर चुके हैं और यदि आपको याद है कि हम इसके इस्तेमाल से आगे निकल गए हैं Html.Raw। तो चलो कोशिश करते हैं कि बाहर। चलो गठबंधन Html.RawऔरJson.Encode

6) का उपयोग करना Html.Rawऔर Json.Encodeउद्धरण के बिना।

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

परिणाम एक मान्य जावास्क्रिप्ट ऑब्जेक्ट है

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

यहाँ छवि विवरण दर्ज करें

7) उद्धरणों का उपयोग करना Html.Rawऔर Json.Encodeभीतर।

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

यहाँ छवि विवरण दर्ज करें

जैसा कि आप उद्धरण के साथ लपेटते हुए देखते हैं, हमें JSON डेटा देता है

ऑब्जेक्ट असाइनमेंट पर शामिल होना

  • का प्रयोग करें Html.Rawऔर Json.Encodecombintaion में के रूप में जावास्क्रिप्ट चर करने के लिए अपने वस्तु आवंटित करने के लिए जावास्क्रिप्ट वस्तु
  • JSON प्राप्त करने के लिए इसका उपयोग करें Html.Rawऔर Json.Encodeइसे भी लपेटेंquotes

नोट: यदि आपने देखा है DataTime डेटा प्रारूप सही नहीं है। ऐसा इसलिए है क्योंकि जैसा कि पहले कहा गया है Converts a data object to a string that is in the JavaScript Object Notation (JSON) formatऔर JSON में एक dateप्रकार नहीं है । इसे ठीक करने के लिए अन्य विकल्प हैं कि इस प्रकार के हैंडल को javascipt Date () ऑब्जेक्ट का उपयोग करने के लिए कोड की एक और लाइन जोड़ना है

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


.jsफ़ाइल में जावास्क्रिप्ट / जक्वेरी कोड ब्लॉक में मॉडल डेटा का उपयोग कैसे करें

रेजर सिंटैक्स का .jsफ़ाइल में कोई अर्थ नहीं है और इसलिए हम सीधे अपने मॉडल का उपयोग नहीं कर सकते हैं .js। हालाँकि एक समाधान है।

1) समाधान जावास्क्रिप्ट वैश्विक चर का उपयोग कर रहा है ।

हमें मान को एक वैश्विक स्कॉप्ड javascipt वैरिएबल पर असाइन करना होगा और फिर इस वेरिएबल का उपयोग अपनी .cshtmlऔर .jsफाइलों के सभी कोड ब्लॉक के भीतर करना होगा । तो वाक्य रचना होगी

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

इस स्थान में हम चर का उपयोग कर सकते हैं userObjऔर userJsonObjजब कभी जरूरत है।

नोट: मैं व्यक्तिगत रूप से वैश्विक चर का उपयोग करने का सुझाव नहीं देता क्योंकि यह रखरखाव के लिए बहुत कठिन हो जाता है। हालाँकि यदि आपके पास कोई अन्य विकल्प नहीं है तो आप इसे उचित नामकरण सम्मेलन के साथ उपयोग कर सकते हैं .. कुछ ऐसा userAppDetails_global

2) फ़ंक्शन का उपयोग करना () या closure किसी फ़ंक्शन में मॉडल डेटा पर निर्भर सभी कोड को लपेटें। और फिर .cshtmlफ़ाइल से इस फ़ंक्शन को निष्पादित करें ।

external.js

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

.cshtml फ़ाइल

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

नोट: आपकी बाहरी फ़ाइल को उपरोक्त स्क्रिप्ट से पहले संदर्भित किया जाना चाहिए। इसके अलावा userDataDependentफ़ंक्शन अपरिभाषित है।

यह भी ध्यान दें कि फ़ंक्शन वैश्विक दायरे में भी होना चाहिए। इसलिए या तो समाधान के लिए हमें वैश्विक स्तर के खिलाड़ियों से निपटना होगा।


क्या मॉडल संपत्ति को जावास्क्रिप्ट में अद्यतन किया जा सकता है और नियंत्रक क्रिया विधि को भेज सकता है?

@sreadnoun हाँ आप कर सकते हैं, आप एक फॉर्म से संशोधित डेटा वापस जमा कर सकते हैं, या यदि आप पृष्ठ को फिर से लोड नहीं करना चाहते हैं तो आप AJAX का उपयोग कर सकते हैं
राजशेखर रेड्डी

मैं अजाक्स का उपयोग नहीं कर रहा था, और सिर्फ जावास्क्रिप्ट में मॉडल संपत्ति को संशोधित करने की कोशिश की। लेकिन फार्म जमा करने पर यह परिवर्तन मॉडल में परिलक्षित नहीं हुआ। मैं कुछ ऐसा कर रहा था: var model = @ Html.Raw (Json.Encode (Model)); model.EventCommand = "अपडेट किया गया"; इसने मुझे सही ढंग से और अद्यतन मूल्य के लिए मॉडल दिया, लेकिन सबमिट करने पर कार्रवाई की विधि में परिवर्तन गायब था। (हालांकि मैंने वही काम किया जो छिपे हुए Html नियंत्रण का उपयोग करके किया था और EventCommand को बाध्य कर दिया और इसे जावास्क्रिप्ट में मान अपडेट कर दिया। लेकिन सोचता हूं कि क्या यह सीधे मॉडल पर कर सकता है?)

@sreadnoun मुझे आपकी बात मिल गई, var model = @Html.Raw(Json.Encode(Model));यह एक जावास्क्रिप्ट ऑब्जेक्ट बनाएगा modelजिसका सी # मॉडल के साथ कोई संबंध नहीं है जिसे आप दृश्य में पास करते हैं। Modelदेखने के लिए प्रस्तुत किए जाने के बाद कोई प्रभाव नहीं होगा । यूआई में फॉर्म को जावास्क्रिप्ट ऑब्जेक्ट डेटा परिवर्तनों पर कोई सुराग नहीं होगा। आपको अब इस पूरे संशोधित मॉडल को AJAX के माध्यम से नियंत्रक के पास भेजना होगा, या आपको जावास्क्रिप्ट का उपयोग करके अपने इनपुट नियंत्रण के मूल्य को फॉर्म में अपडेट करना होगा।
राजशेखर रेड्डी

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?इस कथन के लिए .. EventCommand MVC में कोई भी नहीं है, इसके Webforms के लिए जहां UI और सर्वर क्रियाओं के बीच एक संबंध है, MVC में यह सब अलग हो गया। आपके लिए कंट्रोलर के साथ बातचीत करने का एकमात्र तरीका AJAX या फ़ॉर्म सबमिट करें या नया पृष्ठ अनुरोध (पुनः लोड करें) है
राजशेखर रेड्डी

21

इसे आज़माएं: (आपने एकल उद्धरण याद किया)

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

1
@JuanPieterse उद्धरण के साथ आप एक JSONwihtout उद्धरण देता है आप एक javascript Object। अधिक जानकारी के लिए एक ही सूत्र में मेरे उत्तर की जाँच करें। stackoverflow.com/a/41312348/2592042
राजशेखर रेड्डी

यह सच नहीं है, @danmbuen सॉल्यूशन ने मेरे मामले में काम किया, मुझे मुद्दे मिले और सिंगल कोट्स के बीच इसे लपेटकर एक आकर्षण की तरह काम किया, THANK YOU;)
दिमित्री

4

Parens के आसपास मॉडल संपत्ति लपेटकर मेरे लिए काम किया। आपको अभी भी दृश्य स्टूडियो के साथ अर्ध-बृहदान्त्र के बारे में शिकायत के साथ एक ही मुद्दा मिलता है, लेकिन यह काम करता है।

var closedStatusId = @(Model.ClosedStatusId);

0

यदि "ReferenceError: मॉडल परिभाषित नहीं है" त्रुटि उठाई गई है, तो आप निम्न विधि का उपयोग करने का प्रयास कर सकते हैं:

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

उम्मीद है की यह मदद करेगा...


0

मुझे पता है कि यह बहुत देर हो चुकी है लेकिन यह समाधान .net फ्रेमवर्क और .net कोर दोनों के लिए एकदम सही काम कर रहा है:

@ System.Web.HttpUtility.JavaScriptStringEncode ()

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.