183

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

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

10 回答 10

291

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

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

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

var floorplanSettings = @Html.Raw(Json.Encode(Model.FloorPlanSettings));
于 2013-05-03T14:33:26.417 回答
166

答案内容

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

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

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

有两种类型的 c# 变量 ( Model) 分配给 JavaScript 变量。

  1. 属性赋值- 基本数据类型,如int, string, DateTime(ex: 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;  

在此处输入图像描述

正如你所看到的,有几个错误,RajTrue认为是 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'; 

在此处输入图像描述

结果是有效的,因此将属性赋值用引号括起来给了我们有效的语法。但请注意,数字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.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"
 };

在此处输入图像描述

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

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

在此处输入图像描述

如您所见,用引号括起来为我们提供了JSON 数据

对象赋值的总结

  • 使用Html.RawJson.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) 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>

有了这个,我们可以在需要时使用变量userObjuserJsonObjas 。

注意:我个人不建议使用全局变量,因为它很难维护。但是,如果您没有其他选择,那么您可以通过适当的命名约定来使用它.. 类似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函数未定义。

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

于 2016-12-24T10:14:40.520 回答
23

试试这个:(你错过了单引号)

var floorplanSettings = '@Html.Raw(Json.Encode(Model.FloorPlanSettings))';
于 2014-01-23T14:16:16.647 回答
4

将模型属性包裹在括号周围对我有用。您仍然会遇到与 Visual Studio 抱怨分号相同的问题,但它确实有效。

var closedStatusId = @(Model.ClosedStatusId);
于 2013-10-14T16:19:45.420 回答
2

对于 MVC 4

@model Inventory.Models.PurchaseVModel
@{
    ViewData["Title"] = "Add";
    Layout = "~/Views/Shared/_Layout.cshtml";
    var jsonItems = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model.Items);
}

@section scripts{
    <script>
        $(document).ready(function () {
            var allItem =  @Html.Raw(jsonItems);
        console.log(allItem);
    });
    </script>
}

.Net 核心 3.1

@model Inventory.Models.PurchaseVModel
@{
    ViewData["Title"] = "Add";
    Layout = "~/Views/Shared/_Layout.cshtml";
    var jsonItems = Newtonsoft.Json.JsonConvert.SerializeObject(Model.Items);
}

@section scripts{
    <script>
        $(document).ready(function () {
            var allItem =  @Html.Raw(jsonItems);
        console.log(allItem);
    });
    </script>
}
于 2021-04-13T20:38:51.450 回答
2

我知道为时已晚,但此解决方案对 .net 框架和 .net 核心都适用:

@System.Web.HttpUtility.JavaScriptStringEncode()

于 2020-05-14T19:11:27.977 回答
1

如果出现“ReferenceError: Model is not defined”错误,那么您可以尝试使用以下方法:

$(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 ;
    }
});

希望这可以帮助...

于 2016-05-13T09:05:18.433 回答
1

所以这就是我们在 .net core razor 页面中的做法。

@section scripts
{
    <script>
        $(document).ready(function () {
            leaveStatusDictionary = @Html.Raw(Json.Serialize(Model.LeaveStatusDictionary));
        });

        function GetStatusName(status) {
            return window.leaveStatusDictionary[status];
        }
    </script>
}

请注意以下事项。

  1. 我在 leaveStatusDictionary 之前没有使用 var 关键字。所以这现在是窗口对象的一个​​属性。所以我能够在不同的 js 函数中访问它——你在那里看到的 GetStatusName。

  2. LeaveStatusDictionary 是 Dictionary<int, string> 类型模型类的一个属性。

于 2021-07-09T13:36:30.807 回答
1

除了@Rajshekar 的彻底回答,我更喜欢返回值的帮助方法,IHtmlStringRazor 将其识别为已编码的 HTML。然后,Html.Raw()不需要包装器,提高了可读性。

public static class JSHelper
{
    /// <summary>
    /// Encode a value as a JSON value or object for use in JavaScript code.
    /// </summary>
    /// <param name="value">Value to encode.</param>
    /// <returns>HTML string containing the JavaScript value or object.</returns>
    public static IHtmlString JsonEncode(object value)
    {
        return MvcHtmlString.Create(Json.Encode(value));
    }
}

然后我可以obj = @JSHelper.JsonEncode(myObject);在我的 JavaScript 部分中使用。

在视图中包含using子句或更新 view/web.config 以解析视图中的命名空间。

于 2021-06-18T13:42:59.517 回答
0

我使用以下内容将从 Razor 视图中的控制器传递的模型对象转换为 JavaScript 中的 JSON 对象。这在 ASP.Net Core 中非常适合我。

<script>
    let jsonData = @Html.Raw(Json.Serialize(Model))
    console.log(jsonData)
</script>
于 2021-12-20T17:18:07.967 回答