Доступ к свойству модели MVC из Javascript


148

У меня есть следующая модель, которая обернута в мою модель зрения

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

Как получить доступ к одному из вышеуказанных свойств из Javascript?

Я пытался это, но я получил "неопределенный"

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

5
Просто чтобы быть ясно, что происходит, вы устанавливаете значение переменной JavaScript в значение переменной C # "Model.FloorPlanSettings", которая будет значением .ToString () этого класса (строка). Затем вы пытаетесь предупредить свойство JavaScript с именем «IconsDirectory» в только что созданной строковой переменной JavaScript. Вы получаете неопределенное значение, потому что строка JavaScript не имеет свойства IconsDirectory.
Джоэл Кокран

Предоставил полный контрольный пример и объяснил все сценарии назначения данных модели переменной javascript,
Раджшекар Редди

Это не работает за пределами представления (cshtml). то есть во внешнем файле .js, на который ссылается представление.
Спенсер Салливан

Ответы:


240

Вы можете взять всю свою серверную модель и превратить ее в объект Javascript, выполнив следующие действия:

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

В вашем случае, если вы просто хотите получить объект FloorPlanSettings, просто передайте Encodeметод этому свойству:

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

1
Просто чтобы подтвердить, нет необходимости добавлять; в конце этого? Поскольку я получаю подсказку от VS, заявляющую, что утверждение не прекращено. Но когда я пытаюсь добавить; код не запускается
Null Reference

1
Что вы знаете, у меня такая же ошибка в моих различных проектах. Просто игнорируй это; Visual Studio пытается помочь, но в данном случае это неправильно. Полученный HTML-код и скрипт, отправляемый в браузер, верны.
Джастин Хелгерсон

1
Для меня это сработало: var myModel = @ {@ Html.Raw (Json.Encode (Model));}
скрыто

1
Не работает, если модель имеет начальное значение (страница «Создать» вместо страницы «Правка») и «ReferenceError: Модель не определена».
Джек,

2
В ASP.Net Core, Json.Serialize ()
Мохаммед Нурельдин,

131

Содержание ответа

1) Как получить доступ к данным модели в блоке кода Javascript / Jquery в .cshtmlфайле

2) Как получить доступ к данным модели в блоке кода Javascript / Jquery в .jsфайле

Как получить доступ к данным модели в блоке кода Javascript / Jquery в .cshtmlфайле

Существует два типа Modelприсвоения переменной c # ( ) переменной JavaScript.

  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считаются переменными javascript, и, поскольку они не существуют, это variable undefinedошибка. Если для переменной dateTime ошибка состоит в том, что 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'; 

введите описание изображения здесь

Результаты действительны, поэтому перенос свойства в кавычки дает нам правильный синтаксис. Но обратите внимание, что Number 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, чтобы избежать кавычек, означающих на стороне сервера, или использовать другую кавычку, чем в данных, во время присваивания переменной javascript.

Назначение объекта

Давайте использовать другой синтаксис для присваивания и наблюдать за результатами.

1) Без переноса объекта в кавычки.

  var userObj = @Model; 

введите описание изображения здесь

Когда вы присваиваете объект ac # переменной javascript .ToString(), будет назначено значение этого объекта. Отсюда и вышеприведенный результат.

2 Заключение объекта в кавычки

var userObj = '@Model'; 

введите описание изображения здесь

3) Использование 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 ()

Преобразует объект данных в строку в формате нотации объектов JavaScript (JSON).

Поскольку вы уже сталкивались с этой entity Nameпроблемой при назначении свойств, и, если вы помните, мы преодолели ее с помощью Html.Raw. Итак, давайте попробуем это. Позволяет объединить Html.RawиJson.Encode

6) Использование Html.Rawи Json.Encodeбез кавычек.

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

Результат является допустимым объектом Javascript

 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.Encodeв сочетании, чтобы назначить свой объект переменной javascript как объект JavaScript .
  • Используйте, Html.Rawа Json.Encodeтакже оберните его внутри, quotesчтобы получить JSON

Примечание. Если вы заметили, что формат данных DataTime неверен. Это потому, что, как было сказано ранее, Converts a data object to a string that is in the JavaScript Object Notation (JSON) formatJSON не содержит dateтип. Другие варианты , чтобы исправить это , чтобы добавить еще одну строку кода для обработки этого типа в одиночку , используя Javascipt Дата) ( объект

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


Как получить доступ к данным модели в блоке кода Javascript / Jquery в .jsфайле

Синтаксис Razor не имеет значения в .jsфайле, и, следовательно, мы не можем напрямую использовать нашу модель в .jsфайле. Однако есть обходной путь.

1) Решение использует глобальные переменные javascript .

Мы должны присвоить значение глобальной переменной 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 Wrap весь код, который зависит от данных модели в функции. И затем выполните эту функцию из .cshtmlфайла.

external.js

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

.cshtml файл

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

Примечание: Ваш внешний файл должен быть указан до сценария выше. В противном случае userDataDependentфункция не определена.

Также обратите внимание, что функция также должна находиться в глобальной области видимости. Таким образом, любое решение нам приходится иметь дело с глобальными игроками.


Можно ли обновить свойство Model в javascript и отправить в метод действия контроллера?

@sortednoun да, вы можете, вы можете отправить измененные данные из формы, или, если вы не хотите перезагружать страницу, вы можете использовать AJAX
Rajshekar Reddy

Я не использовал ajax, а просто попытался изменить свойство модели в javascript. но при отправке формы это изменение не было отражено в модели. Я делал что-то вроде: var model = @ Html.Raw (Json.Encode (Model)); model.EventCommand = "updatedvalue"; Он дал мне модель правильно и обновил значение, но при отправке изменения отсутствовал в методе действия. (Хотя я сделал то же самое, используя скрытый элемент управления Html, связал его с EventCommand и обновил его значение в javascript. Но мне интересно, может ли он сделать то же самое непосредственно для модели?)

@ sortednoun Я понял вашу точку зрения, var model = @Html.Raw(Json.Encode(Model));это создаст объект javascript, model который не имеет никакого отношения к C # Model, которую вы передаете представлению. Infact не будет Modelпосле того, как представление было предоставлено. Таким образом, форма в пользовательском интерфейсе не будет иметь никакого представления об изменениях данных объекта javascript. Теперь вам нужно передать всю эту измененную модель в контроллер через AJAX, или вам нужно обновить значение ваших элементов управления вводом с помощью формы, используя javascript.
Раджшекар Редди

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, где есть связь между пользовательским интерфейсом и действиями сервера, в MVC все это разделено. Единственный способ для вас взаимодействовать с контроллером - через AJAX или
отправку

21

попробуйте это: (вы пропустили одинарные кавычки)

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

1
@JuanPieterse с кавычками дает вам JSONбез кавычек дает вам javascript Object. Проверьте мой ответ в той же теме для более подробной информации. stackoverflow.com/a/41312348/2592042
Раджшекар Редди

Это неправда, решение @danmbuen сработало в моем случае, у меня возникли проблемы, и завершение его в одинарные кавычки работало как чудо, СПАСИБО;)
Дмитрий

4

Обертывание свойства модели вокруг паренов работало на меня. Вы все еще получаете ту же проблему с Visual Studio, жалуясь на точку с запятой, но это работает.

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 framework, так и для ядра .net:

@ System.Web.HttpUtility.JavaScriptStringEncode ()

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.