How to pass data from asp.NET MVC to Angular2 How to pass data from asp.NET MVC to Angular2 angular angular

How to pass data from asp.NET MVC to Angular2


The best way that I have found to pass data in from MVC (or any hosting/startup page) is to specify the data as an attribute on the bootstrapped component, and use ElementRef to retrieve the value directly.

Below is an example for MVC derived from the this answer, which states that it is not possible to use @Input for root-level components.

Example:

//index.cshtml<my-app username="@ViewBag.UserName">    <i class="fa fa-circle-o-notch fa-spin"></i>Loading...</my-app>//app.component.tsimport {Component, Input, ElementRef} from '@angular/core';@Component({    selector: 'my-app',    template: '<div> username: <span>{{username}}</span> </div>'})export class AppComponent {    constructor(private elementRef: ElementRef) {}    username: string = this.elementRef.nativeElement.getAttribute('username')}

If you want to retrieve more complex data that is not suitable for an attribute, you can use the same technique, just put the data in a HTML <input type='hidden'/> element or a hidden <code> element, and use plain JS to retrieve the value.

myJson: string = document.getElementById("myJson").value

Warning: Access the DOM directly from a data-bound application such as Angular, breaks the data-binding pattern, and should be used with caution.


You might want to look for similar questions related to AngularJS, not Angular 2 specific, as the main gist of the thing remains the same:

  • you want your server-side Razor engine to render some kind of view (i.e. HTML or JS directly)
  • this view contains a JS template where part of the content is filled from a server model instance or anyway server data (e.g. a resource, dictionary, etc.)
  • in order to properly fill a JS variable from Razor, C# server-side data has to be properly serialized into a JSON format

In this post by Marius Schulz you can see as he serializes the data and uses that to fill a template AngularJS value component:

<script>  angular.module("hobbitModule").value("companionship", @Html.Raw(Model));</script>

Something similar could be made to inject some data e.g. into window.myNamespace.myServerData, and then have Angular2 bootstrap that value among other providers.

In this post by Roel van Lisdonk, a similar approach is used, again, to fill an AngularJS-based template, with that ng-init directive:

<div ng-controller="main"     ng-init="resources={ textFromResource: '@WebApplication1.Properties.Resources.TextFromResource'}">  <h1>{{ title }}</h1>  {{ resources.textFromResource }}</div>

As the first post points out, there's something to think about (pasting here):

A word of caution: The method I'm about to use is probably not a good fit for large amounts of data. Since the JavaScript data is inlined into the HTML response, it's sent over the wire every single time you request that page.

Also, if the data is specific to the authenticated user, the response can't be cached and delivered to different users anymore. Please keep that in mind when considering to bootstrap your Angular Apps with .NET data this way.

The second part may be less of an issue if your served page is already dynamic server-side, i.e. if it already has bits filled in out of server-side data.

HTH


You need to first bundle your services and controllers in separate module files and load services before controllers.For example:

dist|--services.js|--controllers.js

Then you need to load the JavaScript code of the Services via ASP.NET MVC JavaScript result, here you need to inject your startup data.

public class ScriptController: Controller{  public ActionResult GetServices(){   string file= File.ReadAllText(Server.MapPath("~dist/services.js"));   //modify the file to inject data or    var result = new JavaScriptResult();            result.Script = file;   return result;     }

Then in the index.html load the scripts as follows

<script src="/script/getservices"></script><script src="/dist/controller.js"></script>

This way you can inject data into angular code while loading. However, even this has a performance impact due to time spent on fetching the view, compiling the view, and binding data to the view. For an initial load performance can still be improved if you use Server Side Rendering.