从 Javascript 访问 MVC 的模型属性

我在视图模型中包装了以下模型

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);
398357 次浏览

你可以把你的整个服务器端模型变成一个 Javascript 对象,方法如下:

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

在您的示例中,如果只想要 FloorPlanSettings 对象,只需传递 Encode方法 that 属性:

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

围绕括号包装模型属性对我来说很有用。在 VisualStudio 中,您仍然会遇到同样的问题,抱怨分号,但它是有效的。

var closedStatusId = @(Model.ClosedStatusId);

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

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

如果出现 “ 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 ;
}
});

希望这个能帮上忙。

答案内容

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

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

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

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

  1. 属性分配 -基本数据类型,如 intstringDateTime(ex: Model.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

可以看到有两个错误,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';

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 而不更改其实体名称。

来自 译自: 美国《科学》杂志网站(http://msdn.microsoft.com/en-us/library/gg568896(v = vs. 99) .aspx)号文件

将 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数据现在被破坏了,这将破坏脚本。这个问题是因为我们使用单引号 '来包装数据,甚至数据也使用单引号。

我们可以用两种方法来解决这个问题。

1)使用双引号 " "包装 HTML 部分。因为内部数据只有单引号。(确保在用双引号包装之后,数据中也没有 ")

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

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

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

财产转让的结束

  • 对非数字 dataType 使用引号。
  • 不要对数值 dataType 使用引号。
  • 使用 Html.Raw按原样解释 HTML 数据。
  • 注意你的 HTML 数据要么转义服务器端的引号意思,要么在向 javascript 变量赋值期间使用不同于数据的引号。

对象分配

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

1) 不用引号包装对象赋值。

  var userObj = @Model;

enter image description here

当您为 javascript 变量分配一个 c # 对象时,该对象的 .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。用引号包装上面的语法也没有多大用处。我们只是在引号中得到相同的结果。

来自 译自: 美国《科学》杂志网站(http://msdn.microsoft.com/en-us/library/system.web.helpers.Json.Encode (v = vs. 111) .aspx)的文件

将数据对象转换为 JSON (JSON)格式的字符串。

正如你已经遇到了这个 entity Name问题与属性分配,如果你还记得,我们克服了它与使用 Html.Raw。让我们试试看。让我们结合 Html.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 数据

关于对象分配的结论

  • 结合使用 Html.RawJson.Encode将对象分配给 javascript 变量作为 JavaScript 对象
  • 使用 Html.RawJson.Encode也包装它在 quotes得到一个 JSON

注意: 如果您发现 DataTime 数据格式不正确。这是因为如前所述,Converts a data object to a string that is in the JavaScript Object Notation (JSON) format和 JSON 不包含 date类型。解决这个问题的其他方法是添加另一行代码,使用 一个 href = “ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global _ Objects/Date”rel = “ noReferrer”> javascipt Date () 对象单独处理这种类型

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


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

Razor 语法在 .js文件中没有任何意义,因此我们不能直接在 .js文件中使用 Model。然而,有一个变通办法。

1) 解决方案使用 全局变量

我们必须将这个值赋给一个全局作用域的 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) 使用 函数()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函数是未定义的。

还要注意,函数也必须在全局范围内。因此,无论哪种解决方案,我们都必须处理全球范围的参与者。

我知道这太晚了,但是这个解决方案对.net Framework 和.net core 来说都是完美的:

@ System. Web. HttpUtility.JavaScriptStringEncode ()

四级车祸

@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 Core 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>
}

除了@Rajshekar 的完整的 回答之外,我更喜欢一个助手方法,它返回一个 IHtmlString值,Razor 将其识别为已经编码的 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));
}
}

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

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

因此,这里是我们如何做到这一点在.net 核心剃须刀网页。

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


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

请注意以下内容。

  1. 在 leave StatusDictionary 之前我没有使用 var 关键字。这是 window 对象的一个属性。所以我能够在另一个 js 函数中访问它-GetStatusName。

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

我使用以下代码将 Razor 视图中的控制器传递的 Model 对象转换为 JavaScript 中的 JSON 对象。这在 ASP.Net Core 中对我非常有用。

<script>
let jsonData = @Html.Raw(Json.Serialize(Model))
console.log(jsonData)
</script>