从 Javascript 访问 MVC 的模型属性

IT技术 c# javascript jquery asp.net-mvc model
2021-01-25 11:50:06

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

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);
6个回答

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

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

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

var floorplanSettings = @Html.Raw(Json.Encode(Model.FloorPlanSettings));
只是为了确认,没有必要添加 ; 到底呢?因为我确实收到了来自 VS 的提示,说明语句没有终止。但是当我尝试添加时;代码不运行
2021-03-15 11:50:06
如果模型是初始值(创建页面而不是编辑页面)并且遇到“参考错误:模型未定义”,则不起作用。
2021-03-16 11:50:06
对我来说这有效: var myModel = @{@Html.Raw(Json.Encode(Model));}
2021-03-18 11:50:06
在 ASP.Net Core 中,Json.Serialize()
2021-03-19 11:50:06
你知道吗,我在我的各种项目中也遇到了同样的错误。忽略它;它是 Visual Studio 试图提供帮助,但是,在这种情况下是错误的。发送到浏览器的结果 HTML 和脚本是正确的。
2021-04-08 11:50:06

答案的内容

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

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

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

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

  1. 财产分配-基本数据类型一样intstringDateTime(例如: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;  

在此处输入图片说明

正如你可以看到有几个错误的,Raj并且True被认为是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数据现在已损坏,这将破坏脚本。问题是因为我们使用单引号'来包装数据,甚至数据也有单引号。

我们可以通过两种方法解决这个问题。

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

在此处输入图片说明

7)在引号内使用Html.RawJson.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>

有了这个地方,我们可以利用变量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函数未定义。

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

@sortednoun 我明白你的意思,var model = @Html.Raw(Json.Encode(Model));这将创建一个javascript 对象 model,它与你传递给视图的 C# 模型没有联系。事实上Model,在视图被渲染后将不会有。所以 UI 中的 Form 将不知道 javascript 对象数据的变化。您现在需要通过 AJAX 将整个修改后的模型传递给控制器​​,或者您需要使用 javascript 在表单中更新输入控件的值。
2021-03-12 11:50:06
我没有使用 ajax,只是尝试在 javascript 中修改模型属性。但是在提交表单时,此更改未反映在模型中。我在做类似的事情: var model = @Html.Raw(Json.Encode(Model)); model.EventCommand = "更新值"; 它为我提供了正确的模型和更新的值,但在提交时,操作方法中缺少更改。(虽然我使用隐藏的 Html 控件做了同样的事情并将它绑定到 EventCommand 并在 javascript 中更新它的值。但想知道是否可以直接对模型做同样的事情?)
2021-03-19 11:50:06
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 中没有,它用于 Webforms,其中 UI 和服务器操作之间存在连接,在 MVC 中它全部分开。您与控制器交互的唯一方法是通过 AJAX 或表单提交或新页面请求(也重新加载)
2021-03-27 11:50:06
可以在 javascript 中更新模型属性并发送到控制器操作方法吗?
2021-03-29 11:50:06
@sortednoun 是的,您可以,您可以从表单提交修改后的数据,或者如果您不想重新加载页面,则可以使用 AJAX
2021-04-02 11:50:06

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

var floorplanSettings = '@Html.Raw(Json.Encode(Model.FloorPlanSettings))';
事实并非如此,@danmbuen 解决方案在我的情况下有效,我遇到了问题并将其包裹在单引号之间就像一种魅力,谢谢;)
2021-03-31 11:50:06
仅当 json 字符串中没有嵌套单引号时,用单引号括起来才有效
2021-04-01 11:50:06
@JuanPieterse 带引号给你一个JSON没有引号给你一个javascript Object. 查看我在同一线程中的答案以获取更多详细信息。stackoverflow.com/a/41312348/2592042
2021-04-04 11:50:06

围绕 parens 包装模型属性对我有用。您仍然会遇到 Visual Studio 抱怨分号的相同问题,但它有效。

var closedStatusId = @(Model.ClosedStatusId);

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

@System.Web.HttpUtility.JavaScriptStringEncode()

不完美。这适用于字符串,但不适用于其他类型。但是 +1 表示另一种选择。
2021-04-01 11:50:06