ASP.NET 4.5 and ASP.NET Core 1 Hosting BLOG

Tutorial and Articles about ASP.NET 4.0 and the latest ASP.NET 4.5 Hosting

ASP.NET Hosting - ASPHostPortal.com :: Tips to configure Kestrel URLs in ASP.NET Core RC2

clock June 10, 2016 19:44 by author Armend

How to configure Kestrel URLs in ASP.NET Core RC2

ASP.NET Core is completely decoupled from the web server environment that hosts the application. ASP.NET Core supports hosting in IIS and IIS Express, and self-hosting scenarios using the Kestrel and WebListener HTTP servers. Additionally, developers and third party software vendors can create custom servers to host their ASP.NET Core apps.

Prior to the release of ASP.NET Core RC2 Kestrel would be configured as part of the command bindings in project.json:

"commands": {
  "web": "Microsoft.AspNet.Server.Kestrel --server.urls=http://localhost:60000;http://localhost:60001;"
},

If no URLs were specified, a default binding of http://localhost:5000 would be used.

As of RC2 we have a new unified toolchain (the .NET Core CLI) and ASP.NET Core applications are effectively just .NET Core Console Applications. They have a single entry point where we programatically configure and run the web host:

public static void Main(string[] args)
{
    var host = new WebHostBuilder()
        .UseKestrel()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseIISIntegration()
        .UseStartup<Startup>()
        .Build();
    host.Run();
}

Here we're adding support for both Kestrel and IIS hosts via the appropriate extension methods.
When we upgraded SaasKit to RC2 we used the UseUrls extension to configure the URLs Kestrel would bind to:

var host = new WebHostBuilder()
    .UseKestrel()
    .UseContentRoot(Directory.GetCurrentDirectory())
    .UseUrls("http://localhost:60000", "http://localhost:60001")
    .UseIISIntegration()
    .UseStartup<Startup>()
    .Build();

I didn't really like this approach as we're hard-coding URLs. Fortunately it's still possible to load the Kestrel configuration from an external file.
First create a hosting.json file in the root of your application with your required bindings. Separate multiple URLs with a semi-colon:

{
  "server.urls": "http://localhost:60000;http://localhost:60001"
}

Next update Program.cs to load your hosting configuration, then use the UseConfiguration extension to pass the configuration to the WebHostBuilder:

public static void Main(string[] args)
{
    var config = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("hosting.json", optional: true)
        .Build();
    var host = new WebHostBuilder()
        .UseKestrel()
        .UseConfiguration(config)
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseIISIntegration()
        .UseStartup<Startup>()
        .Build();
    host.Run();
}

If you're launching Kestrel with Visual Studio you may also need to update launchSettings.json with the correct launchUrl:

"RC2HostingDemo": {
  "commandName": "Project",
  "launchBrowser": true,
  "launchUrl": "http://localhost:60000/api/values",
  "environmentVariables": {
    "ASPNETCORE_ENVIRONMENT": "Development"
  }
}

Now the web application will listen on the URLs configured in hosting.json:

Hosting environment: Development
Content root path: C:\Users\ben\Source\RC2HostingDemo\src\RC2HostingDemo
Now listening on: http://localhost:60000
Now listening on: http://localhost:60001
Application started. Press Ctrl+C to shut down.



ASP.NET Hosting - ASPHostPortal.com :: How to Check Duplicate User Names In ASP.NET Web Pages Sites

clock October 5, 2015 11:39 by author Kenny

How to Check Duplicate User Names In ASP.NET Web Pages Sites

The Web Pages Starter Site template provides a useful starting point for developing a Razor Web Pages site that includes membership. But it doesn't include any mechanism for preventing duplicate user names. This article offers one solution to the problem that uses jQuery.

If you ask how to prevent duplicate user names in forums, one of the suggestions that is often put forward is to apply a unique constraint in the database column that holds the user name. Any attempt to submit a duplicate value will result in an exception being raised in the relevant database provider. You can catch this exception and show the user an appropriate message. This works but it's a fairly clunky solution. And many people feel that you should not use exceptions as a means to manage your business rules.

The solution featured in this article uses AJAX to query the database and to give the user immediate feedback when they enter their chosen user name. The AJAX call requests a page that exists purely to query the database to see if the selected user name is already in use. The solution also includes a server side chekc to ensure that users who have disabled JavaScript so not slip through the net. The solution requires a couple of amendments to the Register.cshtml file in the Starter Site, and the addition of 3 files. But first, the changes to the Register.cshtml page. The first change is in the inclusion of a JavaScript file called dupecheck.js.

@* Remove this section if you are using bundling *@
@section Scripts {
    <script src="~/Scripts/jquery.validate.min.js"></script>
    <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
    <script src="~/Scripts/dupecheck.js"></script>
}

And the second is the server side check to see if the username is in use:

if(Functions.IsDuplicate(email)){
    ModelState.AddError("email", "User name is already taken");
}

I placed this in the if(IsPost) section just after the initial variables that represent the submitted values (email, password and confirmPassword) are declared. The code calls a function named IsDuplicate. The function is declared in a file called Functions.cshtml which is placed in a folder called App_Code:

@functions {
    public static bool IsDuplicate(string username){
        var db = Database.Open("StarterSite");
        var commandText = @"SELECT COUNT(Email) FROM UserProfile WHERE Email = @0";
        return (int)db.QueryValue(commandText, username) > 0;
    }
}

Note that the name of the folder is important. The function returns a bool. The value of the bool is determined as a result if the SQL query which gets a count of the rows containing the provided user name. By default, the Starter Site uses a column called Email in the UserProfile table for the storage of user names. This function is also called in a separate file named DupeCheck.cshtml. This file is placed in the root of the site:

@{
    Layout = null;
    if(IsAjax){
        var username = Request["username"];
        var result = Functions.IsDuplicate(username);
        Json.Write(new { isDupe = result }, Response.Output);
    }
}

DupeCheck.cshtml is designed to work exclusively with AJAX. The code includes an instruction to nullify any layout pages that might have been set in a _PageStart file, and then it uses the IsAjax property to determine if the page has been requested via an AJAX call. If it has, it uses the IsDuplicate method to check the availability of the posted username and returns the result to the calling code. The result is an anonymous type that has one propery: isDupe, which is a boolean. The anonymous type is serialised to JSON by the Json helper.

The final part of the solution is the dupecheck.js file. This uses jQuery:

$(function () {
    $('#email').change(function () {
        $.post(
            '/DupeCheck',
            { username: $(this).val() },
            function (data) {
                var emailValidation = $('span[data-valmsg-for="email"]');
                if (data.isDupe) {
                    if (emailValidation.hasClass('field-validation-valid')) {
                        emailValidation.removeClass('field-validation-valid');
                        emailValidation.addClass('field-validation-error');
                        emailValidation.text('That name is already taken!');
                    }
                } else {
                    if (emailValidation.hasClass('field-validation-error')) {
                        emailValidation.removeClass('field-validation-error');
                        emailValidation.addClass('field-validation-valid');
                        emailValidation.text('');
                    }
                }
            },'json'
        );
    });
});

An event handler is attached to the change event of the user name input (which has an id if email in the Starter Site). The current value is posted to the DupeCheck.cshtml page via AJAX. The code above checks the response from the server to see if the value is a duplicate, and if it is, an appropriate error message is displayed to the user.

Best ASP.NET 4.6 Hosting Recommendation

ASPHostPortal.com provides its customers with Plesk Panel, one of the most popular and stable control panels for Windows hosting, as free. You could also see the latest .NET framework, a crazy amount of functionality as well as Large disk space, bandwidth, MSSQL databases and more. All those give people the convenience to build up a powerful site in Windows server. ASPHostPortal.com offers ASP.NET hosting starts from $1/month only. They also guarantees 30 days money back and guarantee 99.9% uptime. If you need a reliable affordable ASP.NET Hosting, ASPHostPortal.com should be your best choice.



ASP.NET Hosting - ASPHostPortal.com :: Easy to Design Pie Chart and Donut Chart in ASP.NET

clock September 28, 2015 12:40 by author Kenny

Easy to Design Pie Chart and Donut Chart in ASP.NET

D3.js stands for Data-Driven Document. It is a JavaScript library using which we can manipulate documents based on data. The data can be fetched using multiple ways like Web Services, WCF Services, REST APIs or the relatively new Microsoft ASP.NET Web API amongst many others. Using D3, you can bind the data to the Document Object Model (DOM) and present that data with rich visualizations. D3 internally makes use of CSS, HTML and SVG capabilities to make your data presentable. It is powerful, fast and supports large datasets and dynamic behaviors for interactions and powerful and smooth animations.

D3.js provides easy and declarative selections of DOM nodes using W3C Selector APIs. D3 Selector APIs provides number of methods to manipulate nodes. For example –

  • Setting attributes and applying rich styles
  • Registering Event Listeners
  • You can add, remove and sort DOM nodes
  • You can change the HTML or the text contents of HTML elements
  • You can also have a direct selection/access to the DOM as each selection is an array of nodes

Likewise, we have various features of D3.js selectors which we can use to present data to our DOM nodes.

A simple selector example is the following:

var bodySelection = d3.select('body').style('background-color', 'blue');

In the above example, we are selecting body and changing its background color to blue. Another example would be as follows:

var divSelection = d3.selectAll('div').style('background-color', 'yellow');

In the above example, we are selecting all divs and changing its background color to yellow. If you are familiar with jQuery, the syntax looks similar to jQuery selectors or HTML5 Selectors.

D3 allows us to bind the data to the DOM elements and their attributes using a Data method which takes an array. For example:

d3.selectAll("div")
  .data([200,300,400,100])
  .style("height", function (data) { return data + "px"; });

In the above example, we are selecting all the div’s on the page and based on the index, the first value of an array will be passed to first div, second value to second div and so on.

In D3, you can also make use of Enter and Exit selector methods to create new nodes for incoming data, and remove outing nodes that are no longer used.

You can also apply transitions to nodes using D3. For example –

var area = d3.select('body')
            .append('svg')
            .attr('width', 500)
            .attr('height', 500);
 
var circle = area.append('rect')
                 .attr('width', 100)
                 .attr('height', 100)
                 .attr('fill', 'red');
 
circle.transition()
      .duration(2000)
      .delay(2000)
      .attr('width', 400)
      .each('start', function () {
            d3.select(this).attr('fill', 'green');})
      .transition()
      .duration(2000)
      .attr('height', 400)
      .transition()
      .duration(2000)
      .attr('width', 50)
      .transition()
      .duration(2000)
      .attr('height', 50)
      .each('end', function () {
            d3.select(this).attr('fill', 'blue'); });

In the above example, we are drawing a Rectangle and applying the transition to the same. Likewise, we can make use of various features of D3.js to present our data using rich visualizations.

A Quick overview of ASP.NET Web API

REST(REpresentational State Transfer) has emerged as the prominent way to create web services. By using REST we can build loose coupled services with data available on the web over HTTP protocol.

ASP.NET Web API is a platform for building RESTful applications. ASP.NET Web API is a framework using which we can build HTTP Services which can be called from a broad range of clients, browsers and mobile devices. ASP.NET Web API is the defacto standard of creating web services and replaces WCF.

When we think about exposing data on the web, we usually talk about four common operations which we use on a daily basis in our apps – CREATE, RETRIVE, UPDATE, DELETE.

We call these operations as CRUD operations. REST provides 4 basic HTTP verbs which we can map to our CRUD operations as described here - POST – CREATE, GET – RETRIVE, PUT – UPDATE, DELETE – DELETE.

By using REST, if you can connect to the web, any application can consume your data. When the data is pulled or pushed by using REST, the data is always serialized into or de-serialized from JSON or XML.

Setting up the application and ASP.NET Web API

To start designing the Pie chart and Donut chart, use the following tools and technologies:

  • Microsoft Visual Studio 2013 (Express or Professional)
  • Microsoft SQL Server 2012 (Express or Developer)
  • jQuery
  • D3.js
  • ASP.NET WEB API

Let’s first design the table where we can add our data. To design the table, open SQL Server Management Studio and write the following script:

CREATE TABLE [dbo].[CityPopulationTable](
    [CityID] [int] IDENTITY PRIMARY KEY,
    [CityName] [nvarchar](30) NULL,
    [Population] [int] NULL
)

Create an ASP.NET Web application by choosing Web Forms template. Then add the Entity Framework, jQuery and D3.js libraries into our web application using NuGet.

Once you add these libraries, right click on the Models folder in our Web application under Solution Explorer, and click on Add New Item. Choose Data  > ADO.NET Entity Data Model.

Using Entity Data Model Wizard, connect to our database and choose CityPopulationTable.

It’s time to implement the ASP.NET Web API into our project. Right click the web application and add a new folder with the name Controllers.

After adding the Web API, open Global.asax file and import two namespaces as shown here:

using System.Web.Http;
using System.Web.Routing;

Also add the following code to the Application_Start method –

GlobalConfiguration.Configure(WebApiConfig.Register);

The above line registers the Web API route in our web application. Now under App_Start folder, you will find WebApiConfig.cs file. Open this file and write the following code:

public static void Register(HttpConfiguration config)
{
    config.MapHttpAttributeRoutes();
 
    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
    var json = config.Formatters.JsonFormatter;
    json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
    json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    config.Formatters.Remove(config.Formatters.XmlFormatter);
}

In the above code, we are configuring Web API to make use of JSON formatter with camel casing, as most of the JavaScript developer will expect JSON output in Camel casing.

Now modify the Get method of our Web API controller as shown here:

public class PieChartController : ApiController
{
    NorthwindEntities dataContext = new NorthwindEntities();
    // GET api/piechart
    public IEnumerable<CityPopulationTable> Get()
    {
        return dataContext.CityPopulationTables.ToList();
    }
}

In the above code, we have created an object of our Entity Data model which will give access to the tables. Then we are returning an IEnumerable of our object CityPopulationTables.

Let us design our Pie chart and Donut chart using the Web API data shown in above:

Creating D3 Charts

Add a HTML page with the name ‘CityPolulationPieChart.html’. Once you add the page, we will reference the jQuery and D3.js file in the page:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Pie Chart Example</title>
    <script src="Scripts/jquery-1.10.2.js"></script>
    <script src="Scripts/d3.js"></script>
</head>

We will make use of jQuery AJAX function to fetch the data from our Web API and display it in a Pie and Donut chart. Let’s add a DOM ready function into our <body> tag. In this function, we will first declare two arrays. First array will hold the data for our chart and the second array will hold the colors which we will use for our chart:

$(function () {
            var chartData = [];
            var colors = [];
});

In the next step, we will fetch the data from our Web API using jQuery $.ajax function. Add this code after our array declaration:

$.ajax({
        type: "GET",
        url: "api/PieChart",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (result) {
            $.each(result, function (i,j) {
                chartData.push(j.population);
                var currentColor = '#' + Math.floor(Math.random() * j.population+5566656).toString(16);
                colors.push(currentColor);
            });
            console.log(chartData);}
        error: function (msg) {
            $("#result").text(msg);
        }
});

Note: Although I have used success and error here for devs using an older version of jQuery, these methods have been deprecated from jQuery 1.8. You should replace them with .done() and fail().

In the above code, we are using a GET request with the Web API URL and the type of data set to JSON. On successful completion of the request, we are running a loop using $.each() which will push the fetched data into our chartData array. We are also generating colors and adding them into our colors array.

Now it’s time to use the D3 selector. We will use D3 selector to select the body and will append the SVG element to the same by setting its height and width. Add this code after console.log function. The code is shown below –

var radius = 300;
var colorScale = d3.scale.ordinal().range(colors);
                    
var area = d3.select('body').append('svg')
             .attr('width', 1500)
             .attr('height', 1500);

Also note that we are using the scale function of D3 which allows us to set the ordinal scale with the range to set the scale’s output range. We have also added a variable called radius which is set to 300.

The next step is to group the elements and draw an arc into our SVG as shown in the following code:

var pieGroup = area.append('g').attr('transform', 'translate(300, 300)');
var arc = d3.svg.arc()
                .innerRadius(0)
                .outerRadius(radius);

In the above code, we are using radius variable as the outer radius and fixing the inner radius to 0. As the next step, use a pie layout available under D3. Then pass the chart data and append it to our group ‘g’. The code is shown below –

var pie = d3.layout.pie()
       .value(function (data) { return data; })
var arcs = pieGroup.selectAll('.arc')
       .data(pie(chartData))
       .enter()
       .append('g')
       .attr('class', 'arc');

Also observe, we are using D3 selector to select arc class added at the end, which will select all the elements which has a class arc. In the last step,  append the path and fill the color from our array. We will also display the population data as text to our pie chart. The code is shown below –

arcs.append('path')
    .attr('d', arc)
    .attr('fill', function (d) { return colorScale(d.data); });
 
arcs.append('text')
    .attr('transform', function (data) { return 'translate(' + arc.centroid(data) + ')'; })
    .attr('text-anchor', 'middle')
    .attr('font-size', '1em')
    .text(function (data) { return data.data; });

Donut Chart

Designing a Donut chart is very simple. Just change the inner radius to something higher than zero. I am making it 200. The code is as shown here:

var arc = d3.svg.arc()
        .innerRadius(200)
        .outerRadius(radius);

Best ASP.NET 4.6 Hosting Recommendation

ASPHostPortal.com provides its customers with Plesk Panel, one of the most popular and stable control panels for Windows hosting, as free. You could also see the latest .NET framework, a crazy amount of functionality as well as Large disk space, bandwidth, MSSQL databases and more. All those give people the convenience to build up a powerful site in Windows server. ASPHostPortal.com offers ASP.NET hosting starts from $1/month only. They also guarantees 30 days money back and guarantee 99.9% uptime. If you need a reliable affordable ASP.NET Hosting, ASPHostPortal.com should be your best choice.



ASP.NET MVC 6 Hosting - ASPHostPortal :: Remote Validation in ASP.NET MVC

clock August 24, 2015 08:07 by author Kenny

Remote Validation in ASP.NET MVC

ASP.NET is an open-source server-side Web application framework designed for Web development to produce dynamic Web pages. It was developed by Microsoft to allow programmers to build dynamic web sites, web applications and web services. ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites that enables a clean separation of concerns and that gives you full control over markup. Remote validation is used to make server calls to validate data without posting the entire form to the server when server side validation is preferable to client side.  It's all done set up model and controller which is pretty neat. 

Using the Code

To implement remote validation in an application we have two scenarios, one is without an additional parameter and the other is with an additional parameter. First we create an example without an additional parameter. In this example we check whether a username exists or not. If the username exists then that means the input user name is not valid. We create a view model class "UserViewModel" under the Models folder and that code is:

using System.Web.Mvc;  
namespace RemoteValidation.Models   
{  
    public class UserViewModel   
    {  
        public string UserName   
        {  
            get;  
            set;  
        }  
        public string Email   
        {  
            get;  
            set;  
        }  
    }  
}

 

Now we create a static data source, in other words we create a static list of UserViewModel in which we could check whether a username exists or not. You can also use the database rather than a static list. The following code snippet is for StaticData.

using RemoteValidation.Models;  
using System.Collections.Generic;  
 
namespace RemoteValidation.Code   
{  
    public static class StaticData   
    {  
        public static List < UserViewModel > UserList   
        {  
            get {  
                return new List < UserViewModel >   
                {  
                    new UserViewModel   
                    {  
                        UserName = "User1", Email = "[email protected]"  
                    },  
                    new UserViewModel   
                    {  
                        UserName = "User2", Email = "[email protected]"  
                    }  
                }  
            }  
        }  
    }  

 

Now we create a controller "ValidationController" in which we create an action method to check whether a user name exists or not and return a result as a JSON format. If the username exists then it returns false so that the validation is implemented on the input field. The following code snippet shows ValidationController under the Controllers folder.

using RemoteValidation.Code;  
using System.Linq;  
using System.Web.Mvc;  
 
namespace RemoteValidation.Controllers   
{  
    public class ValidationController: Controller   
    {  
        [HttpGet]  
        public JsonResult IsUserNameExist(string userName)   
        {  
            bool isExist = StaticData.UserList.Where(u = > u.UserName.ToLowerInvariant().Equals(userName.ToLower())).FirstOrDefault() != null;  
            return Json(!isExist, JsonRequestBehavior.AllowGet);  
        }  
    }  
}

 

Now we add remote validation on the UserName of the UserViewModel property as in the following code snippet.

using System.Web.Mvc;  
 
namespace RemoteValidation.Models   
{  
    public class UserViewModel   
    {  
        [Remote("IsUserNameExist", "Validation", ErrorMessage = "User name already exist")]  
        public string UserName   
        {  
            get;  
            set;  
        }  
        public string Email   
        {  
            get;  
            set;  
        }  
    }  

 

As in the preceding code snippet, the IsUserNameExist is a method of ValidationController that is called on the blur of an input field using a GET request. Now we create UserController under the Controllers folder to render a view on the UI.

using RemoteValidation.Models;  
using System.Web.Mvc;  
 
namespace RemoteValidation.Controllers   
{  
    public class UserController: Controller   
    {  
        [HttpGet]  
        public ActionResult AddUser()   
        {  
            UserViewModel model = new UserViewModel();  
            return View(model);  
        }  
    }  

Now we add jquery.validate.js and jquery.validate.unobtrusive.js to the project and create a bundle as in the following code snippet.

using System.Web.Optimization;  
 
namespace RemoteValidation.App_Start   
{  
    public class BundleConfig   
    {  
        public static void RegisterBundles(BundleCollection bundles)   
        {  
            bundles.Add(new StyleBundle("~/Content/css").Include(  
                "~/Content/css/bootstrap.css",  
                "~/Content/css/font-awesome.css",  
                "~/Content/css/site.css"));  
 
            bundles.Add(new ScriptBundle("~/bundles/jquery").Include(  
                "~/Scripts/jquery-{version}.js"));  
 
            bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(  
                "~/Scripts/jquery.validate*"));  
        }  
    }  

Thereafter we add the following keys in the web.config file.

<add key="ClientValidationEnabled" value="true" />   
<add key="UnobtrusiveJavaScriptEnabled" value="true" />  
 
 

Thereafter we create a view for the AddUser action method. The following code snippet is for the AddUser view.

@model RemoteValidation.Models.UserViewModel  
 
< div class = "panel panel-primary" > < div class = "panel-heading panel-head" > Add User < /div>    
    <div class="panel-body">    
        @using (Html.BeginForm())    
        {    
            <div class="form-horizontal">    
                <div class="form-group">    
                    @Html.LabelFor(model => model.UserName, new { @class = "col-lg-2 control-label" })    
                    <div class="col-lg-9">    
                        @Html.TextBoxFor(model => model.UserName, new { @class = "form-control" })    
                        @Html.ValidationMessageFor(model => model.UserName)    
                    </div > < /div>    
                <div class="form-group">    
                    @Html.LabelFor(model => model.Email, new { @class = "col-lg-2 control-label" })    
                    <div class="col-lg-9">    
                        @Html.TextBoxFor(model => model.Email, new { @class = "form-control" })    
                        @Html.ValidationMessageFor(model => model.Email)    
                    </div > < /div>                    
                <div class="form-group">    
                    <div class="col-lg-9"></div > < div class = "col-lg-3" > < button class = "btn btn-success"  
                     id = "btnSubmit"  
                     type = "submit" > Submit < /button>    
                    </div >
               < /div>    
            </div >  
} < /div>    
</div >   
@section scripts   
{  
    @Scripts.Render("~/bundles/jqueryval")  

Let's run the application and put values into the user name field to execute the remote validation as in the following image.

Figure 1: Remote validation on user name


Now we move to another option, we pass an additional parameter in the remote validation. We pass both the user name and email as a parameter and check whether the username and email combination exist or not on the email input. That's why we add one more method in ValidationController as in the following code snippet for it.

[HttpGet]  
public JsonResult IsUserExist(string email, string userName)   
{  
    bool isExist = StaticData.UserList.Where(u = > u.UserName.ToLowerInvariant().Equals(userName.ToLower()) && u.Email.ToLowerInvariant().Equals(email.ToLower())).FirstOrDefault() != null;  
    return Json(!isExist, JsonRequestBehavior.AllowGet);  

Now we call this method on the Email property of UserViewModel as in the following code snippet.

using System.Web.Mvc;  
 
namespace RemoteValidation.Models   
{  
    public class UserViewModel   
    {  
        [Remote("IsUserNameExist", "Validation", ErrorMessage = "User name already exist")]  
        public string UserName   
        {  
            get;  
            set;  
        }  
        [Remote("IsUserExist", "Validation", ErrorMessage = "User already exist", AdditionalFields = "UserName")]  
        public string Email   
        {  
            get;  
            set;  
        }  
    }  
}

As in the preceding code snippet, we are passing an additional field using AdditionalFields in Remote. If we must pass more than one parameter then these will be comma-separated. Now run the application and the result will be as shown in the following image.  



ASP.NET 4.5 HOSTING - ASPHostPortal :: How to Create Nested WebGrid in ASP.NET MVC6.

clock November 19, 2014 05:51 by author Mark

How to Create Nested WebGrid with Expand/Collapse in ASP.NET MVC6.

Introduction

In this post, I am explain How to Create Nested WebGrid with Expand/Collapse in ASP.NET MVC6.
Steps :

Step - 1 : Create New Project.

  • Go to File > New > Project > Select asp.net MVC6 web application > Entry Application Name > Click OK > Select Internet Application > Select view engine Razor > OK

Step-2: Add a Database.

  • Go to Solution Explorer > Right Click on App_Data folder > Add > New item > Select SQL Server Database Under Data > Enter Database name > Add.

Step-3: Create table for fetch data.

  • Open Database > Right Click on Table > Add New Table > Add Columns > Save > Enter table name > OK.

In this example, I have used two tables as below

Step-4: Add Entity Data Model.

  • Go to Solution Explorer > Right Click on Project name form Solution Explorer > Add > New item > Select ADO.net Entity Data Model under data > Enter model name > Add.
  • A popup window will come (Entity Data Model Wizard) > Select Generate from database > Next >
  • Chose your data connection > select your database > next > Select tables > enter Model Namespace > Finish.

Step-5: Add a class for create a view model.

  • 1st : Add a folder.
  • Go to Solution Explorer > Right Click on the project > add > new folder.
  • 2nd : Add a class on that folder
  • Go to Solution Explorer > Right Click on that folder > Add > Class... > Enter Class name > Add.

Write the following code in this class

using System.Collections.Generic;
namespace MVCNestedWebgrid.ViewModel
{
    public class OrderVM
    {
        public OrderMaster order { get; set; }
        public List<OrderDetail> orderDetails { get; set; }
    }
}

Step-6: Add a new Controller.

  • Go to Solution Explorer > Right Click on Controllers folder form Solution Explorer > Add > Controller > Enter Controller name > Select Templete "empty MVC Controller"> Add.

Step-7: Add new action into your controller for show nested data in a webgrid.

Here I have added "List" Action into "Order" Controller. Please write this following code

public ActionResult List()
{
    List<OrderVM> allOrder = new List<OrderVM>();
 
    // here MyDatabaseEntities is our data context
    using (MyDatabaseEntities dc = new MyDatabaseEntities())
    {
        var o = dc.OrderMasters.OrderByDescending(a => a.OrderID);
        foreach (var i in o)
        {
            var od = dc.OrderDetails.Where(a => a.OrderID.Equals(i.OrderID)).ToList();
            allOrder.Add(new OrderVM { order= i, orderDetails = od });
        }
    }
    return View(allOrder);
}

Step-8: Add view for the Action & design.

  • Right Click on Action Method (here right click on form action) > Add View... > Enter View Name > Select View Engine (Razor) > Check "Create a strong-typed view" > Select your model class > Add.

NOTE " Please Rebuild solution before add view

Html Code
@model IEnumerable<MVCNestedWebgrid.ViewModel.OrderVM>

@{
    ViewBag.Title = "Order List";
    WebGrid grid = new WebGrid(source: Model, canSort: false);
}
<div id="main" style="padding:25px; background-color:white;">
    @grid.GetHtml(
    htmlAttributes: new {id="gridT", width="700px" },
    columns:grid.Columns(
            grid.Column("order.OrderID","Order ID"),
            grid.Column(header:"Order Date",format:(item)=> string.Format("{0:dd-MM-yyyy}",item.order.OrderDate)),
            grid.Column("order.CustomerName","Customer Name"),
            grid.Column("order.CustomerAddress","Address"),
            grid.Column(format:(item)=>{
                WebGrid subGrid = new WebGrid(source: item.orderDetails);
                return subGrid.GetHtml(
                    htmlAttributes: new { id="subT" },
                    columns:subGrid.Columns(
                            subGrid.Column("Product","Product"),
                            subGrid.Column("Quantity", "Quantity"),
                            subGrid.Column("Rate", "Rate"),
                            subGrid.Column("Amount", "Amount")
                        )                   
                    );
            })
        )
    )
</div>
Css Code
<style>
th, td {
        padding:5px;
    }
    th
    {
        background-color:rgb(248, 248, 248);       
    }
    #gridT,  #gridT tr {
        border:1px solid #0D857B;
    }
    #subT,#subT tr {
        border:1px solid #f3f3f3;
    }
    #subT {
        margin:0px 0px 0px 10px;
        padding:5px;
        width:95%;
    }
    #subT th {
        font-size:12px;
    }
    .hoverEff {
        cursor:pointer;
    }
    .hoverEff:hover {
        background-color:rgb(248, 242, 242);
    }
    .expand {
        background-image: url(/Images/pm.png);
        background-position-x: -22px;
        background-repeat:no-repeat;
    }
    .collapse  {
        background-image: url(/Images/pm.png);
        background-position-x: -2px;
        background-repeat:no-repeat;
    }
</style>
Write the following Jquery code for make webgrid collapsible
<script>
    $(document).ready(function () {
        var size = $("#main #gridT > thead > tr >th").size(); // get total column
        $("#main #gridT > thead > tr >th").last().remove(); // remove last column
        $("#main #gridT > thead > tr").prepend("<th></th>"); // add one column at first for collapsible column
        $("#main #gridT > tbody > tr").each(function (i, el) {
            $(this).prepend(
                    $("<td></td>")
                    .addClass("expand")
                    .addClass("hoverEff")
                    .attr('title',"click for show/hide")
                );
            //Now get sub table from last column and add this to the next new added row
            var table = $("table", this).parent().html();
            //add new row with this subtable
            $(this).after("<tr><td></td><td style='padding:5px; margin:0px;' colspan='" + (size - 1) + "'>" + table + "</td></tr>");
            $("table", this).parent().remove();
            // ADD CLICK EVENT FOR MAKE COLLAPSIBLE
            $(".hoverEff", this).live("click", function () {
                $(this).parent().closest("tr").next().slideToggle(100);
                $(this).toggleClass("expand collapse");
            });
        });
        //by default make all subgrid in collapse mode
        $("#main #gridT > tbody > tr td.expand").each(function (i, el) {
            $(this).toggleClass("expand collapse");
            $(this).parent().closest("tr").next().slideToggle(100);
        });    
    });
</script>



ASP.NET MVC SignalR Hosting - ASPHostPortal.com :: Create a Real-Time Message Board Making use of ASP.Net MVC 5, SignalR 2, and KnockoutJS

clock October 28, 2014 06:05 by author Ben

Have you ever questioned how Facebook sends you notifications the instant you receive a new information, friend request, or remark? Does the customer constantly look for new events? Doesn’t that consume a whole lot of memory within the user’s side? What sort of pressure does that place on Facebook’s servers?


 

Due to HTMl five as well as the support of web sockets in modern browsers, this performance can be achieved with out over-taxing the user or even the server. Leveraging a library like SignalR for .NET or Socket.IO for Node.js, most of the very hard perform around working with web sockets is already completed to suit your needs.

On this tutorial, we’re planning to build a real-time concept board, very similar to Facebook. Although this will not be something you should model and drive to manufacturing as-is, it could supply you with the fundamental groundwork for creating your own personal real-time net application.

Let's Start

Start the Project - Initial, begin a new ASP.Net MVC 5 project from Visual Studio 2013. You can title it what ever you want, but I named the undertaking “MessageBoardTutorial”. Make sure you place a checkmark close to "Web API".


Get dependencies with NuGet - Let’s go on and get downloading our required libraries out of the best way. We can get every thing with NuGet, saving us plenty of your time. Within the Remedy Explorer, right-click around the project name and click on “Manage NuGet Packages…” from the context menu.

Initial, you'll want to update all the packages presently set up to their newest variations. Be aware that because MVC 4, all the MVC libraries are bin deployed, so you will need to update them when commencing a fresh undertaking. On the still left, simply click on “Updates->nuget.org” and also you will see each of the offers that must be up-to-date. Just click on on “Update All” and allow NuGet do its thing.


When that's done, near the window. Open up the Package Supervisor Console in Tools > NuGet Package Manager > Package Manager Console. We must set up a few a lot more deals for this tutorial. Run the subsequent commands to set up the deals we need for this tutorial.

PM> Install-Package EntityFramework
PM> Install-Package Microsoft.AspNet.SignalR
PM> Install-Package Moment.js
PM> Install-Package KnockoutJS

NuGet will put in several dependencies that SignalR 2 needs. Additionally, you will get yourself a good tiny readme.txt. Feel free to read this, but we are going to be covering this listed here also.

The Front End

We are going to now truly commence coding. The Layout - First, we've got to go into the structure file and simplify issues somewhat - we don't truly require the responsive menu for this tutorial. Open /Views/Shared/_Layout.cshtml. It ought to now search such as this, assuming you failed to modify the default directories:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
</head>
<body>
    <div class="container body-content">
        @RenderBody()
    </div>
 
    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)
</body>
</html>

Edit the Home Controller and Index View - We will only need a single controller and view for this software. Inside the Remedy Explorer, open Controllers > HomeController and take away all Steps except for Index.

Now, open up the Index check out and just delete every thing. If you are a neat freak like me, truly feel totally free to eliminate another views inside the Views > Home.

Edit the View - Under is the see for your application. In case you are new to KnockoutJS, a few of this may appear unfamiliar. I will clarify a lot more when we get to the JavaScript inside the up coming section. Just be aware that wherever the thing is a "data-bind" attribute, the component is joined into a JS worth we are tracking with Knockout.

We're mostly using regular CSS courses from Bootstrap. Bootstrap gives us a quick way to incorporate a responsive grid framework for our view. The still left column includes our "login" type and also the proper the information board itself.

@{
    ViewBag.Title = "Land of Ooobook";
}
 
<div class="jumbotron">
    <h1>Land of Ooobook</h1>
    <p>Candy Kingdom's Social Network</p>
</div>
 
<div class="container">
    <div class="row">
        <div class="col-md-4">
            <form class="pad-bottom" data-bind="visible: !signedIn(), submit: signIn">
                <div class="form-group">
                    <label for="username">Sign In</label>
                    <input class="form-control" type="text" name="username" id="username" placeholder="Enter your userame" />
                </div>
                <button type="submit" class="btn btn-primary">Sign In</button>
                <br />
            </form>
 
            <div data-bind="visible: signedIn">
                <p>You are signed in as <strong data-bind="text: username"></strong></p>
            </div>
        </div>
        <div class="col-md-8">
            <div data-bind="visible: notifications().length > 0, foreach: notifications">
                <div class="summary alert alert-success alert-dismissable">
                    <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
                    <p data-bind="text: $data"></p>
                </div>
            </div>
 
            <div class="new-post pad-bottom" data-bind="visible: signedIn">
                <form data-bind="submit: writePost">
                    <div class="form-group">
                        <label for="message">Write a new post:</label>
                        <textarea class="form-control" name="message" id="message" placeholder="New post"></textarea>
                    </div>
                    <button type="submit" class="btn btn-default">Submit</button>
                </form>
            </div>
 
            <ul class="posts list-unstyled" data-bind="foreach: posts">
                <li>
                    <p>
                        <span data-bind="text: username" class="username"></span><br />
                    </p>
                    <p>
                        <span data-bind="text: message"></span>
                    </p>
 
                    <p class="no-pad-bottom date-posted">Posted <span data-bind="text: moment(date).calendar()" /></p>
 
                    <div class="comments" data-bind="visible: $parent.signedIn() || comments().length > 0">
                        <ul class="list-unstyled" data-bind="foreach: comments, visible: comments().length > 0">
                            <li>
 
                                <p>
                                    <span class="commentor" data-bind="text: username"></span>
                                    <span data-bind="text: message"></span>
                                </p>
                                <p class=" no-pad-bottom date-posted">Posted <span data-bind="text: moment(date).calendar()" /></p>
                            </li>
                        </ul>
 
                        <form class="add-comment" data-bind="visible: $parent.signedIn, submit: addComment">
                            <div class="row">
                                <div class="col-md-9">
                                    <input type="text" class="form-control" name="comment" placeholder="Add a comment" />
                                </div>
                                <div class="col-md-3">
                                    <button class="btn btn-default" type="submit">Add Comment</button>
                                </div>
                            </div>
                        </form>
                    </div>
                </li>
            </ul>
        </div>
    </div>
 
</div>
 
@section scripts {
    <script src="~/Scripts/moment.js"></script>
    <script src="~/Scripts/jquery.signalR-2.0.3.min.js"></script>
    <script src="~/signalr/hubs"></script>
    <script src="~/Scripts/knockout-3.1.0.js"></script>
    <script src="~/Scripts/board.js"></script>
}

Add a bit of CSS - We have a few custom CSS classes on top of what Bootstrap provides. Currently, /Content/Site.css is in your style bundle. Open it and replace everything above the validation helper classes with this:

.pad-bottom {
    margin-bottom: 10px;
}
 
.no-pad-bottom {
    margin-bottom: 0;
}
 
.new-post {
    background-color: #c9e0fc;
    padding: 15px 10px;
}
 
.username {
    font-weight: bold;
    color: #ff6a00;
}
 
.commentor {
    font-weight: bold;
    color: #004bff;
}
 
.posts li .date-posted {
    font-size: 12px;
    font-style: italic;
}
 
.posts li {
    border-bottom: 1px solid #CCC;
    padding: 15px 0;
}
 
.posts li:first-child {
    border-top: 1px solid #CCC;
}
 
.posts .comments {
    background-color: #efefef;
    margin-top: 10px;
    padding: 10px;
    padding-left: 30px;
}
 
.posts .comments li {
    padding-top: 10px;
    border: 0;
}
 
form.add-comment  {
    margin-top: 10px;
    margin-bottom: 10px;
}

The JavaScript

Create a script - In the Scripts directory, make a new script called board.js. This script will contain the client-side logic for the application.

Edit the script - Let's begin with our script.

A message board is made of posts and comments to those posts. Let's define those objects.

var post = function (id, message, username, date) {
    this.id = id;
    this.message = message;
    this.username = username;
    this.date = date;
    this.comments = ko.observableArray([]);
 
    this.addComment = function (context) {
        var comment = $('input[name="comment"]', context).val();
        if (comment.length > 0) {
            $.connection.boardHub.server.addComment(this.id, comment, vm.username())
            .done(function () {
                $('input[name="comment"]', context).val('');
            });
        }
    };
}
 
var comment = function (id, message, username, date) {
    this.id = id;
    this.message = message;
    this.username = username;
    this.date = date;
}

A submit has an observable variety of remarks. This enables it in order that when new remarks come in, it's immediately displayed within the view.

We've outlined our submit and remark objects. Now let's define our view design that is the glue from the application.

var vm = {
    posts: ko.observableArray([]),
    notifications: ko.observableArray([]),
    username: ko.observable(),
    signedIn: ko.observable(false),
    signIn: function () {
        vm.username($('#username').val());
        vm.signedIn(true);
    },
    writePost: function () {
        $.connection.boardHub.server.writePost(vm.username(), $('#message').val()).done(function () {
            $('#message').val('');
        });
    },
}
 
ko.applyBindings(vm);

We have an observable array of posts (which have an observable array of remarks). We even have an observable assortment of notifications, which inform customers of latest posts or comments on their posts. Our view model tracks the username and if a user is signed in. Finally, a view design can include techniques.

Next, we've a way for loading posts, which is known as when the web page hundreds and the user connects into a SignalR hub. The posts are loaded from the Net API controller which we are going to make later. Each and every submit is additional to the observable assortment of posts. Each and every from the post's feedback are added to the comments observable variety of the submit. This really is a really verbose method of performing this, but I wanted to make it distinct what was happening right here.

function loadPosts() {
$.get('/api/posts', function (data) {
    var postsArray = [];
    $.each(data, function (i, p) {
        var newPost = new post(p.Id, p.Message, p.Username, p.DatePosted);
        $.each(p.Comments, function (j, c) {
            var newComment = new comment(c.Id, c.Message, c.Username, c.DatePosted);
            newPost.comments.push(newComment);
        });
 
        vm.posts.push(newPost);
        });
    });
}

The rest of the script has to do with SignalR connections and methods. We'll get back to that later. Below is the entire board.js script.

var post = function (id, message, username, date) {
    this.id = id;
    this.message = message;
    this.username = username;
    this.date = date;
    this.comments = ko.observableArray([]);
 
    this.addComment = function (context) {
        var comment = $('input[name="comment"]', context).val();
        if (comment.length > 0) {
            $.connection.boardHub.server.addComment(this.id, comment, vm.username())
            .done(function () {
                $('input[name="comment"]', context).val('');
            });
        }
    };
}
 
var comment = function (id, message, username, date) {
    this.id = id;
    this.message = message;
    this.username = username;
    this.date = date;
}
 
var vm = {
    posts: ko.observableArray([]),
    notifications: ko.observableArray([]),
    username: ko.observable(),
    signedIn: ko.observable(false),
    signIn: function () {
        vm.username($('#username').val());
        vm.signedIn(true);
    },
    writePost: function () {
        $.connection.boardHub.server.writePost(vm.username(), $('#message').val()).done(function () {
            $('#message').val('');
        });
    },
}
 
ko.applyBindings(vm);
 
function loadPosts() {
    $.get('/api/posts', function (data) {
        var postsArray = [];
        $.each(data, function (i, p) {
            var newPost = new post(p.Id, p.Message, p.Username, p.DatePosted);
            $.each(p.Comments, function (j, c) {
                var newComment = new comment(c.Id, c.Message, c.Username, c.DatePosted);
                newPost.comments.push(newComment);
            });
 
            vm.posts.push(newPost);
        });
    });
}
 
$(function () {
    var hub = $.connection.boardHub;
    $.connection.hub.start().done(function () {
        loadPosts(); // Load posts when connected to hub
    });
 
    // Hub calls this after a new post has been added
    hub.client.receivedNewPost = function (id, username, message, date) {
        var newPost = new post(id, message, username, date);
        vm.posts.unshift(newPost);
 
        // If another user added a new post, add it to the activity summary
        if (username !== vm.username()) {
            vm.notifications.unshift(username + ' has added a new post.');
        }
    };
 
    // Hub calls this after a new comment has been added
    hub.client.receivedNewComment = function (parentPostId, commentId, message, username, date) {
        // Find the post object in the observable array of posts
        var postFilter = $.grep(vm.posts(), function (p) {
            return p.id === parentPostId;
        });
        var thisPost = postFilter[0]; //$.grep returns an array, we just want the first object
 
        var thisComment = new comment(commentId, message, username, date);
        thisPost.comments.push(thisComment);
 
        if (thisPost.username === vm.username() && thisComment.username !== vm.username()) {
            vm.notifications.unshift(username + ' has commented on your post.');
        }
    };
});

The Data Layer - We will be making use of Entity Framework as well as the Code First sample for our straightforward info layer.

Inside the Models directory, develop a brand new C# class referred to as MessageBoard.cs. Our data designs are little, and in our scenario we'll just place them in a single file alongside with all the data context.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Linq;
using System.Web;
 
namespace MessageBoardTutorial.Models
{
    public class MessageBoardContext : DbContext
    {
        public DbSet<Post> Posts { get; set; }
        public DbSet<Comment> Comments { get; set; }
    }
 
    public class Post
    {
        [Key]
        public int Id { get; set; }
        public string Message { get; set; }
        public string Username { get; set; }
        public DateTime DatePosted { get; set; }
        public virtual ICollection<Comment> Comments { get; set; }
    }
 
    public class Comment
    {
        [Key]
        public int Id { get; set; }
        public string Message { get; set; }
        public string Username { get; set; }
        public DateTime DatePosted { get; set; }
        public virtual Post ParentPost { get; set; }
    }
}

Although the actual database doesn't yet exist, it will likely be produced if the application deems it essential. Should you maintain your internet.config unchanged, it's going to develop it within your LocalDB instance of SQL Server Specific.

The API

The script requirements a technique to get in touch with to get the posts to the concept board. Whilst we could just tack a technique on to our HomeController that would try this, we can equally as effortlessly create an ASP.Web Internet API controller which will fetch and immediately convert the posts into a JSON format.

Create the API Controller - In the Solution Explorer, right click on the Controllers directory and click on Add > Web API Controller Class (v2) in the context menu. Add a new Web API controller and call it PostsController.cs

Write the API
- Replace the code with the below. Our API will simply return a JSON or XML-serialized array of all of the posts and comments on the message board when a client calls http://[yoursite]/api/posts.

using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Web.Http;
    using MessageBoardTutorial.Models;
 
    namespace MessageBoardTutorial.Controllers
    {
        public class PostsController : ApiController
        {
            private MessageBoardContext _ctx;
            public PostsController()
            {
                this._ctx = new MessageBoardContext();
            }
 
            // GET api/<controller>
            public IEnumerable<post> Get()
            {
                return this._ctx.Posts.OrderByDescending(x => x.DatePosted).ToList();
            }
        }
    }
</post></controller>

Handle circular references - If you look at our data models, a Post contains a virtual collection of comments, and a Comment contains a virtual Post that refers to the comment's parent. This circular reference will freak out Web API's serialization method. To solve this, just add the following line of code to the Register method in the WebApiConfig class located at App_Start/WeApiConfig.cs
   
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling =
    Newtonsoft.Json.ReferenceLoopHandling.Ignore;

Circular references will now be ignored.

Implementing the SignalR Hub

SignalR provides a relationship between clientele and also the server. Clients connect to a SignalR Hub. The Hub can then contact client-side occasions on a single, some, or all related clients. The Hub tracks which consumers are linked to it. This can be the center of real-time net programs. Within our case, a client generates a fresh submit or comment, which phone calls a method around the Hub. The Hub then calls a method on all of the message board's connected users that inserts the brand new submit or remark.

In a nutshell, the awesomeness of SignalR is that it may call JavaScript capabilities on any browser linked to it. The outdated assemble is clientele could only get in touch with server-side features. This type of functionality could only be achieved via long-polling (a customer working an infinite loop that calls a server method).


Newer browsers connect to hubs via HTML 5 web sockets. For older browsers, there are long-polling and "forever frame" fallbacks.

Map the hubs - In order for SignalR to begin and for the web application to map the connection hubs, we must create an OWIN startup class. Lucky for us, this just involves a couple of clicks and a line of code. Right-click on the solution and add a new item. Find the OWIN Startup Class template. Name this file "Startup.cs". Now, you just have to add one line of code in the Configuration method to map the hubs.

using System;
using System.Threading.Tasks;
using Microsoft.Owin;
using Owin;
 
[assembly: OwinStartup(typeof(MessageBoardTutorial.Startup))]
 
namespace MessageBoardTutorial
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
        }
    }
}

Create the Hub - Make a new directory in the root of your project called Hubs. Now, right-click on this new directory and click on Add > New Item... in the context menu. Create a new SignalR Hub Class called BoardHub.cs.


Replace the code in the file with the below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
using MessageBoardTutorial.Models;
 
namespace MessageBoardTutorial.Hubs
{
    public class BoardHub : Hub
    {
        public void WritePost(string username, string message)
        {
            var ctx = new MessageBoardContext();
            var post = new Post { Message = message, Username = username, DatePosted = DateTime.Now };
            ctx.Posts.Add(post);
            ctx.SaveChanges();
 
            Clients.All.receivedNewPost(post.Id, post.Username, post.Message, post.DatePosted);
        }
 
        public void AddComment(int postId, string comment, string username)
        {
            var ctx = new MessageBoardContext();
            var post = ctx.Posts.FirstOrDefault(p => p.Id == postId);
 
            if (post != null)
            {
                var newComment = new Comment { ParentPost = post, Message = comment, Username = username, DatePosted = DateTime.Now };
                ctx.Comments.Add(newComment);
                ctx.SaveChanges();
 
                Clients.All.receivedNewComment(newComment.ParentPost.Id, newComment.Id, newComment.Message, newComment.Username, newComment.DatePosted);
            }
        }
    }

}

The Hub contains a method for writing a new post and a method for writing a new comment. Both methods are called from the client and ultimately call client-side methods for connected users.

For example, the writePost client-side method is called when a user writes a new post:

writePost: function () {
    $.connection.boardHub.server.writePost(vm.username(), $('#message').val()).done(function () {
        $('#message').val('');
    });
},

This method calls the WritePost method on the Hub. After the new post is added to the database, the Hub then calls the receivedNewPost method on all connected clients.

Clients.All.receivedNewPost(post.Id, post.Username, post.Message, post.DatePosted);

From BoardHub.cs

hub.client.receivedNewPost = function (id, username, message, date) {
    var newPost = new post(id, message, username, date);
    vm.posts.unshift(newPost);
 
    // If another user added a new post, add it to the activity summary
    if (username !== vm.username()) {
        vm.notifications.unshift(username + ' has added a new post.');
    }
};

From board.js

The Hub sends info about the new submit to this client method, which then helps make a brand new Publish JavaScript object and adds it to the starting from the view model's posts observable array. This new post is instantaneously displayed for all related customers since Knockout is observing this array. A brand new notification can also be produced for all customers other than the creator of the new publish.

Adding a remark follows the same pattern, although the client callback method differs marginally:

hub.client.receivedNewComment = function (parentPostId, commentId, message, username, date) {
    // Find the post object in the observable array of posts
    var postFilter = $.grep(vm.posts(), function (p) {
        return p.id === parentPostId;
    });
    var thisPost = postFilter[0]; //$.grep returns an array, we just want the first object
 
    var thisComment = new comment(commentId, message, username, date);
    thisPost.comments.push(thisComment);
 
    if (thisPost.username === vm.username() && thisComment.username !== vm.username()) {
        vm.notifications.unshift(username + ' has commented on your post.');
    }
};

The ID of the parent post of the comment is sent to the client, which then adds the new comment to the comments observable array of the post

Finally, let us run this point

Now you can construct and operate the project! Ooo is in dire need of a social community.

Go on and open up two browser windows and "log in" as a various person on every. Recognize how once you include a submit in a single window, it instantaneously is additional towards the other window in addition to a notification. Now, the Ice King can annoy princesses on-line too! Effectively, possibly that is not all that good.




ASP.NET SignalR Hosting ASPHostPortal.com :: How you can Push Data from Server to Client Making use of SignalR

clock October 3, 2014 20:11 by author Ben

In real-time environments the server is aware from the information updates, occasion occurrences, and so forth. however the customer doesn’t understand it unless the request is initiated by the client towards the server seeking the updates. This is typically attained through techniques like constant polling, extended polling, and so forth. and these methodologies incur lots of site visitors and load to the server.

 


The alternate method to simplify and reduce the overhead is to make the server effective at notifying the clients. There are lots of systems launched to attain this and a few of them are WebSockets, SSE (Server Sent Activities), Lengthy polling, and so forth. Every of those techniques has its personal caveats like WebSockets are supported only on browsers that assistance HTML5 and SSE just isn't supported on Web Explorer.

SignalR is surely an Asp.Net library, which can be created to utilize the present transport systems underneath primarily based within the client nature and the assistance it provides. ASP.NET SignalR is effective at pushing the information to some wide selection of clientele like a Internet webpage, Window application, Window Cellphone Application, and so on. The onus is now taken out in the developers of stressing about which server push transportation to use and selecting the fallbacks in the event of unsupported situations.


Composition of SignalR

To start out with SignalR it is vital that you know the components. The server component from the SignalR engineering demands web hosting a PersistentConnection or even a SignalR hub.

  1. PersistentConnection - This can be a server endpoint to press the messages for the clientele. It enables the developers to accessibility the SignalR features at a low stage.
  2. Hub - It really is built on top of the PersistentConnection exposing high-level APIs and it allows the builders to produce the server to consumer calls within an RPC style (Remote Method Contact).

Within the client front SignalR offers various consumer libraries to different customers like Home windows Application, Internet Type, Home windows Cellphone, iOS, Android, and so on. The clientele must make use of the consumer libraries to get connected to the SignalR hub. These client libraries are available as NuGet deals.




Sample Application

Let us construct a sample chat software that broadcasts the messages to all linked customers or to specific teams. In this instance think about the customers to become a Windows software as well as a net kind customer.


Creating an Asp.Net SignalR Hub

Open Visual Studio and develop an vacant Asp.net MVC application named MyChatApplicationServer. Now open up the NuGet deals, lookup and include Microsoft ASP.Net SignalR.

Now right click on within the venture, include the SignalR Hub class and name it as MyChatHub. Add the following code to the course.

public class MyChatHub : Hub
    {
        public void BroadcastMessageToAll(string message)
        {
            Clients.All.newMessageReceived(message);
        }
 
        public void JoinAGroup(string group)
        {
            Groups.Add(Context.ConnectionId, group);
        }
 
        public void RemoveFromAGroup(string group)
        {
            Groups.Remove(Context.ConnectionId, group);
        }
 
        public void BroadcastToGroup(string message, string group)
        {
            Clients.Group(group).newMessageReceived(message);
        }
    }

The HUB course also provides the qualities Clientele, Groups, Context and events like OnConnected, and so on.

Ultimately it's also wise to add Owin startup course to map the obtainable hubs as proven below.

    [assembly: OwinStartup(typeof(MyChatApplicationServer.Startup))]
   
    namespace MyChatApplicationServer
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                app.MapSignalR();
            }
        }
    }

Pushing Data to a Web Form Client

Now create an internet form client venture named WebClient and incorporate a simple HTML file ChatWebClient.html with all the following code. Include the references towards the necessary script documents.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script src="Scripts/jquery-1.6.4.min.js"></script>
    <script src="Scripts/jquery.signalR-2.0.1.min.js"></script>
    <script src="http://localhost:32555/signalr/hubs/" type="text/javascript"></script>
    <script type="text/javascript">
        $(function () {
            var myChatHub = $.connection.myChatHub;
            myChatHub.client.newMessageReceived = function (message) {
                $('#ulChatMessages').append('<li>' + message + '</li>');
            }
            $.connection.hub.url = "http://localhost:32555/signalr";
            $.connection.hub.start().done(function () {
                $('#btnSubmit').click(function (e) {
                    myChatHub.server.broadcastMessageToAll($('#txtEnterMessage').val(), 'Web user');
                });
            }).fail(function (error) {
                console.error(error);
            });;
         
        });
    </script>
</head>
<body>
    <div>
        <label id="lblEnterMessage">Enter Message: </label>
        <input type="text" id="txtEnterMessage" />
        <input type="submit" id="btnSubmit" value="Send Message" />
        <ul id="ulChatMessages"></ul>
    </div>
</body>
</html>

You'll find two ways of applying the customer function one with proxy as well as other without having. The above instance is the a single without a proxy.

In the link begin you may also point out which transport SignalR must use.
Pushing Info to a Home windows Application Consumer

Let us include a home windows application and subscribe for the SignalR host. Create a new windows software named WinFormClient and from the nugget offers install Microsoft ASP.Net SignalR .Internet consumer package deal. Within the Program.cs add the subsequent code.

    namespace WinFormClient
    {
        public partial class Form1 : Form
        {
            HubConnection hubConnection;
            IHubProxy hubProxy;
            public Form1()
            {
                InitializeComponent();
                hubConnection = new HubConnection("http://localhost:32555/signalr/hubs");
                hubProxy = hubConnection.CreateHubProxy("MyChatHub");
                hubProxy.On<string>("newMessageReceived", (message) => lstMessages.Items.Add(message));
                hubConnection.Start().Wait();
            }
   
            private void btnSubmit_Click(object sender, EventArgs e)
            {
                hubProxy.Invoke("BroadcastMessageToAll", textBox1.Text, "Window App User").Wait();
            }
        }
    }

When done go on and operate each the net and Windows consumer. Enter the messages and look at how the information is getting pushed throughout each the clients although they may be of a distinct character.



SignalR is able of serving several connected clients irrespective of the customer system or technology. I hope this short article offers a good sum of data about pushing information from the server to consumer using Asp.Internet SignalR.



Cheap ASP.NET 4.5 Hosting

We’re a company that works differently to most. Value is what we output and help our customers achieve, not how much money we put in the bank. It’s not because we are altruistic. It’s based on an even simpler principle. "Do good things, and good things will come to you".

Success for us is something that is continually experienced, not something that is reached. For us it is all about the experience – more than the journey. Life is a continual experience. We see the Internet as being an incredible amplifier to the experience of life for all of us. It can help humanity come together to explode in knowledge exploration and discussion. It is continual enlightenment of new ideas, experiences, and passions


Author Link


 

Corporate Address (Location)

ASPHostPortal
170 W 56th Street, Suite 121
New York, NY 10019
United States

Tag cloud

Sign in