Sunday, December 3, 2017

HTTP Error 500.23 - Internal Server Error. An ASP.NET setting has been detected that does not apply in Integrated managed pipeline mode. (ASP.NET MVC HttpHandler)

Good day!
I was trying to apply integrate an Image HttpHandler that discourages leeching from one of my Web Forms project to ASP.NET MVC. This hack is found on ASP.NET 2.0 MVP Hacks site. Upon running the ASP.NET MVC project, an issue was thrown to the browser specifically "HTTP Error 500.23 - Internal Server Error. An ASP.NET setting has been detected that does not apply in Integrated managed pipeline mode." Upon investigating, I found out that handlers in WebForms are declared in <httpHandlers> under <system.web>.
<system.web>
 <httpHandlers>
  <add verb="*" path="*.jpg" type="Events.Web.Extensions.NoLeechImageHandler"/>
  <add verb="*" path="*.jpeg" type="Events.Web.Extensions.NoLeechImageHandler"/>
  <add verb="*" path="*.gif" type="Events.Web.Extensions.NoLeechImageHandler"/>
  <add verb="*" path="*.png" type="Events.Web.Extensions.NoLeechImageHandler"/>
 </httpHandlers>
</system.web> 
And handlers in MVC are set inside the <handlers> node belonging to <system.webServer>.
<system.webServer>
 <handlers>
   <add name="jpgHandler" verb="*" path="*.jpg" type="Events.Web.Extensions.NoLeechImageHandler"/>
   <add name="jpegHandler" verb="*" path="*.jpeg" type="Events.Web.Extensions.NoLeechImageHandler"/>
   <add name="gifHandler" verb="*" path="*.gif" type="Events.Web.Extensions.NoLeechImageHandler"/>
   <add name="pngHandler" verb="*" path="*.png" type="Events.Web.Extensions.NoLeechImageHandler"/>
 </handlers>
</system.webServer>
That fixed the issue for ASP.NET MVC.

Friday, December 1, 2017

Hide GridView BoundField column with value accessible through JavaScript

To hide a BoundField column but make it's value still accessible through JavaScript just set column's ItemStyle-CssClass and HeaderStyle-CssClass properties using CSS class with value display:none.
CSS
.hiddenColumn{
 display:none;
}
ASPX
<asp:BoundField DataField="GroupCode" HeaderText="Group Code" ItemStyle-CssClass="hiddenColumn" HeaderStyle-CssClass="hiddenColumn"/>

Monday, November 20, 2017

Display Images Using Generic Handler in ASP.NET MVC

There are several options on how to show images in ASP.NET MVC. One of them is using a generic handler. This method was applied since the early days of ASP.NET Webforms and still can be used with recent frameworks. The class below will render the images on the page by calling the ProcessRequest method which will then get the image from datasources such as database and file system and return it as a Bitmap object.
public class ImageHandler : IHttpHandler
{
 private OnlineShoppingDBEntities shoppingContext;

 public ImageHandler()
 {
  shoppingContext = new OnlineShoppingDBEntities();
 }

 public void ProcessRequest(HttpContext context)
 {
  if (context.Request.QueryString["ProductID"] != null)
  {
   Product product = shoppingContext.Products.Find(Convert.ToInt32(context.Request.QueryString["ProductID"]));
   if (product != null)
   {
    Byte[] bytes = product.Image;
    int height = 0;
    int width = 0;

    height = 100;
    width = 100;

    Bitmap image = GetImage(bytes, height, width);

    context.Response.Buffer = true;
    context.Response.Charset = "";
    context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    context.Response.ContentType = "image/jpeg";
    image.Save(context.Response.OutputStream, ImageFormat.Jpeg);
    context.Response.Flush();
    context.Response.End();
   }
  }
 }

 private Bitmap GetImage(Byte[] bytes, int width, int height)
 {
  Image originalImage;
  using (MemoryStream ms = new MemoryStream(bytes))
  {
   originalImage = Image.FromStream(ms);
  }

  var newImage = new Bitmap(originalImage, width, height);
  Graphics g = Graphics.FromImage(originalImage);
  g.FillRectangle(Brushes.White, 0, 0, newImage.Width, newImage.Height);
  Rectangle Box = new Rectangle(10, 10, newImage.Size.Width - 20, newImage.Size.Height - 20);
  g.DrawRectangle(Pens.Black, Box);
  return newImage;
 }

 public bool IsReusable
 {
  get
  {
   return false;
  }
 }
}
When using this code to show images of type GIF, you might encounter an issue such as "A Graphics object cannot be created from an image that has an indexed pixel format". The fix for that is to revise the GetImage() method wherein you create a blank bitmap with the same dimensions and the correct PixelFormat and then draw on that bitmap the original image bitmap.
public class ImageHandler : IHttpHandler
{

 ProductRepository repository;

 public ImageHandler()
 {
  repository = new ProductRepository();
 }

 public void ProcessRequest(HttpContext context)
 {
  if (context.Request.QueryString["ProductID"] != null)
  {
   ProductViewModel product = repository.Product(Convert.ToInt32(context.Request.QueryString["ProductID"]));
   if (product != null)
   {
    Byte[] bytes = product.Image;
    Bitmap image = GetImage(bytes);

    context.Response.Buffer = true;
    context.Response.Charset = "";
    context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    context.Response.ContentType = "image/jpeg";
    image.Save(context.Response.OutputStream, ImageFormat.Jpeg);
    context.Response.Flush();
    context.Response.End();
   }
  }
 }

 private Bitmap GetImage(Byte[] bytes)
 {
  Image originalImage;
  Bitmap originalBmp;
  using (MemoryStream ms = new MemoryStream(bytes))
  {
   originalImage = Image.FromStream(ms);
  }

  originalBmp = new Bitmap(originalImage);
  Bitmap tempBitmap = new Bitmap(originalBmp.Width, originalBmp.Height);
  using (Graphics g = Graphics.FromImage(tempBitmap))
  {
   // Draw the original bitmap onto the graphics of the new bitmap
   g.DrawImage(originalBmp, 0, 0);
   Rectangle Box = new Rectangle(0, 0, tempBitmap.Size.Width, tempBitmap.Size.Height);
   g.DrawRectangle(Pens.White, Box);
  }

  return tempBitmap;
 }

 public bool IsReusable
 {
  get
  {
   return false;
  }
 }
}
To use this class, all you need to do is add an img tag in your view and replace the src attribute with the relative path of the handler and append the model id as query string.
<img src="~/Helpers/ImageHandler.ashx?ProductID=@item.ProductID" />
Rendered View:

Sunday, November 19, 2017

Add glyphicon to Ajax.ActionLink() in ASP.NET MVC

Good evening!
Adding a Bootstrap glyphicon to Ajax.ActionLink() helper is similar with Html.ActionLink() except that when the linkText parameter of the helper is empty, it will cause an Ajax issue and an Internal Server Error will be thrown from the browser. If you're going to integrate glyphicons on Ajax.ActionLink() helper and exclude the linkText property, supply that parameter with space instead of empty string so as not to cause jQuery or Ajax issues.
@Ajax.ActionLink(" ", "DeleteComment", "Home",
    new { id = comment.CommentID },
    new AjaxOptions
    {
     OnBegin = "return confirm('Are you sure you want to delete this comment?');",
     InsertionMode = InsertionMode.Replace,
     UpdateTargetId = "event-details-" + Model.Id,
     HttpMethod = "GET",                                  
    }, new 
    {  
     @class = "commentDelete glyphicon glyphicon-trash"
    });
linkText is the first parameter of Ajax.ActionLink() helper.
Output:

Thursday, November 9, 2017

Invalid nested tag div found, expected closing tag input

Hello all,
I've been experimenting on how to print html document using the said 3rd party software called iTextSharp. iTextSharp is a popular tool and has several examples on the internet regarding integration to the project and occurring issues. One of the issue I encountered is Invalid nested div tag and is expecting a closing tag input. As I trace back my html source, the tags are well-formed except that they are self closing tags such as <input>, <hr>, <img>, <br> or the like. These tags when passed to an action method as string are not properly closed and thus an issue is thrown by iTextSharp's XMLWorkerHelper's ParseXHtml() method.
<img src="~/Images/success.png" /> 
<input type="hidden" name="OrderStatusHTML" />
<input type="submit" id="btnSubmit" value="Export to PDF" class="btn btn-success" />
The solution I came up with is to fix the page source using HTMLAgilityPack which is to explicitly close the tags by assigning HtmlElementFlag.Closed enum to HtmlNode.ElementsFlag["img"] dictionary.
[HttpPost]
[ValidateInput(false)]
public FileResult ExportToPDF(string OrderStatusHTML)
{
 HtmlNode.ElementsFlags["img"] = HtmlElementFlag.Closed;
 HtmlNode.ElementsFlags["input"] = HtmlElementFlag.Closed;
 HtmlDocument doc = new HtmlDocument();
 doc.OptionFixNestedTags = true;
 doc.LoadHtml(OrderStatusHTML);
 OrderStatusHTML = doc.DocumentNode.OuterHtml;

 using (MemoryStream stream = new System.IO.MemoryStream())
 {
  Encoding unicode = Encoding.UTF8;
  StringReader sr = new StringReader(OrderStatusHTML);
  Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 100f, 0f);
  PdfWriter writer = PdfWriter.GetInstance(pdfDoc, stream);
  pdfDoc.Open();
  XMLWorkerHelper.GetInstance().ParseXHtml(writer, pdfDoc, sr);
  pdfDoc.Close();
  return File(stream.ToArray(), "application/pdf", "OrderStatus.pdf");
 }
}

That's it.. :-D

Tuesday, November 7, 2017

Add glyphicon to Html.ActionLink() in ASP.NET MVC

Hello,
Here's how to integrate glyphicon to Html.ActionLink() helper in ASP.NET MVC. The code below will display the glyphicon shopping cart right after the text Checkout of the anchor element.
@Html.ActionLink("Checkout", "Index", "Home", null, new { @class = "btn btn-info glyphicon glyphicon-shopping-cart" })
In order to add the glyphicon before the text of the anchor element, use @Url.Action() instead.
<a href="@Url.Action("Index", "Checkout")" class="btn btn-info">
 <span class="glyphicon glyphicon-shopping-cart" ></span>Checkout
</a>
Output:

Thursday, November 2, 2017

Formatting numbers using toLocaleString() in JavaScript

I've been using a JavaScript 3rd party library to format numbers with comma and decimal place(s). The JavaScript library called NumberFormatter was introduced to me by my developer with exceptional skills in front-end programming. Due to simplicity sake, I'm exploring options if this can be achieved using an existing JavaScript function instead of using the existing 3rd party app.

After doing some research, I found an answer here: How to use toLocaleString() and tofixed(2) in javascript which is to use toLocaleString() by setting the options minimumFractionDigits and maximumFractionDigits to 2.
Number.prototype.toLocaleFixed = function (n) {
    return this.toLocaleString(undefined, {
        minimumFractionDigits: n,
        maximumFractionDigits: n
    });
};
Sample usage:
var result = parseFloat(amount).toLocaleFixed(2)

Saturday, October 21, 2017

Task Management System with Entity Framework and ASP.NET MVC

Hello,
Here's a simple Task Management System with Entity Framework 6 taken from Udemy's Asp.Net MVC With Entity Framework From Scratch video tutorial. The output of the project should be in ASP.NET Webform but I chose to upload a sample in ASP.NET MVC which is intended for ASP.NET MVC developers. The entire source code can be downloaded here:Task Management System MVC. The project includes the stored procedure necessary to display the data through the grid. As for the database table, it is included in the tutorial series through a PDF file.
Cheers!

Monday, October 16, 2017

Ajax.ActionLink() not redirecting to ActionResult with Ajax Attribute

Given that I have this code in my .cshtml page using Ajax.ActionLink() that calls a controller method using Ajax request:
@Ajax.ActionLink("Select", "TaskListing", new { id = item.TaskID }, 
   new AjaxOptions(){ 
    HttpMethod = "GET",
    UpdateTargetId = "taskListing",
    InsertionMode = InsertionMode.Replace
})
And the controller method called by the Ajax ActionLink is decorated with Ajax attribute.
[HttpGet]
[AjaxOnly(true)]
[ActionName("TaskListing")]
public ActionResult TaskListing_Ajax(int id = -1)
{
 var projects = projRep.GetAllProjects();
 var model = new TaskAndTaskViewModel();
 model.Task = te.Tasks.FirstOrDefault(t => t.TaskID == id);
 model.SelectList = from p in projRep.GetAllProjects()
        select new SelectListItem
        {
         Selected = (p.ProjectID == Convert.ToInt32(model.Task.ProjectID)),
         Text = p.ProjectName.ToString(),
         Value = p.ProjectID.ToString()
        };

 return PartialView("TaskForm", model);
}
Normally, the request would push through. If does not proceed, maybe you have not added the Microsoft JQuery Unobtrusive Ajax to your project. Downloading and installing the said package(Microsoft JQuery Unobtrusive Ajax) via NuGet might fix the problem.

Sunday, October 8, 2017

Read .NET configuration files using NameValueSectionHandler and AppSettingsSection Types

Hello all,
I've read from a tutorial NameValueCollection and .NET Configuration Files which targets .NET 1.0/1.1 on how to read config files using type NameValueSectionHandler. I intend to explore more on applying this concept to recent versions of .NET frameworks. Upon doing some diggings, I came up with two options. First is using NameValueSectionHandler type and the other one is AppSettingsSections. To begin with, I have this App.config file with XML elements scriptsfiles and docfiles all registered in configSections.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="scriptfiles" type="System.Configuration.NameValueSectionHandler"/>
    <section name="docfiles" type="System.Configuration.AppSettingsSection"/>
  </configSections>
  <scriptfiles>
    <add key="C:\batchfiles\2017" value="*.bat" />
    <add key="C:\vbs\2017" value="*.vbs" />
  </scriptfiles>
  <docfiles>
    <add key="C:\applicants\2017" value="*.doc" />
    <add key="C:\officemanuals\2017" value="*.pdf" />
  </docfiles>
  <startup> 
      <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
  </startup> 
</configuration>
If you noticed, each sections are declared with different types specifically NameValueSectionHandler and AppSettingsSection with similar node structures. To read the element with type NameValueSectionHandler we use the ConfigurationManager.GetSection() method.
C# Code
private static void ReadNameValueSectionHandler()
{
 Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);            
 NameValueCollection scriptFiles = (NameValueCollection)ConfigurationManager.GetSection(config.GetSection("scriptfiles").SectionInformation.SectionName);
 foreach (var item in scriptFiles.AllKeys)
 {
  Console.WriteLine(String.Format("Key:{0}, value:{1}", item, scriptFiles[item]));
 }
}
For the element with AppSettingsSection type we simply cast the ConfigurationSection object to AppSettingsSection.
C# Code
private static void ReadAppSettingsSection()
{
 Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
 ConfigurationSection section = config.GetSection("docfiles");
 var scriptSettings = ((AppSettingsSection)section).Settings;    

 foreach (var item in scriptSettings.AllKeys)
 {
  Console.WriteLine(String.Format("Key:{0}, value:{1}", item, scriptSettings[item].Value));
 }
}