Marcos Vainer Loeff

Testing the ASP.NET vNext with PI AF SDK

Blog Post created by Marcos Vainer Loeff Employee on Oct 28, 2014

What is ASP.NET vNext?

ASP.NET MVC was introduced in 2009 and it is distributed separately from the classic ASP.NET, increasing the delivery speed since recent ASP.NET MVC versions were delivered as a complement through NuGet, for instance.

 

If you have been developing with ASP.NET for some time in recent years, you probably have been witnessing many changes on Web API, SignalR, SPA, ASP.NET Identity since all of them were distributed separately.

 

Following the same path, ASP.NET vNext, which is actually ASP.NET MVC 6, represents a fundamental change on how Microsoft constructs and deploys web frameworks. The purpose is eliminate the dependency of the System.Web assembly since it is quite expensive in order to develop a host framework. This way, ASP.NET MVC can run not only on Windows through IIS but also on other operating system and hosts.

 

Here is what has changes:

  • Web Pages, MVC, Web API is now the same thing, called the MVC 6.
  • New MVC 6 versions optimized for cloud MVC 6, SignalR 3 and Entity Framework 7
  • Finished dependency on System.Web, MVC 6 is now a middleware and now only Web Forms depends on System.Web.
  •  Cloud-optimized versions of MVC, Web API, Web Pages, SignalR and Entity Framework.
  • Increased portability since there is no dependence on the GAC assemblies facilitating cloud deployment.
  • Ability to host your application in IIS or on a self-hosted process.
  • Support legacy Web Forms, MVC 5, Web API 2, SignalR 2 and EF 6.
  • Rosyln support. You no longer need to stop the application to change a class! Just change it, save and press F5 in the browser! That is all! Much productivity!
  • Very low memory consumption.
  • Multiplatform! Turn ASP.NET wherever you want!

Objective

On my previous blog post, I have developed a sample ASP.NET MVC 5 web application which shows snapshot values from searched PI Points through PI AF SDK. On this blog post, I will develop a similar project with ASP.NET vNext (ASP.NET MVC 6) running the web application on a self-hosted process.

 

We are using Visual Studio 14 CTP3 on Windows 8.1. Please refer to my other previous blog post to find out more information concerning download this CTP version and the procedure to install it.

Create a new project

Open Visual Studio and click on File à New Project… --> Visual C# --> Web --> ASP.NET vNext Web Application. Figure 1 shows the screenshot for creating new project.

 

 8420.fig1.png

 

Figure 1 – Creating a new  ASP.NET vNext project in Visual Studio.

 

For the name of your solution, please write “PIAFSDK-vNextWebApplication” and click on “OK”.

 

On the previous blog post, I have chosen the empty template because on the MVC template a lot of resources were available which I wouldn’t use. Therefore, the empty template is a better option for a clean solution. Nevertheless, for ASP.NET vNext, we have not chosen the ASP.NET vNext Empty Web Application because it would be more difficult to get started.

 

Please refer to my previous blog post in case you want more information about the Models, Controllers and Views in this exercise since they are very similar. Here we will only show the content of the files since they were already explained.

Add the PI AF SDK reference

If you right click on References, there won’t be an option called “Add reference…” as on ASP.NET MVC 5. The reason is that on this version references are defined on the project.json file. If you want to reference PI AF SDK, open the file project.json and add a string to the dependencies string array as shown below:

 
{
    "dependencies": {
        "OSIsoft.AFSDK":  "4.0.0.0",
        "EntityFramework.SqlServer": "7.0.0-alpha3",
        "Microsoft.AspNet.Mvc": "6.0.0-alpha3",
        "Microsoft.AspNet.Identity.EntityFramework": "3.0.0-alpha3",
        "Microsoft.AspNet.Identity.Authentication": "3.0.0-alpha3",
        "Microsoft.AspNet.Security.Cookies": "1.0.0-alpha3",
        "Microsoft.AspNet.Server.IIS": "1.0.0-alpha3",
        "Microsoft.AspNet.Server.WebListener": "1.0.0-alpha3",
        "Microsoft.AspNet.StaticFiles": "1.0.0-alpha3",
        "Microsoft.Framework.ConfigurationModel.Json": "1.0.0-alpha3",
        "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0-alpha2",
        "jQuery": "1.10.2"
 
    },
    "commands": {
        /* Change the port number when you are self hosting this application */
        "web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5000"
    },
    "frameworks": {
        "net451" : { },
        "k10" : { }
    }
}

Create a new Model

On the solution explorer, right click on the Models folder and select à Add class. Name this class PIPointSnapshotModelView and click on OK. The content of this class should be: 

 
using System;
using OSIsoft.AF.Asset;

namespace PIAFSDK_vNextWebApplication.Models
{
    public class PIPointSnapshotModelView
    {
        public string PIPointName { get; set; }
        public object Value { get; set; }
        public DateTime TimeStamp { get; set; }

        public PIPointSnapshotModelView(string piPointName, AFValue snapshot)
        {
            PIPointName = piPointName;
            Value = snapshot.Value;
            TimeStamp = snapshot.Timestamp;
        }
    }
} 

Change the HomeController

As we have not chosen the “ASP.NET vNext Empty Web Application”, there is already some action methods defined for HomeController. Modify this file to implement other actions instead:

 
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.Mvc;
using OSIsoft.AF.PI;
using PIAFSDK_vNextWebApplication.Models;

namespace PIAFSDK_vNextWebApplication.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View("Query");
        } 

        public ActionResult Query()
        {
            return View();
        }
 

        public ActionResult Result(string piPointNameQuery, string pointSourceNameQuery)
        {
            PIServer myPIServer = new PIServers()["MARC-RRAS"];
            PIPointQuery query1 = new PIPointQuery(PICommonPointAttributes.Tag, OSIsoft.AF.Search.AFSearchOperator.Equal, piPointNameQuery);
            PIPointQuery query2 = new PIPointQuery(PICommonPointAttributes.PointSource, OSIsoft.AF.Search.AFSearchOperator.Equal, pointSourceNameQuery);
            IEnumerable<PIPoint> foundPoints = PIPoint.FindPIPoints(myPIServer, new PIPointQuery[] { query1, query2 });
            PIPointList pointlist = new PIPointList(foundPoints.Take(1000));
            List<PIPointSnapshotModelView> PIPointSnapshotValueList = new List<PIPointSnapshotModelView>();
            foreach (PIPoint pipoint in pointlist)
            {
                PIPointSnapshotValueList.Add(new PIPointSnapshotModelView(pipoint.Name.ToString(), pipoint.Snapshot()));
            }
            return View(PIPointSnapshotValueList);
        }
    }
}

Create the Views

Go to the Views\Home folder and delete the Views: Index.cshtml, About.cshtml and Contact.cshtml.

 

Create two Views: Query.cshtml and Result.cshtml on the Views\Home with the following content:

 
//Query.cshtml

@{
    Layout = null;
}

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <link href="~/Content/bootstrap.css" rel="stylesheet" />
    <link href="~/Content/bootstrap-theme.css" rel="stylesheet" />
    <script src="~/scripts/jquery-1.10.2.js"></script>
    <script src="~/Scripts/bootstrap.js"></script>
    <title>Query PI Data Archive</title>
</head>
<body>
    <div class="col-sm-8 col-sm-offset-2">
        <h1>My first ASP.NET MVC with PI AF SDK</h1>
        <br /><br />
        <h4>Search for PI Points and check its snapshots.</h4>
        <br /><br />
        <div class="container">
            <div class="row">
                @using (Html.BeginForm("Result", "Home", FormMethod.Get, new { @class = "form-inline", role = "form" }))
                {
                    <div class="form-group">
                        <label class="sr-only" for="name">Search PI Point: </label>
                        @Html.TextBox("piPointNameQuery", string.Empty, new { @class = "form-control", placeholder = "PI Point" })
                    </div>
                    <div class="form-group">
                        <label class="sr-only" for="inputfile">With this Point Source: </label>
                        @Html.TextBox("pointSourceNameQuery", string.Empty, new { @class = "form-control", placeholder = "Point Source" })
                    </div>
                    <button type="submit" class="btn btn-default">Submit</button>
                }
            </div>
        </div>
    </div>
</body>
</html>
//Result.cshtml
 
@model List<PIAFSDK_vNextWebApplication.Models.PIPointSnapshotModelView>

@{
    Layout = null;
}

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Results</title>
    <link href="~/Content/bootstrap.css" rel="stylesheet" />
    <link href="~/Content/bootstrap-theme.css" rel="stylesheet" />
    <script src="~/scripts/jquery-1.10.2.js"></script>
    <script src="~/Scripts/bootstrap.js"></script>
</head>
<body>
    <div class="col-sm-8 col-sm-offset-2">
        <h1>My first ASP.NET MVC with PI AF SDK</h1>
        <br /><br />
        <table class="table">
            <tr>
                <th>PI Point</th>
                <th>Value</th>
                <th>Timestamp</th>
            </tr>
            @foreach (var piPointSnapshotValue in Model)
            {
                <tr>
                    <td>@piPointSnapshotValue.PIPointName</td>
                    <td>@piPointSnapshotValue.Value.ToString()</td>
                    <td>@piPointSnapshotValue.TimeStamp.ToString()</td>
                </tr>
            }
        </table>
        <br />
        <center>
            <a href="@Url.Action("Index")" class="btn btn-primary">Make another search</a>
        </center>
    </div>
</body>
</html>

If you compare carefully, in this example,  I am using Url.Action instead of Html.ActionLink on Result.cshtml. The reason is that Html.ActionLink didn’t work as expected on this version of ASP.NET vNext.

Create a self-hosted web site

First of all, start your web site and make sure it behaves like the ASP.NET MVC 5 version. If it works well, right click on the project and choose “Publish…”. On the Publish Web window, choose “File System” for the publish target as shown on Figure 2. Type a custom profile name and click on “OK”.

 

7382.fig2.png

 

Figure 2 – Selecting a publish target when publishing.

 

On the next section, choose any target location. In my case, I am using c:\AFSDKApp as shown on Figure 3.

 

4861.fig3.png

 

Figure 3– Selecting a publish target when publishing.

 

Finally, click on Publish. After Visual Studio has finished copying the files to the folder, close this project and check the content of the C:\AFSDKApp folder. You will see that there is file called web.cmd. If you run this file, your web site will be running on a self-hosted process as shown on Figure 4 without being executed by Visual Studio, IIS or IIS Express.

 

 8863.fig4.png

 

 

 

Figure 4 – Running your ASP.NET vNext Web Application on a self-host process.

Conclusion

This example was tested using Visual Studio 14 CTP3. By the time of this writing, CTP 4 was already released. Although I have not tested, this example should work as well with CTP 4.

 

I hope you find this blog post interesting and stay tuned for the next one!

Outcomes