13

我有一个用户列表,我使用视图包从控制器传递到我的视图。现在我需要能够将相同的列表传递给页面上的 javascript。我可以使用 foreach 循环重建列表:

    @foreach (var item in ViewBag.userList) //Gets list of users passed from controller and adds markers to the map
{
    var userLat = item.LastLatitude;
    var userLon = item.LastLongitude;
    var _userId = item.Id;

    <script>array.push({"userId":"'@_userId'","userLat":"'@userLat'","userLon":"'@userLon'"});</script>
}

然而,这似乎是一种混乱的方法,如果进行更改,则需要进行大量返工。我知道 Stack Overflow 上也有类似的帖子,但其中很多都使用以前版本的 MVC,而且似乎不适用相同的语法。有任何想法吗?

4

3 回答 3

24

您可以使用 JSON 解析器在一行安全的代码中完成此操作。你绝对不应该像你在你的例子中尝试做的那样,用一些字符串连接和东西手动构建 JSON。也不需要编写任何循环。

这是正确的方法:

<script type="text/javascript">
    var array = @Html.Raw(
        Json.Encode(
            ((IEnumerable<UserModel>)ViewBag.userList).Select(user => new 
            { 
                userId = user.Id, 
                userLat = user.LastLatitude, 
                userLon = user.LastLongitude 
            })
        )
    );

    alert(array[0].userId);
</script>

The generated HTML will look exactly as you expect:

<script type="text/javascript">
    var array = [{"userId":1,"userLat":10,"userLon":15}, {"userId":2,"userLat":20,"userLon":30}, ...];
    alert(array[0].userId);
</script>

Of course the next level of improvement in this code is to get rid of the ViewCrap and use a strongly typed view model.

于 2013-03-08T10:17:24.857 回答
2

Another option, could be to create a new action in your controller returning a JsonResult. This json result could return your list. In your page you can call the action with jquery and use it from there.

public ActionResult GetMyList()
{
    var list = GetMyUserList();

    return Json(new { userlist = list }, JsonRequestBehaviour.AllowGet);
}
于 2013-03-08T10:21:12.793 回答
2

@Darin Dimitrov answer is spot on. I would just like to add to it if anyone is passing a model and not a viewbag.

<script type="text/javascript">
 var array = @Html.Raw(Json.Encode(
            Model.YourModel.Select(_ => new {
              id = _.Id,
              text = _.Name
            })
          ))

My use case was specific to select2 . One can then just pass the array to the data: attribute

 $("#storeSelect").select2({
        data: array,
        placeholder: "Select something"
 });
</script>

viewmodel

public class YourViewModel
  {
    public IEnumarable<YourPoco> YourPocos { get; set; }
  }

Controller

public class YourController : Controller
{
    public ActionResult Index()
    {
        YourViewModel vm = new YourViewModel{
            // Using Dependancy injection
            YourPocos = yourRepo.GetYourPocos();
        };
        return View("Index", "_Layout",vm);
    }
}

I realise this answer might be redundant, but it is the first time i am using Json.Encode and passing model values to a jquery extension. This for me is too cool. It does to a certain degree create massive extensibility on what would otherwise be an @htmlhelper

于 2014-06-19T09:56:55.270 回答