In this post, we will see how to create a sample C# Corner User Flair in ASP.NET MVC application using HtmlAgilityPack. We will also add a provision to save this flair as an image using a third-party JavaScript library, html2canvas.
Introduction
C# Corner itself provides the user flair. This is my humble attempt to scrape the data from C# Corner user profile page using HtmlAgilityPack in ASP.NET MVC application. We collected the user data like Name, Rank, Reputation, Reads from the corresponding span ids. We also got all the image URLs from the site (profile page) and only took the image used for the author's image. We will create a sample user flair using this data. Will also provide an option to save this flair as an image.
Dependencies for this project -
- Visual Studio 2015 or higher (we are using .NET framework 4.5)
- Install HtmlAgilityPack using NuGet
- Valid CDN link for html2canvas library
Create an MVC application in Visual Studio
We can choose the ASP.NET 4.5.2 Templates and MVC template. Click the OK button to create the project.
In the MVC project, we have Controllers, Models, and Views folders. We need to create a “UserInfo” class inside the Models folder.
- namespace CsharpCornerFlairMVC.Models
- {
- public class UserInfo
- {
- public string UserId { get; set; }
- public string UserName { get; set; }
- public string UserRank { get; set; }
- public string UserReputation { get; set; }
- public string UserRead { get; set; }
- public string ImageURL { get; set; }
- public bool InvalidUser { get; set; }
- public bool PageInit { get; set; }
- }
- }
Please note that we have additionally added “InvalidUser” and “PageInit” properties along with other user information properties in this class. These are used for controlling the visibility of some page contents in Razor Views. We will discuss about these details later in this post.
Now, modify the “_Layout.cshtml” Razor View file inside the Views -> Shared folder.
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>C# Corner Sample Flair</title>
- <link href="https://csharpcorner-mindcrackerinc.netdna-ssl.com/Images/McnIcon.ico" rel="shortcut icon" type="image/x-icon" />
- @Styles.Render("~/Content/css")
- @Scripts.Render("~/bundles/modernizr")
- </head>
- <body>
- <div class="navbar navbar-inverse navbar-fixed-top">
- <div class="container">
- <div class="navbar-header">
- <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- </button>
- @Html.ActionLink("C# Corner Sample Flair", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
- </div>
- <div class="navbar-collapse collapse">
- <ul class="nav navbar-nav">
- <li>@Html.ActionLink("Home", "Index", "Home")</li>
- <li>@Html.ActionLink("About", "About", "Home")</li>
- </ul>
- </div>
- </div>
- </div>
- <div class="container body-content">
- @RenderBody()
- <hr />
- <footer>
- <p>
- © 2019 - C# Corner Sample Flair
- <a href="https://codewithsarath.com" target="_blank">By Sarath Lal</a>
- </p>
- </footer>
- </div>
- @Scripts.Render("~/bundles/jquery")
- @Scripts.Render("~/bundles/bootstrap")
- @RenderSection("scripts", required: false)
- </body>
- </html>
This is a master layout page which will be rendered with all the other Views. We can modify the important Razor View file “Index.cshtml”.
- @{
- ViewBag.Title = "Home Page";
- }
- @model CsharpCornerFlairMVC.Models.UserInfo
- @using (Html.BeginForm("Index", "Home", FormMethod.Post))
- {
- <div style="padding-top:30px;">
- @Html.Label("C# Corner User Id")
- </div>
- <div>
- @Html.TextBoxFor(m => m.UserId)
- <i onclick="resetValues()" style="color:forestgreen; cursor:pointer;" class="glyphicon glyphicon-repeat" title="Reset Values"></i>
- </div>
- <div style="padding-top:20px;">
- <input class="btn-lg btn-info" type="submit" id="btnSubmit" value="Process Flair" onclick="processFlair()" name="Submit" />
- </div>
- <div id="process" style="display:none">
- <img src="~/Content/process.gif" alt="Process" />
- </div>
- @Html.HiddenFor(model => model.UserId)
- }
- @if (Model != null && !Model.InvalidUser && !Model.PageInit)
- {
- <div id="flair" style="padding-top:30px; width:550px; column-count: 4;">
- <div style="float: left;">
- <img src="~/Content/SiteLogo.png" style="width:30px; height:22px;" alt="C# Corner" />
- </div>
- <div style="padding-left: 30px; width:250px;">
- @Model.UserName
- </div>
- <div style="padding-left: 30px; width:250px; cursor:pointer">
- <i class="greendot"></i> <text title="Current Rank">@Model.UserRank</text> <i class="orangedot"></i> <text title="Total Reputation">@Model.UserReputation</text> <i class="bluedot"></i> <text title="Total Reads">@Model.UserRead</text>
- </div>
- <div style="float: right;">
- <img src="@Model.ImageURL" alt="NA"
- style="border-radius: 50%; width:50px; height:50px;">
- </div>
- </div>
- <div id="saveflair">
- <div style="padding-top:20px;">
- <input class="btn-success btn-sm" type="button" onclick="saveAsImage()" value="Save as Image!" />
- </div>
- <div style="padding:10px">
- <img id="txtScreenshot" src="">
- </div>
- </div>
- }
- else
- {
- if (Model != null && Model.InvalidUser && !Model.PageInit)
- {
- <div id="invaliduser" style="padding-top:30px;">
- <i>Invalid User Id</i>
- </div>
- }
- }
- @section scripts {
- <script src="//cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
- <script>
- function resetValues() {
- document.getElementById("UserId").value = '';
- var invalidUser = @Html.Raw(Json.Encode(Model.InvalidUser));
- if (invalidUser) {
- document.getElementById("invaliduser").style.display = 'none';
- }
- else {
- document.getElementById("saveflair").style.display = 'none';
- document.getElementById("flair").style.display = 'none';
- }
- }
- function processFlair() {
- document.getElementById("process").style.display = 'block';
- var invalidUser = @Html.Raw(Json.Encode(Model.InvalidUser));
- if (invalidUser) {
- document.getElementById("invaliduser").style.display = 'none';
- }
- else {
- document.getElementById("saveflair").style.display = 'none';
- document.getElementById("flair").style.display = 'none';
- }
- }
- function saveAsImage() {
- html2canvas(document.getElementById("flair"),
- {
- useCORS: true,
- onrendered: function (canvas) {
- var screenshot = canvas.toDataURL("image/png");
- document.getElementById("txtScreenshot").setAttribute("src", screenshot);
- }
- });
- }
- </script>
- }
I have put all the client-side logic inside this Razor file. As I mentioned earlier, I have used the “InvalidUser” and “PageInit” properties to hide/show some div tags.
- if (Model != null && Model.InvalidUser && !Model.PageInit)
- {
- <div id="invaliduser" style="padding-top:30px;">
- <i>Invalid User Id</i>
- </div>
- }
Please note, I have also used @Html.Raw to get the server Model values in the client-side code.
- function resetValues() {
- document.getElementById("UserId").value = '';
- var invalidUser = @Html.Raw(Json.Encode(Model.InvalidUser));
- if (invalidUser) {
- document.getElementById("invaliduser").style.display = 'none';
- }
- else {
- document.getElementById("saveflair").style.display = 'none';
- document.getElementById("flair").style.display = 'none';
- }
- }
I have used a very simple logic to save the HTML to image. (Here, we are saving it as a PNG file).
- function saveAsImage() {
- html2canvas(document.getElementById("flair"),
- {
- useCORS: true,
- onrendered: function (canvas) {
- var screenshot = canvas.toDataURL("image/png");
- document.getElementById("txtScreenshot").setAttribute("src", screenshot);
- }
- });
- }

Rushi MehtaPosted Dec 4, 2019, 2:18 AM
Great Article Share.. It is very useful
Vrushali GhodkePosted Dec 2, 2019, 9:14 AM
Great...thanks for sharing.
Chu DuPosted Dec 2, 2019, 5:05 AM
Thank You so much!.
Arun Kumar SinghPosted Dec 2, 2019, 3:25 AM
We need more article like this
Sundaram SubramanianPosted Dec 2, 2019, 2:31 AM
Hi, Can you please give me an another example, so that I can relate it much.
Sourav Kumar DasPosted Dec 2, 2019, 1:23 AM
Nice article Sir based on MVC Sir.
Prakash ChasiyaPosted Dec 1, 2019, 11:15 PM
Very Nice. Thanks for sharing sir!!
Sourabh SomaniPosted Dec 27, 2018, 11:26 PM
Awesome, I love your approach reading HTML and generating flair. Well this process is quite slow because you are requesting for the web page and you get the infromation from that page which is completly and if We change something in the page it will not work.
Mahesh ChandPosted Dec 27, 2018, 10:54 PM
Nicely done! I think we should open source these kind of projects. What do you guys think of adding an open source section on the site.
Hiten PandyaPosted Dec 27, 2018, 10:31 PM
Superb Article. Thank you so much sir for sharing this.
Abhishek MishraPosted Dec 27, 2018, 9:43 PM
I simply loved and enjoyed reading this. Good one.
Ahsan SiddiquePosted Dec 27, 2018, 8:40 PM
Good Sarathlal...I like it.