从Javascript访问MVC的模型属性


147

我的视图模型中包含以下模型

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

5
只需清楚一点,就是将JavaScript变量的值设置为C#变量“ Model.FloorPlanSettings”的值,该值将是该类的.ToString()值(字符串)。然后,您尝试在刚创建的JavaScript字符串变量上提醒一个名为“ IconsDirectory”的JavaScript属性。您未定义,因为JavaScript字符串没有“ IconsDirectory”属性。
乔尔·科克伦

提供了完整的测试用例,并说明了将模型数据分配给javascript变量的所有情况,
Rajshekar Reddy

这在视图(cshtml)之外不起作用。即在视图引用的外部.js文件中。
斯潘塞·沙利文

Answers:


240

您可以通过以下步骤将整个服务器端模型转换为Javascript对象:

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

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

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

1
只是为了确认,不需要添加;。在结尾吗?因为我确实从VS得到提示,说明该语句没有终止。但是当我尝试添加时;该代码无法运行
空引用,

1
您知道什么,我在各个项目中也遇到相同的错误。只是忽略它;是Visual Studio试图提供帮助,但是在这种情况下是错误的。发送到浏览器的结果HTML和脚本是正确的。
贾斯汀·赫尔格森2013年

1
对我来说,这可行:var myModel = @ {@ Html.Raw(Json.Encode(Model));}
隐藏

1
如果模型是初始值(“创建”页面而不是“编辑”页面)并且遇到“ ReferenceError:未定义模型”,则该模型不起作用。
杰克

2
在ASP.Net Core中,Json.Serialize()
Mohammed

131

答案的内容

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

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

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

ModelJavaScript变量有两种类型的c#变量()分配。

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

在此处输入图片说明

结果是有效的,因此将属性分配括在引号中可以提供有效的语法。但是请注意,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);

在此处输入图片说明

结果类似于我们的测试案例1。但是@Html.Raw()HTML字符串上使用确实显示了一些更改。保留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)';

在此处输入图片说明

所有类型的结果都很好。但是我们的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 Object Notation(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.RawJson.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文件中没有意义,因此我们不能直接使用Model坚持.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函数未定义。

还要注意,该功能也必须在全局范围内。因此,无论哪种解决方案,我们都必须应对全球范围内的参与者。


可以在javascript中更新Model属性并将其发送到控制器操作方法吗?

@sortednoun是的,您可以,您可以从表单中提交修改后的数据,或者,如果您不想重新加载页面,则可以使用AJAX
Rajshekar Reddy

我没有使用ajax,只是尝试在javascript中修改模型属性。但是在提交表单时,此更改未反映在模型中。我正在做类似的事情:var model = @ Html.Raw(Json.Encode(Model)); model.EventCommand =“ updatedvalue”; 它为我提供了正确的模型并更新了值,但是在提交时,操作方法中缺少更改。(尽管我使用隐藏的HTML控件做了同样的事情,并将其绑定到EventCommand并在javascript中更新了它的值。但是想知道是否可以直接对模型进行同样的操作吗?)

@sortednoun我明白了,var model = @Html.Raw(Json.Encode(Model));这将创建一个javascript对象 ,该对象model与传递给视图的C#模型没有任何关系。实际上,Model渲染视图后将没有任何结果。因此,UI中的Form不会对javascript对象数据的更改有所提示。您现在需要通过AJAX将整个修改后的模型传递给控制器​​,或者您需要使用javascript在表单中使用来更新输入控件的值。
Rajshekar Reddy

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或表单提交或新页面请求(也需要重新加载)
Rajshekar Reddy

21

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

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

1
@JuanPieterse与报价给你一个JSONwihtout报价给你一个javascript Object。在同一主题中查看我的答案以获取更多详细信息。stackoverflow.com/a/41312348/2592042
拉杰谢卡·雷迪

事实并非如此,@ danmbuen解决方案在我的情况下有效,我遇到了问题,并将其包装在单引号之间就像是一种魅力,谢谢;)
Dimitri

4

将模型属性包装在parens周围对我有用。Visual Studio抱怨分号时,您仍然会遇到相同的问题,但是它可以工作。

var closedStatusId = @(Model.ClosedStatusId);

0

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

希望这可以帮助...


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.