ASP.NET MVC如何将C#对象传递给JavaScript

26

我有一个C#类,比如AjaxOptions更像是一些选项。

public class options
{
   public string Url {get;set;}
   public string httpMethod {get;set}
}

还有一个像这样的JavaScript函数

function dosomething(obj)
{
   if (obj.Url!="" and obj.HttpMethod=="something")
    loadsomething();

}

现在在我的控制器操作中

 public class mycontroller : controller
 {
    public ActionResult WhatToDo()
    {
       options obj = new options{Url="someurl"};
       return PartialView(obj);
    }


 }

在我看来,我需要一种类似字符串的对象,我应该能够将其传递给我的方法。

@model options

<script>
   dosomething(@model.SomeFunctionToConverToString())

</script>
所以我需要一个 SomeFunctionToConverToString 方法,它可以将这个对象转换为字符串。
谢谢。

你是想将模型及其属性提供给JavaScript使用?还是想让模型中的单个字符串属性可用于你的脚本? - Jason
5个回答

42

您应该能够像处理模型属性的其他输出一样在视图中使用它。只需引用您想要传递给JS函数的属性即可。

@model options

<script>
   dosomething('@(model.Url)');
</script>

查看此贴了解有关在JS内部使用Razor的更多信息。

编辑:可能会遇到的问题是,如果您的URL由于Razor使用上述HTML编码而中断,您可以使用@Html.Raw()函数,它将传递未进行HTML编码的Url属性。

<script>
   dosomething('@Html.Raw(model.Url)');
</script>

编辑2 - 还有另一篇SO文章来拯救!您很可能需要将模型转换为JSON以在Javascript函数中使用。因此...为了做到这一点-您需要在视图模型中添加一些内容来处理JSON对象。

public class optionsViewModel
{
   public options Options{get;set;}
   public string JsonData{get;set;}
}

在你的控制器中:

public class mycontroller : controller
 {
    public ActionResult WhatToDo()
    {
       options obj = new options{Url="someurl"};
       var myViewModel = new optionsViewModel;
       myViewModel.options = obj;
       var serializer = new JavaScriptSerializer();
       myViewModel.JsonData = serializer.Serialize(data);
       return PartialView(myViewModel);
    }
 }

最后是视图:

@model optionsViewModel

<script>
   dosomething('@model.JsonData')

</script>

使用这种方法,你的函数将会按照预期运行:

function dosomething(obj)
{
   if (obj.Url!="" and obj.HttpMethod=="something")
    loadsomething();
}

编辑3 可能是迄今为止最简单的方法?和编辑2的原理相同,但是这里使用视图将模型转换为Json。关于在视图、控制器或存储库/服务层中进行此转换的问题,可能有一些好的争论。然而,在视图中进行转换……

@model options

<script>
   dosomething('@Html.Raw(Json.Encode(Model))');
</script>

1
我需要传递整个对象,传递属性并不是问题。 - Parminder
汤米,我需要整个对象转换,而不仅仅是一个属性。 - Parminder
上面的代码示例可以在控制器方法中进行重构,但我希望这能帮助您朝着正确的方向前进。 - Tommy
@Jason - 没问题,我发帖后也注意到了自己答案中的语法错误 :) - Tommy
FYI,我之前使用了 JavaScriptSerializer,也尝试过 Json.Encode(),但是日期显示为 /Date(286769410010)/ 时出现了问题。这个答案 建议使用 Json.NET 替代,这解决了我的问题。提醒一下,如果有人遇到和我一样的问题,可以尝试使用 Json.NET。 - Travesty3
显示剩余6条评论

20

试试这个:

<script type="text/javascript">
    var obj= @Html.Raw(Json.Encode(Model));
    function dosomething(obj){}
</script>

3
最好在代码中包含一些上下文/解释,这样可以使答案对于提问者和未来的读者更有用。 - EJoshuaS - Stand with Ukraine
@PrakharTrivedi 仅包含代码的答案可能不是一个好答案,但它仍然是一个答案。我建议您阅读关于LQPRQ的这篇文章:You're doing it wrong: A plea for sanity in the Low Quality Posts queue - FelixSFD
1
它对我起作用了,而我学到的是:Json.Encode将把数据对象转换为JavaScript对象表示法(JSON)格式的字符串。而Html.Raw只会给你一个未经Html编码的标记。 - Atta H.
在上面的例子中,“var obj = @Html.Raw(Json.Encode(Model));” obj将包含类似于C#对象的对象,您可以对其进行操作。我使用它并得到了这个(我在使用它的地方)https://www.screencast.com/t/TiJxKVK06Xo - Atta H.
1
虽然不直观,但在这里使用JSON.parse会更快。例如,var obj= JSON.parse('@Html.Raw(Json.Encode(Model))'); - Onosa

3

That's work for me

Client side:

function GoWild(jsonData)
{
    alert(jsonData);
}

警告打印:

{"wildDetails":{"Name":"Al","Id":1}}

MVC Razor 视图引擎:

 @{var serializer new System.Web.Script.Serialization.JavaScriptSerializer();}
<div onclick="GoWild('@serializer.Serialize(Model.wildDetails)')"> Serialize It </div>

1

还有一个语法错误

<script type="text/javascript">
  dosomething("@Model.Stringify()");
</script>

请注意,@Model.Stringify()周围的引号是为了JavaScript而存在的,因此生成的HTML将是:

<script type="text/javascript">
  dosomething("this model has been stringified!");
</script>

我的错误,但 stringify 不是你在这里看到的 http://msdn.microsoft.com/en-us/library/cc836459%28VS.85%29.aspx ,我已经编辑了问题。请看一下。 - Parminder
2
无论您在模型上调用什么函数都没有关系。重点是模型在服务器上执行,而JavaScript在客户端上执行。一切都源于对代码执行位置的理解。 - Jason

1
我建议您查看SignalR,它允许服务器触发JavaScript回调。
有关详细信息,请参阅Scott H网站:http://www.hanselman.com/blog/AsynchronousScalableWebApplicationsWithRealtimePersistentLongrunningConnectionsWithSignalR.aspx 总之...
JavaScript客户端:
var chat = $.connection.chat;
chat.name = prompt("What's your name?", "");

chat.receive = function(name, message){
    $("#messages").append("
"+name+": "+message);
}

$("#send-button").click(function(){
    chat.distribute($("#text-input").val());
});

服务器:

public class Chat : Hub {
    public void Distribute(string message) {
        Clients.receive(Caller.name, message);
    }
}

所以..在C#中的Clients.receive最终会触发javascript中的chat.receive函数。

它也可以通过NuGet获得。


11
当你尝试从他人那里获取答案时,你的态度确实很直率。你的标题表明你正在寻找将C#对象传递到HTML视图的方法,而SignalR可以实现这一点。SignalR是另一种实现你所需的功能的方式,并且提供比包含完整HTTP头的多个发送要求更低的带宽消耗。 - JTew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接