1

I am trying to use AngularJs with ASP.NET MVC - this is my first attempt.

Index.html

@model string
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}

<div class="container" ng-init="courses = [{'name':'first'},{'name':'second'},{'name':'third'}]">
<table class="table table-bordered">
    <thead>
        <tr>
            <th>Name</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="course in courses">
            <td>{{ course.name }}</td>
        </tr>
    </tbody>
</table>

_Layout.cshtml

<!DOCTYPE html>

<html ng-app>
<head>
<meta name="viewport" content="width=device-width" />
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />

<script src="~/Scripts/angular.min.js"></script>
<title></title>
</head>
<body>
@RenderBody()
</body>
</html>

Above works fine and grid is displayed with Name as header and first, second and third as 3 rows. So my next step is to use

courses = @Html.Raw(Json.Encode(Model))

instead of

courses = [{'name':'first'},{'name':'second'},{'name':'third'}]

CourseController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace AngularJsMvc.Controllers
{
    public class CoursesController : Controller
    {
        // GET: Courses
        public ActionResult Index()
        {
            return View("Index", "", "[{'name':'first'},{'name':'second'},    {'name':'third'}]"); //This works fine when used with @Html.Raw(Model) in index.html
            //return View("Index", "", GetCourses()); //This doesn't work when used with with @Html.Raw(Model) in index.html
        }

        public string GetCourses()
        {
            var courses = new[]
            {
                new Course { Name = "First" },
                new Course { Name = "Second" },
                new Course { Name = "Third" }
            };
            var settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() };
            return JsonConvert.SerializeObject(courses, Formatting.None, settings);
        }
    }

    public class Course
    {
        public string Name { get; set; }
    }
}

This works fine if I use

return View("Index", "", "[{'name':'first'},{'name':'second'},{'name':'third'}]");

But if I use

return View("Index", "", GetCourses());

Then, below is the error I get. Please help - I have been struggling for almost entire day yesterday. I tried with or without Json.Encode

angular.min.js:123 Error: [$parse:ueoe] 
http://errors.angularjs.org/1.6.4/$parse/ueoe?p0=courses%20%3D
at angular.min.js:6

"<div class="container" ng-init="courses = " [{\"name\":\"first\"},{\"name\":\"second\"},{\"name\":\"third\"}]""="">"
Raoul
  • 45
  • 5
  • How about `return Regex.Unescape(JsonConvert.SerializeObject(courses, Formatting.None, settings));`? JSON.NET escape double quotes in JSON string, hence you need to revert to non-escaped strings first. – Tetsuya Yamamoto Jun 08 '17 at 07:47
  • Thanks @TetsuyaYamamoto, tried this just now and same issue. – Raoul Jun 08 '17 at 08:03

1 Answers1

3

The following worked for me:

<div class="container" ng-init="courses = @Newtonsoft.Json.JsonConvert.DeserializeObject(Model)">

This also works:

<div class="container" ng-init="courses = @HttpUtility.HtmlDecode(Model)">

It's all about how angular treats the object it tries to parse and since you're passing an HTML decoded string it will treat as a string and therefore it won't be able to iterate threw it.

Yoav
  • 3,326
  • 3
  • 32
  • 73
  • Thanks @Yoav, this worked and I will use it. I am still keen on understanding what is wrong in my approach of "injecting" (so to speak) it from controller method so will leave this unanswered for now. – Raoul Jun 08 '17 at 08:07
  • Thanks @Yoav, @HttpUtility.HtmlDecode(Model) also worked. – Raoul Jun 08 '17 at 08:27
  • Thanks @Yoav still unsure however why in the html courses = @HTML.Raw(Model) doesn't work, but your solution works, thanks. – Angel Cloudwalker Mar 22 '18 at 14:45
  • @Raoul You may also use \@Html.Raw(Html.AttributeEncode(Model)), I like this b/c you still use the \@Html synthax and it's clear that you are formatting it for HTML purposes (for example it doesn't like the quotations and changes it to html friendly ") – Angel Cloudwalker Mar 22 '18 at 15:06