从 Javascript 访问 MVC 的模型属性

2022-08-30 01:37:43

我有以下模型,它被包装在我的视图模型中

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

答案 1

您可以通过执行以下操作来获取整个服务器端模型并将其转换为Javascript对象:

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

在您的情况下,如果您只需要 FloorPlanSettings 对象,只需传递该属性的方法:Encode

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

答案 2

答案内容

1) 如何在文件中访问 Javascript/Jquery 代码块中的模型数据.cshtml

2) 如何在文件中访问 Javascript/Jquery 代码块中的模型数据.js

如何访问 .cshtml 文件中的 Javascript/Jquery 代码块中的模型数据

有两种类型的 c# 变量 () 赋值到 JavaScript 变量。Model

  1. 属性赋值 - 基本数据类型,如 、 、(例如:intstringDateTimeModel.Name)
  2. 对象赋值 - 自定义或内置类(例如:、ModelModel.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;  

enter image description here

如您所见,有几个错误,并且被认为是javascript变量,并且由于它们不存在,因此它是一个错误。对于 dateTime 可变性,错误是数字不能有特殊字符,HTML 标记将转换为其实体名称,以便浏览器不会混淆您的值和 HTML 标记。RajTruevariable undefinedunexpected number

2) 在引号中包装属性赋值。

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

enter image description here

结果是有效的,因此将属性赋值括在引号中为我们提供了有效的语法。但请注意,数字现在是一个字符串,因此,如果您不希望,我们可以删除引号,它将呈现为数字类型。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);

enter image description here

结果类似于我们的测试用例 1。然而,在字符串上使用确实向我们展示了一些变化。HTML 将保留,而不更改为其实体名称。@Html.Raw()HTML

来自 docs 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)';

enter image description here

所有类型的结果都很好。但是我们的数据现在已经损坏了,这将破坏脚本。问题是因为我们使用单引号来包装数据,甚至数据也有单引号。HTML'

我们可以通过2种方法克服这个问题。

1)使用双引号包装HTML部分。由于内部数据只有单引号。(确保用双引号换行后,数据中也没有)" ""

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

2)转义服务器端代码中的字符含义。喜欢

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

财产转让的结束

  • 对非数字数据类型使用引号。
  • 不要对数值数据类型使用引号。
  • 用于按原样解释 HTML 数据。Html.Raw
  • 照顾好你的HTML数据,要么在服务器端转义引号的含义,要么在分配给javascript变量期间使用与数据不同的引号。

对象分配

让我们使用不同的语法进行赋值并观察结果。

1) 不将对象赋值括在引号中。

  var userObj = @Model; 

enter image description here

当您将 c# 对象分配给 javascript 变量时,将分配该 oject 的值。因此,上述结果。.ToString()

2 用引号括起来对象赋值

var userObj = '@Model'; 

enter image description here

3)使用不带引号。Html.Raw

   var userObj = @Html.Raw(Model); 

enter image description here

4) 与引号一起使用Html.Raw

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

enter image description here

在将对象分配给变量时,这对我们没有多大用处。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 NameHtml.RawHtml.RawJson.Encode

6)使用和不带引号。Html.RawJson.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"
 };

enter image description here

7) 使用引号和在引号内。Html.RawJson.Encode

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

enter image description here

如您所见,用引号包装为我们提供了一个JSON数据

对象赋值

  • 使用 和 在组合中将你的对象作为 JavaScript 对象分配给 javascript 变量。Html.RawJson.Encode
  • 使用并包装它以获取JSONHtml.RawJson.Encodequotes

注意:如果您已经观察到 DataTime 数据格式不正确。这是因为如前所述,JSON 不包含类型。解决此问题的其他选项是添加另一行代码以使用javascipt Date()对象单独处理此类型Converts a data object to a string that is in the JavaScript Object Notation (JSON) formatdate

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


如何在文件中访问 Javascript/Jquery 代码块中的模型数据.js

Razor 语法在文件中没有任何意义,因此我们不能直接使用我们的模型 insisde 文件。但是,有一个解决方法。.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

另请注意,该函数也必须在全局范围内。因此,无论哪种解决方案,我们都必须与全球范围的参与者打交道。