JavaScriptからMVCのモデルプロパティにアクセスする


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

JavaScriptから上記のプロパティの1つにアクセスするにはどうすればよいですか?

私はこれを試しましたが、「未定義」になりました

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

5
明確にするために、何が起こっているかというと、JavaScript変数の値をC#変数「Model.FloorPlanSettings」の値に設定しています。これは、そのクラスの.ToString()値(文字列)になります。次に、作成したJavaScript文字列変数の「IconsDirectory」というJavaScriptプロパティにアラートを送信しようとしています。JavaScript文字列には "IconsDirectory"プロパティがないため、未定義になります。
Joel Cochran、2013

完全なテストケースを提供し、モデルデータをJavaScript変数に割り当てるすべてのシナリオを説明しました
Rajshekar Reddy

これはビュー(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およびスクリプトは正しいです。
ジャスティンヘルガーソン2013年

1
私にとってこれはうまくいきました:var myModel = @ {@ Html.Raw(Json.Encode(Model));}
非表示

1
モデルが初期値(編集ページではなく作成ページ)で、「ReferenceError:モデルが定義されていません」が発生した場合、機能しません。
ジャック

2
ASP.Net Coreで、Json.Serialize()
Mohammed Noureldin 2018

131

回答の内容

1).cshtmlファイルのJavascript / Jqueryコードブロックのモデルデータにアクセスする方法

2).jsファイル内のJavascript / Jqueryコードブロックのモデルデータにアクセスする方法

.cshtmlファイルのJavascript / Jqueryコードブロックのモデルデータにアクセスする方法

ModelJavaScript変数へのc#変数()割り当てには2つのタイプがあります。

  1. プロパティの割り当て -などの基本データ型intstringDateTime(例:Model.Name
  2. オブジェクトの割り当て -カスタムまたは組み込みのクラス(例:ModelModel.UserSettingsObj

これら2つの割り当ての詳細を見てみましょう。

残りの回答については、以下の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がvarialbleの場合、エラーは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は、エンティティ名に変更を加えることなく保持されます。

docs Html.Raw()から

HtmlStringインスタンスでHTMLマークアップをラップして、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>"

プロパティ割り当ての結論

  • 非数値のdataTypeには引用符を使用します。
  • 数値のdataTypeには引用符を使用しないでください。
  • Html.RawHTMLデータをそのまま解釈するために使用します。
  • サーバー側で引用符の意味をエスケープするか、JavaScript変数への割り当て中にデータとは異なる引用符を使用するために、HTMLデータに注意してください。

オブジェクトの割り当て

割り当てに異なる構文を使用して、結果を観察してみましょう。

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 Object Notation(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.RawJson.Encodeとしてjavascriptの変数に、あなたのオブジェクトを割り当てるcombintaionでJavaScriptオブジェクト
  • JSONを取得するために使用Html.RawJson.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ファイルのJavascript / Jqueryコードブロックのモデルデータにアクセスする方法

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>

これで、変数userObjuserJsonObj必要に応じて使用できます。

注:グローバル変数はメンテナンスが非常に難しくなるため、個人的には使用しないことをお勧めします。ただし、他にオプションがない場合は、適切な命名規則を使用して使用できますuserAppDetails_global

2)function(を使用する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関数は未定義です。

また、関数もグローバルスコープ内にある必要があることに注意してください。したがって、どちらのソリューションも、グローバルスコープのプレーヤーに対処する必要があります。


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));これはあなたがビューに渡すC#モデルとの関連がないjavascriptオブジェクト modelを作成します。実際にはModel、ビューがレンダリングされた後はありません。そのため、UIのフォームには、JavaScriptオブジェクトデータの変更に関する手掛かりがありません。この変更されたモデル全体をAJAX経由でコントローラーに渡す必要があります。または、JavaScriptを使用するフォームで入力コントロールの値を更新する必要があります。
Rajshekar Reddy 2017

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 にはありません。UIとサーバーアクションの間に接続があるWebフォームの場合、MVCではすべて分離されます。コントローラーとやり取りする唯一の方法は、AJAXまたはフォーム送信または新しいページリクエスト(再
ロード

21

これを試してください:(あなたは単一引用符を逃しました)

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

1
引用符で@JuanPieterseはあなたに与えJSONwihtoutの引用はあなたなりますjavascript Object。詳細については、同じスレッドで私の答えを確認してください。stackoverflow.com/a/41312348/2592042
Rajshekar Reddy

それは真実ではありません、@ danmbuenソリューションは私の場合に機能しました、私は問題を抱えており、単一引用符
Dimitri

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フレームワークと.netコアの両方に最適です。

@ System.Web.HttpUtility.JavaScriptStringEncode()

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.