Archive

Archive for the ‘asp.net features’ Category

Broadcasting website data using SignalR in MVC

December 19, 2015 Leave a comment

SignalR is a cool API in dotnet framework which you can use to show real time data in your application. You can broadcast real time data to all the connected clients(browsers) once data is ready on server side.

It generates javascripts when rendering on the client side. But you don’t have to worry about all the proxy javascripts as signalR takes care of all those things. All you have to do is just call your javascript function from the server side.

To add signalR in your project go to Nuget Package Manager and search for signalR , you will  see Microsoft ASP.NET SignalR at the top of the list just click install. It will add all the references required to run it. If your project doesn’t have a Scripts folder it will add a Scripts folder and import jquery and jquery-signalR libraries.

At this stage you’ve got all the required references and scripts now its time to add the SignalR startup class so we can tell the OWIN so it can configure it.

Startup class is like;


using Microsoft.Owin;
using Owin;

[assembly: OwinStartupAttribute(typeof(DeepASP.SignalRMVC.SignalRStartup))]
namespace DeepASP.SignalRMVC
{
public partial class SignalRStartup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
}

I added this startup class in App_Start folder as MVC has already created this folder with the startup classes. But you can keep wherever you want. Now add the SignalR Hub class. If you right click and add new item it should be under signalR templates but if it is not, don’t worry just add a new class and inherit it from abstract class–

 Microsoft.AspNet.SignalR.Hub

Lets name this class as “SignalRHub”. You can name anything but just remember this is the hub which you will use in the javascript side. Although you can change the display name by decorating this class with attribute

 [Microsoft.AspNet.SignalR.Hubs.HubName("DisplayName")].

This class looks like;

namespace DeepASP.SignalRMVC
{
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
[HubName("Broadcaster")]
public class SignalRHub : Hub
{ }
}

Logically that’s all you needed for signalR. Now you want to access the Hub so you can call javascript function from server side, right? YES. OK lets add another class Broadcast.cs as;


namespace DeepASP.SignalRMVC
{
    using Microsoft.AspNet.SignalR;
    using System;

    public class Broadcast
    {
        private static Lazy<IHubContext> context = new Lazy<IHubContext>(() => GlobalHost.ConnectionManager.GetHubContext<SignalRHub>());

        private static IHubContext Broadcaster
        {
            get
            {
                return context.Value;
            }
        }

        public static bool SendDataToAllConnectedClients(string data)
        {
            Broadcaster.Clients.All.JavaScriptFunction(data);
            return true;
        }
    }
}

SendDataToAllConnectedClients method calls javascript function “JavaScriptFunction” passing a string parameter. You can pass as many complex objects in JSON format as you want. Just for clarity I call the javascript side function name as JavascriptFunction but you will give a meaningful and purposeful name. Now we will write this javascript function. Like for this post I created another controller called BroadcastController.cs and its view. Now as because this view will be responsible for broadcasting the message sent from server we will add the required .js libraries in this view:

<script src="~/Scripts/jquery-2.1.4.js"></script>
<script src="~/Scripts/jquery.signalR-2.2.0.js"></script>
<script src="~/signalr/hubs"></script> 
<script> 
var broadcaster = $.connection.Broadcaster; 
broadcaster.client.JavaScriptFunction = function (d) { 
   document.getElementById("data").innerHTML = d; 
} 
$.connection.hub.start(); 
</script> 

Order of javascript libraries DOES matter. Now this is where we are subscribing the javascript function “JavaScriptFunction” which we are calling from server side. For this demo I was just sending a string html from server side but you can write your logic for this function here when you are subscribing.

Yep that’s all signalR is about. If you are interested in downloading this demo just click here.

Well here are some important things to remember before you going to move into production.

Pre-requisites of SignalR2:

  • Dotnet Framework 4.5
  • The user for which Application (IIS) is running must have full trust
  • IIS must be running in Managed mode NOT  Classic.
  • IIS 7 or greater (Websocket requires IIS8)
  • jQuery version must be greater  than 1.6

If you want more control on server side then you might want to look into this http://socket.io/docs/.

Well here are some of the cool articles I came across while researching some of the issues when I was working on my signalR project;

http://www.asp.net/signalr/overview/getting-started/supported-platforms

http://bradwilson.typepad.com/blog/2012/07/webstack-of-love.html

http://www.asp.net/signalr/overview/getting-started/tutorial-server-broadcast-with-signalr

Categories: asp.net features

HTML to PDF in ASP.Net

March 8, 2015 Leave a comment

In this post I am going to show you how can we easily import html into pdf in asp.net without compromising UI. I was looking for an alternative of crystal reports in asp.net to generate reports without any javascript burden and complexities in developing them.

As crystal reports gives you the feature to import the report into pdf or excel. So I did some research for libraries for these file formats. Most programming folks were recommending for ITextSharp.

I knew and had used ITextSharp for pdf merge in a project. But when I tried to use this for html to pdf I didn’t get the result I wanted and there were a lot of workarounds needed to get all my requirements.

So I looked for some other solutions and fortunately I found this amazing free library NReco. Which by the way is a wrapper library in .net for this wonderful html to pdf exe wkhtmltopdf.

Before going into detail I’d like to mention my requirements when I was working on html to pdf import on a project. So it would be easier for you if it matches your requirements as well.

Requirements

  • Same PDF page as its showing on browser
  • Show Background-color
  • Repeat header on every page
  • Show page number on every page
  • Page number count on every page
  • Show images
  • Option to change page orientation (Landscape, Portrait)
  • Free library
  • Support css

Issues I encountered and resolved.

  • Header overlaps when repeating on other pages
  • Page number
  • deploying on 32bit OS.

I’ve attached the link of a sample asp.net solution at the end of source codes.

Example code;

/// <summary>
/// Converts html into PDF using nReco dll and wkhtmltopdf.exe.
/// </summary>        
private byte[] ConvertHtmlToPDF()
{
   HtmlToPdfConverter nRecohtmltoPdfObj = new HtmlToPdfConverter();
   nRecohtmltoPdfObj.Orientation = PageOrientation.Portrait;
   nRecohtmltoPdfObj.PageFooterHtml = CreatePDFFooter();
   nRecohtmltoPdfObj.CustomWkHtmlArgs = "--margin-top 35 --header-spacing 0 --margin-left 0 --margin-right 0";            
   return nRecohtmltoPdfObj.GeneratePdf(CreatePDFScript() + ShowHtml() + "</body></html>");
}

Html string sample;

        /// <summary>
        /// Returns HTML string.
        /// </summary>
        /// <remarks>Its test data. You can create html using data getting from database or whatever your data source.</remarks>
        /// <returns></returns>
        public string ShowHtml()
        {
            StringBuilder html = new StringBuilder("<table id=\"tblReport\" cellspacing=\"0\" cellpadding=\"0\" style=\"border-width: 0px; border-collapse: collapse; font-family: Tahoma; font-size: 11px; table-layout: fixed; line-height: 20px;\">" +
            "<thead>" +
                "<tr style=\"background-color: #4862A3; font-family: verdana; color: white;\">" +
                    "<th style=\"width: 200px;  text-align: center;\">Name</th>           " +
                    "<th style=\"width: 150px; text-align: center;\">Date Published</th> " +
                    "<th style=\"width: 200px;  text-align: center;\">Category</th>     " +
                    "<th style=\"width: 100px; text-align: center;\">Popularity</th>     " +
                "</tr>" +
            "</thead>" +
            "<tbody>" +
                "<tr>" +
                    "<th style=\"width: 200px; text-align: left; text-align: center;\">Domain Driven Design</th>" +
                    "<th style=\"width: 150px; text-align: left; text-align: center;\">02/05/2011</th>          " +
                    "<th style=\"width: 200px; text-align: center; text-align: center;\">Design Patterns</th>   " +
                    "<th style=\"width: 100px; text-align: left; text-align: center;\">6 out of 10</th>         " +
                "</tr>" +
                "<tr>" +
                    "<th style=\"width: 200px; text-align: left; text-align: center;\">When Not to use jQuery</th> " +
                    "<th style=\"width: 150px; text-align: left; text-align: center;\">02/05/2011</th>             " +
                    "<th style=\"width: 200px; text-align: center; text-align: center;\">jQuery in ASP.Net</th>    " +
                    "<th style=\"width: 100px; text-align: left; text-align: center;\">8 out of 10</th>            " +
                "</tr>" +
                "<tr>" +
                    "<th style=\"width: 200px; text-align: left; text-align: center;\">Programmer's evolution</th> " +
                    "<th style=\"width: 150px; text-align: left; text-align: center;\">02/05/2011</th>             " +
                    "<th style=\"width: 200px; text-align: center; text-align: center;\">General Programming</th>  " +
                    "<th style=\"width: 100px; text-align: left; text-align: center;\">4 out of 10</th>            " +
                "</tr>");
            for (int i = 0; i < 150; i++)
            {
                html.Append("<tr>" +
                    "<th style=\"width: 200px; text-align: left; text-align: center;\">Test Data</th> " +
                    "<th style=\"width: 150px; text-align: left; text-align: center;\">02/05/2011</th>             " +
                    "<th style=\"width: 200px; text-align: center; text-align: center;\">import html to pdf in asp.net</th>  " +
                    "<th style=\"width: 100px; text-align: left; text-align: center;\">4 out of 10</th>            " +
                "</tr>");
            }
            html.Append("</tbody></html>");
            return html.ToString();
        }

Creat Page number on every page with count.

private string CreatePDFScript()
        {
            return "<html><head><style>td,th{line-height:20px;} tr { page-break-inside: avoid }</style><script>function subst() {var vars={};var x=document.location.search.substring(1).split('&');for(var i in x) {var z=x[i].split('=',2);vars[z[0]] = unescape(z[1]);}" +
            "var x=['frompage','topage','page','webpage','section','subsection','subsubsection'];for(var i in x) {var y = document.getElementsByClassName(x[i]);" +
            "for(var j=0; j<y.length; ++j) y[j].textContent = vars[x[i]];}}</script></head><body onload=\"subst()\">";
        }

Below image is a snap of the source code. You can download sample asp.net solution here.
ClassStructure

Handling DBNull.Value

October 20, 2014 2 comments

Every asp.net developer use DbNull.Value when writing code to communicate with database. But it could sometimes be quite painful when you want to write with a null-coalescing or ?: operator. The same would be when getting something from database and type checking.

For example in this code snippet I wrote a function which stores a comment in database. As userWebsite is an optional parameter so it could be null and if database expects null then you need to send DBNull.Value. To make it adjustable in ?: operator you just have to cast into an object. like;
Value = userWebsite != null ? userWebsite : (object)DBNull.Value.
I tested this code in fw 4.0 only, so I’m not sure about older versions.

internal int SaveComment(string name, string email, string comment, string? userWebsite)
        {
            SqlCommand _command = new SqlCommand
            {
                Connection = new SqlConnection { ConnectionString = "connection string" },
                CommandType = CommandType.StoredProcedure,
                CommandText = "csp_comment_save",
            };
            _command.Parameters.AddRange(new SqlParameter[] { new SqlParameter { ParameterName = "name", Value = name, SqlDbType = SqlDbType.VarChar, Size = 100 },
            new SqlParameter { ParameterName = "email", Value = email, SqlDbType = SqlDbType.VarChar, Size = 50 },
            new SqlParameter { ParameterName = "comment", Value = comment, SqlDbType = SqlDbType.VarChar, Size = 255 },
            new SqlParameter { ParameterName = "website", Value = userWebsite != null ? userWebsite : (object)DBNull.Value, SqlDbType = SqlDbType.VarChar, Size = 20 }});
            _command.Connection.Open();
            int result=_command.ExecuteNonQuery();
            _command.Connection.Close();
            return result;
        }