web-dev-qa-db-ja.com

JavascriptファイルからMVC ViewBagオブジェクトにアクセスできますか?

MVCアプリケーションのjavascriptファイルから次のことを実行できますか?

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

現在、エラーがスローされます:

未定義のXML名@ViewBagへの参照

58
Abe Miessler

現在、これを行う方法はないと思います。 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」となり、同じ問題にすぐに戻ります。 (これは連鎖エンコーディングの古くからの困難です。)これを処理する最良の方法は、バックスラッシュと引用符を特別なものとして扱い、それらがallエスケープされていることを確認することです:

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

JavaScriptファイルではありません。
JavaScriptファイルにクラスを含めることができ、ビューでそのクラスの新しいインスタンスをインスタンス化してから、クラスコンストラクターでViewBag値を渡すことができます。

または、クラスではない場合、他の唯一の選択肢は、HTML要素でdata属性を使用し、Viewのプロパティに割り当てて、JSファイルで取得することです。

次の入力があると仮定します。

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

次に、JSファイルで次を使用して取得できます。

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

Html:

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

スクリプト内:

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

これを行うには、JavaScriptファイルをサーバー側で前処理する必要があります。基本的に、become何らかのASP.NETビューであり、ファイルを参照するscriptタグは、そのビューで応答するコントローラーアクションを参照する必要があります。

開けたくないワームの缶のように聞こえます。

JavaScriptはクライアント側であるため、クライアント側の要素に値を設定し、JavaScriptにそれと対話させるだけではどうでしょうか。おそらく間接的な追加のステップですが、JavaScriptビューを作成するよりも頭痛の種のように聞こえます。

このようなもの:

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

その後、外部JavaScriptファイルは、そのドキュメントのスコープ内でsomeValue JavaScript変数を参照できます。

あるいは:

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

その後、その非表示の入力にアクセスできます。

JavaScriptファイルを実際にビューとして使用できるようにするための本当に洗練された方法を考え出さない限り。それは確かに実行可能であり、私は準備完了あなたが持っている問題を考えることはできません(ビューエンジンが取得するため、本当にいビューコード以外非常に JavaScriptとRazorとは... ton of <text>マークアップを期待します)後でコードをサポートします。

5
David

あなたがこれをしようとすると、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インジェクション攻撃または実行時エラーの可能性があります。

1
JSideris

ビューを作成し、部分ビューとして返します。

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のインテリセンスがそれをJavaスクリプトとして読み取ります)

//<script>

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

//</script>

次に、最終ビューで、このようにjavascriptへの参照を追加できます。

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

次に、最終的なView ControllerでViewBagを作成/渡すことができ、javascriptでレンダリングされます。

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

それが役に立てば幸い。

1
OAK

.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>
1
bax 1188

コントローラーアクションで追加:

 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>
}
0
Savita