Подтвердить что ты не робот

Можно ли получить доступ к объекту MVC ViewBag из файла Javascript?

Можно ли сделать следующее из файла javascript в приложении MVC?

$(function(){
   alert(@ViewBag.someValue);
}

В настоящее время он выдает ошибку:

ссылка на undefined XML-имя @ViewBag

4b9b3361

Ответ 1

Я не верю, что в настоящее время есть какой-то способ сделать это. Двигатель Razor не анализирует файлы Javascript, а только Razor. Однако вы можете выполнить то, что вы хотите, установив переменные внутри вашего вида Razor:

<script>
  var someStringValue = '@(ViewBag.someStringValue)';
  var someNumericValue = @(ViewBag.someNumericValue);
</script>
<!-- "someStringValue" and "someNumericValue" will be available in script -->
<script src="js/myscript.js"></script>

Как отмечает Joe в комментариях, строковое значение выше будет ломаться, если в нем будет одна цитата. Если вы хотите сделать это полностью утюгом, вам придется заменить все одинарные кавычки на экранированные одиночные кавычки. Проблема в том, что все внезапные косые черты становятся проблемой. Например, если ваша строка "foo \' bar", и вы заменяете одиночную кавычку, то выйдет "foo \\' bar", и вы вернетесь к той же проблеме. (Это возрастная сложность кодированного кодирования). Лучший способ справиться с этим - относиться к обратным косым чертам и кавычкам как к специальным и убедиться, что они все экранированы:

  @{
      var safeStringValue = ViewBag.someStringValue
          .Replace("\\", "\\\\")
          .Replace("'", "\\'");
  }
  var someStringValue = '@(safeStringValue)';

Ответ 2

Не в файле JavaScript, нет.
Ваш файл JavaScript может содержать класс, и вы можете создать экземпляр нового экземпляра этого класса в представлении, тогда вы можете передать значения ViewBag в конструкторе класса.

Или, если это не класс, ваша единственная альтернатива - использовать атрибуты data в ваших HTML-элементах, назначить их свойствам в вашем представлении и получить их в JS файле.

Предполагая, что у вас есть этот вход:

<input type="text" id="myInput" data-myValue="@ViewBag.MyValue" />

Затем в вашем JS файле вы можете получить его, используя:

var myVal = $("#myInput").data("myValue");

Ответ 3

Для этого ваш файл JavaScript должен быть предварительно обработан на стороне сервера. По существу, он должен был стать представлением ASP.NET для определенного типа, а теги script, которые ссылаются на файл, по существу будут ссылаться на действие контроллера, которое отвечает на это представление.

Это похоже на банку червей, которую вы не хотите открывать.

Поскольку JavaScript является клиентским, почему бы просто не установить значение для некоторого элемента на стороне клиента и связать с ним JavaScript. Это, возможно, дополнительный шаг косвенности, но это звучит гораздо меньше, чем головная боль, чем создание представления JavaScript.

Что-то вроде этого:

<script type="text/javascript">
    var someValue = @ViewBag.someValue
</script>

Затем внешний файл JavaScript может ссылаться на переменную JavaScript someValue в пределах области действия этого документа.

Или даже:

<input type="hidden" id="someValue" value="@ViewBag.someValue" />

Затем вы можете получить доступ к этому скрытому вводу.

Если вы не придумаете какой-нибудь действительно гладкий способ сделать ваш файл JavaScript пригодным для использования в качестве представления. Это, безусловно, выполнимо, и я не могу с готовностью думать о каких-либо проблемах, которые у вас были бы (кроме действительно уродливого кода просмотра, так как механизм просмотра будет очень запутан в отношении того, что JavaScript и что такое Razor... так что ожидайте тонну <text> markup), поэтому, если вы обнаружите гладкий способ сделать это, это будет довольно круто, хотя, возможно, неинтуитивно для кого-то, кто нуждается в поддержке кода позже.

Ответ 4

в Html:

<input type="hidden" id="customInput" data-value = "@ViewBag.CustomValue" />

в Script:

var customVal = $("#customInput").data("value");

Ответ 5

Используйте этот код в файле .cshtml.

 @{
    var jss = new System.Web.Script.Serialization.JavaScriptSerializer();
    var val = jss.Serialize(ViewBag.somevalue); 
    }

    <script>
        $(function () {
            var val = '@Html.Raw(val)';
            var obj = $.parseJSON(val);
            console.log(0bj);
    });
    </script>

Ответ 6

Создайте представление и верните его как частичный вид:

public class AssetsController : Controller
{
    protected void SetMIME(string mimeType)
    {
        this.Response.AddHeader("Content-Type", mimeType);
        this.Response.ContentType = mimeType;
    }

    // this will render a view as a Javascript file
    public ActionResult GlobalJS()
    {
        this.SetMIME("text/javascript");
        return PartialView();
    }
}

Затем в представлении GlobalJS добавьте код javascript, например (добавление//сделает visual studio intellisense прочитанным как java- script)

//<script>

    $(document).ready(function () {
       alert('@ViewBag.PropertyName');
    }); 

//</script>

Затем в вашем последнем представлении вы можете добавить ссылку на javascript именно так.

<script src="@Url.Action("GlobalJS", "Assets")"></script> 

Затем в вашем конечном контроллере можно создать/передать свои ViewBags, и он будет отображаться в вашем javascript.

public class MyFinalViewController : Controller
{
    public ActionResult Index()
    {
        ViewBag.PropertyName = "My ViewBag value!";
        return View();
    }
}

Надеюсь, что это поможет.

Ответ 7

Я заметил, что встроенный детектор ошибок Visual Studio становится тупым, если вы попытаетесь это сделать:

var intvar = @(ViewBag.someNumericValue);

Потому что @(ViewBag.someNumericValue) может оценивать до нуля, что приведет к созданию следующего ошибочного JavaScript:

var intvar = ;

Если вы уверены, что someNemericValue будет установлен на допустимый числовой тип данных, вы можете избежать наличия предупреждений Visual Studio, выполнив следующие действия:

var intvar = Number(@(ViewBag.someNumericValue));

Это может сгенерировать следующий пример:

var intvar = Number(25.4);

И он работает для отрицательных чисел. В случае, если элемент не находится в вашей сумке просмотра, Number() принимает значение 0.

Больше предупреждений Visual Studio! Но убедитесь, что значение установлено и является числовым, иначе вы откроете двери для возможных атак JavaScript-инъекций или ошибок времени выполнения.

Ответ 8

В действии контроллеров добавьте:

 public ActionResult Index()
        {
            try
            {
                int a, b, c;
                a = 2; b = 2;
                c = a / b;
                ViewBag.ShowMessage = false;
            }
            catch (Exception e)
            {
                ViewBag.ShowMessage = true;
                ViewBag.data = e.Message.ToString();
            }
            return View();    // return View();

        }

in Index.cshtml
Place at the bottom:

<input type="hidden" value="@ViewBag.data" id="hdnFlag" />

@if (ViewBag.ShowMessage)
{
    <script type="text/javascript">

        var h1 = document.getElementById('hdnFlag');

        alert(h1.value);

    </script>
    <div class="message-box">Some Message here</div>
}