从Javascript访问MVC的模型属性

Nul*_*nce 135 javascript c# asp.net-mvc jquery model

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

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; }
}
Run Code Online (Sandbox Code Playgroud)

如何从Javascript访问上述属性之一?

我试过这个,但我得到了"未定义"

var floorplanSettings = "@Model.FloorPlanSettings";
alert(floorplanSettings.IconsDirectory);
Run Code Online (Sandbox Code Playgroud)

Jus*_*son 216

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

var model = @Html.Raw(Json.Encode(Model));
Run Code Online (Sandbox Code Playgroud)

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

var floorplanSettings = @Html.Raw(Json.Encode(Model.FloorPlanSettings));
Run Code Online (Sandbox Code Playgroud)

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

Raj*_*ddy 112

答案的内容

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

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

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

ModelJavaScript变量有两种类型的c#variable()赋值.

  1. 财产分配 -基本数据类型一样int,string,DateTime(例如: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; }
}
Run Code Online (Sandbox Code Playgroud)

我们为这个模型分配的值是

AppUser appUser = new AppUser
{
    Name = "Raj",
    IsAuthenticated = true,
    LoginDateTime = DateTime.Now,
    Age = 26,
    UserIconHTML = "<i class='fa fa-users'></i>"
};
Run Code Online (Sandbox Code Playgroud)

财产分配

让我们使用不同的语法进行分配并观察结果.

1)不用引号括起属性赋值.

var Name = @Model.Name;  
var Age = @Model.Age;
var LoginTime = @Model.LoginDateTime; 
var IsAuthenticated = @Model.IsAuthenticated;   
var IconHtml = @Model.UserIconHTML;  
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

正如你所看到的,有几个错误,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'; 
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

结果是有效的,因此将属性赋值包装在引号中会为我们提供有效的语法.但请注意,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);
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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

来自文档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)';
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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

我们可以通过两种方法克服这个问题.

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

  var IconHtml = "@Html.Raw(Model.UserIconHTML)";
Run Code Online (Sandbox Code Playgroud)

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

  UserIconHTML = "<i class=\"fa fa-users\"></i>"
Run Code Online (Sandbox Code Playgroud)

财产分配的结论

  • 对非数字dataType使用引号.
  • 不要对数字dataType使用引号.
  • 用于Html.Raw按原样解释HTML数据.
  • 注意你的HTML数据要么转义服务器端的引号,要么在分配给javascript变量时使用与数据不同的引号.

对象分配

让我们使用不同的语法进行分配并观察结果.

1)不用引号括起对象赋值.

  var userObj = @Model; 
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

将ac#object分配给javascript变量.ToString()时,将分配该对象的值.因此上述结果.

2用引号括起对象赋值

var userObj = '@Model'; 
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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

   var userObj = @Html.Raw(Model); 
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

4)使用Html.Raw以及股价

   var userObj = '@Html.Raw(Model)'; 
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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;
              };
Run Code Online (Sandbox Code Playgroud)

我们确实看到了一些变化,我们看到我们的模型被解释为一个对象.但我们将这些特殊字符改为entity names.将上述语法包装在引号中也没什么用处.我们只是在引号内得到相同的结果.

来自Json.Encode()的文档

将数据对象转换为JavaScript Object Notation(JSON)格式的字符串.

因为你已经遇到entity Name了属性赋值的这个问题,如果你还记得我们用它来克服它Html.Raw.所以让我们尝试一下.让我们结合Html.RawJson.Encode

6)使用Html.RawJson.Encode不使用引号.

var userObj = @Html.Raw(Json.Encode(Model));
Run Code Online (Sandbox Code Playgroud)

结果是一个有效的Javascript对象

 var userObj = {"Name":"Raj",
     "IsAuthenticated":true,
     "LoginDateTime":"\/Date(1482573224421)\/",
     "Age":26,
     "UserIconHTML":"\u003ci class=\"fa fa-users\"\u003e\u003c/i\u003e"
 };
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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

var userObj = '@Html.Raw(Json.Encode(Model))';
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

如你所见,用引号包装给我们一个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
Run Code Online (Sandbox Code Playgroud)

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

Razor语法在.js文件中没有意义,因此我们不能直接使用我们的模型insisde .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>
Run Code Online (Sandbox Code Playgroud)

有了这个地方,我们可以利用变量userObjuserJsonObj到什么时候需要.

注意:我个人不建议使用全局变量,因为它很难维护.但是,如果您没有其他选项,那么您可以使用它具有正确的命名约定.类似于userAppDetails_global.

2)使用function()closure Wrap所有依赖于函数中模型数据的代码.然后从.cshtml文件中执行此函数.

external.js

 function userDataDependent(userObj){
  //.... related code
 }
Run Code Online (Sandbox Code Playgroud)

.cshtml 文件

 <script type="text/javascript">
  userDataDependent(@Html.Raw(Json.Encode(Model))); //execute the function     
</script>
Run Code Online (Sandbox Code Playgroud)

注意:必须在上述脚本之前引用外部文件.否则该userDataDependent函数未定义.

另请注意,该函数也必须在全局范围内.因此,无论采用哪种解决方案,我们都必须与全球范


dan*_*uen 20

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

var floorplanSettings = '@Html.Raw(Json.Encode(Model.FloorPlanSettings))';
Run Code Online (Sandbox Code Playgroud)


小智 5

将模型属性包裹在括号中对我有用。Visual Studio 仍然会遇到同样的问题,抱怨分号,但它有效。

var closedStatusId = @(Model.ClosedStatusId);
Run Code Online (Sandbox Code Playgroud)