Return PDF/TXT/XLS/PXLS to browser in ASP.NET MVC using crystal report

This example is using SAP crystal report for Visual studio. Can get a copy here for free.

Below sample show how to generate different file type format report to the browser dynamically.

 

In Controller:

public ActionResult PrintReport(string filters, string fileType)
 {
  var page = FilterPage(new Page<StaffOrder>(), filters);

  report = ReportUtil.GetReport<StaffOrder, StaffOrderReport>(StaffOrderModel.PropertyNames, page.result.OrderBy(x => x.StaffName).ThenBy(z => z.Id).ToList());
  ReportUtil.AssignBasicInfo(report, "Staff Order Report", WebUtil.GetUserDetails().username);

  return ReportUtil.GenerateReport(report, fileType);

 }

 

In ReportUtil class:

using System.Globalization;
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Web.Mvc;
using Microsoft.Office.Interop.Excel;

namespace STDSInternal
{
 public class ReportUtil
 {
 public static TK GetReport<T, TK>(string[] names, IList<T> items)
 where T : class
 where TK : ReportClass, new()
 {
 var report = new TK();
 report.Load();
 report.SetDataSource(GetDataTable<T>(names, items));
 return report;
 }
public static System.Data.DataTable GetDataTable<T>(string[] names, IList<T> items)
{
 var dt = new System.Data.DataTable();
 dt.Columns.AddRange(GetDataColumns(names));
 foreach (T item in items)
 {
 var objs = new List<object>();
 foreach (var name in names)
 {
 PropertyInfo pi = item.GetType().GetProperty(name);
 var obj = pi.GetValue(item);
 objs.Add(DoConversion(obj));
 }
 dt.Rows.Add(objs.ToArray());
 }
 return dt;
 }

public static DataColumn[] GetDataColumns(string[] columnNames)
 {
 return columnNames.Select(name => new DataColumn(name)).ToArray();
 }

public static FileStreamResult GenerateReport<T>(T report, string fileType) where T : ReportClass
 {
 var contentType = WebConstants.APPLICATION_PDF;
 switch (fileType)
 {
 case "txt":
   report.ExportOptions.ExportFormatType = ExportFormatType.Text;
   contentType = WebConstants.TEXT_PLAIN;
   break;
 case "xls":
   report.ExportOptions.ExportFormatType = ExportFormatType.Excel;
   contentType = WebConstants.TEXT_XLS;
   break;
 case "pxls":
   report.ExportOptions.ExportFormatType = ExportFormatType.ExcelRecord;
   contentType = WebConstants.TEXT_XLS;
   fileType = "xls";
   break;
 default:
   report.ExportOptions.ExportFormatType = ExportFormatType.PortableDocFormat;
   fileType = "pdf";
   break;
 }
 return new FileStreamResult(report.ExportToStream(report.ExportOptions.ExportFormatType), contentType)
 {
 FileDownloadName = report.SummaryInfo.ReportTitle + "." + fileType
 };

}

 

In WebConstants class file:

public static readonly string APPLICATION_PDF = "application/pdf";
public static readonly string TEXT_PLAIN = "text/plain";
public static readonly string TEXT_XLS = "text/xls";

 

 

 

 

 

Making a Simple Ajax call to controller in asp.net mvc to load data into dropdownlist

Controller:

 Public Function Get_Plant() As ActionResult
 Dim plantrole As New PlantRequestParam
 Dim rinfo = New Common.ResultInfo
 rinfo = iPlant.GetAllActiveList(plantrole)
 Return Json(rinfo)
End Function

View:

var AjaxUrl = "../Home/Get_Plant";
$.ajax({
 type: 'POST',
 url: AjaxUrl,
 contentType: 'application/json; charset=utf-8',
 success: function (data) {
 if (data.Status == true) {
 var taglist = data.Data;

$.each(taglist, function (index, value) {
 var opt = new Option(value.Name, value.Id);
 $(opt).attr('data-code', value.Code);
 $('#PlantDdl').append(opt);
 });

error: function (ex) {
 showAlert({
 Message: AjaxUrl + "
" + ex.status + " - " + $(ex.responseText).filter('title').text(),
 Status: false
 });
 });

To load into HTML li tag:

$.each(taglist, function (index, value) {
 list.append('<li data-id="' + value.Id + '" data-name="' + value.Name + '" data-predictionperformance="'
 + value.PredictionPerformanceIndicator + '"><a>' + value.Code + '</a></li>');
 });

Authorization failure for Ajax request in MVC application

I encounter an ajax request authorization failure and causes bad user experience. I had click on a button which require ajax response in my ASP.net MVC application which already timout. Below is the way to handle it properly without getting any bugs.

I have created a OnAuthorizationModule action filter to check on each action to determine which pipeline to go. If IsAjaxRequest is true, it will throw HttpException, else it will redirect to error page.

 

ajax1

JQuery global error handle will receive the exception and display error message accordingly.

ajax2

 

ajax3.JPG

Simple way of adding a row of textboxes dynamically for input

How to add a row of column dynamically when user click the link to add new row?

Below illustration were done in MVC framework whereby as it is not as easy as using the control directly in web form. These concerns are populate data into the drop down list, passing back all newly added data to the controller and retrieving all data for display when page load.

dynamicAdd

In my view page, I have added the below code.

dynamicAdd2In script section, I have added a few function calls in document.ready. when page load, those method will be trigger.

dynamicAdd3In initRelationship(), is to retrieve stored values to be display in the textboxes. The first ajax postback is to retrieve a list of objects of data to be display and second ajax postback is to retrieve a list of relationship type to be display in the dropdownlist. After that, it will loop through the list of relationship type to check which one is the selected one based on the data get from list of objects. After that, all the options will be added to a string of HTML code to be appended to the div tag.

dynamicAdd6When ‘add another account’ link is click, below code will be trigger to add a new row. I have used ajax to get the list of relationship type to added to dropdownlist options before append the string of HTML code to the div tag.

dynamicAdd4Below method is just solely to assigned values to the rows of textboxes if anything left out populated into the UI controls. Can ignore this is above have done it.dynamicAdd5How to pass all these data back to the controller to be process? For all the UI controls above, the name must be the same eg. p_Relationship, p_Relationship[1]…in array format. It will automatically populated into the list in the model.

dynamicAdd7

 

When it post back to controller, you will get all the data to be process!! dynamicAdd8

 

 

NHibernate to handle search and paging from stored procedure

Basically my task is to create a page that display data in grid, able to filter (search), and print the data I retrieve from a stored procedure using NHibernate.

cac

I will pass a filter with few parameter into the SP to retrieve the data to be display.

In xml file, I have added ‘sql-query’ query tag to query out the data. ‘query-param’ is the parameter to pass into the SP.

————————————————————————————————————

in .hbm.xml file:

<?xml version=”1.0″ encoding=”utf-8″?>
<hibernate-mapping namespace=”Domain.Entity” assembly=”Domain” xmlns=”urn:nhibernate-mapping-2.2″>
<class name=”Domain.Entity.ClientAccountReport, Domain” table=”ClientAccountReport_UI” schema=”dbo”>
<id name=”Id” column=”[Id]”>
<generator class=”native”/>
</id>
<property name=”SalesPerson”/>
<property name=”SalesPersonName”/>
<property name=”SalesPersonOpenDate”/>
<property name=”ClientAccountType”/>
<property name=”ClientCode” />
<property name=”ClientName”/>
<property name=”AppointCode”/>
<property name=”AppointName”/>
<property name=”AppointPersonCreatedDate”/>
<property name=”AppointPersonAmendedDate”/>
<property name=”AuditDate”/>
<property name=”AuditRecordID”/>
<property name=”FieldName”/>
<property name=”ActionType”/>
<property name=”OldValue”/>
<property name=”NewValue”/>
<property name=”Remarks”/>
<property name=”UserID”/>
<property name=”OpenDate”/>
<property name=”CloseDate”/>
<property name=”LastActiveDate”/>
<property name=”ClientDeleteDate”/>
</class>

<sql-query name=”ClientAccountReport_UI” callable=”true”>
<query-param name=”ClientCode” type=”String”/>
<query-param name=”ClientRefTypeCode” type=”String”/>
<query-param name=”ActionType” type=”String”/>
<query-param name=”AuditDate” type=”DateTime”/>
<return class=”ClientAccountReport”>
<return-property column=”ID” name=”Id” />
<return-property column=”SalesPerson” name=”SalesPerson” />
<return-property column=”SalesPersonName” name=”SalesPersonName” />
<return-property column=”SalesPersonOpenDate” name=”SalesPersonOpenDate” />
<return-property column=”ClientAccountType” name=”ClientAccountType” />
<return-property column=”ClientCode” name=”ClientCode” />
<return-property column=”ClientName” name=”ClientName” />
<return-property column=”AppointCode” name=”AppointCode” />
<return-property column=”AppointName” name=”AppointName” />
<return-property column=”AppointPersonCreatedDate” name=”AppointPersonCreatedDate” />
<return-property column=”AppointPersonAmendedDate” name=”AppointPersonAmendedDate” />
<return-property column=”AuditDate” name=”AuditDate” />
<return-property column=”AuditRecordID” name=”AuditRecordID” />
<return-property column=”FieldName” name=”FieldName” />
<return-property column=”ActionType” name=”ActionType” />
<return-property column=”OldValue” name=”OldValue” />
<return-property column=”NewValue” name=”NewValue” />
<return-property column=”Remarks” name=”Remarks” />
<return-property column=”UserID” name=”UserID” />
<return-property column=”OpenDate” name=”OpenDate” />
<return-property column=”CloseDate” name=”CloseDate” />
<return-property column=”LastActiveDate” name=”LastActiveDate” />
<return-property column=”ClientDeleteDate” name=”ClientDeleteDate” />
</return>
exec [ClientAccountReport_UI] @ClientCode=:ClientCode, @ClientRefTypeCode=:ClientRefTypeCode, @ActionType=:ActionType, @AuditDate=:AuditDate
</sql-query>
</hibernate-mapping>

————————————————————————————————————

In Dao.cs  class file

public void GetClientAccountReportByPage(IPage<ClientAccountReport> page, IList<IFilter> filters)
{
HibernateDaoHelp.SearchByPageForSP(page, “ClientAccountReport_UI”, filters);
}

————————————————————————————————————

In HibernateDaoHelp.cs class file

public void SearchByPageForSP(IPage<T> page, string hql, IList<FXBOSS.Utils.IFilter> Filters)
{
IQuery iQuery = this.GetSession().GetNamedQuery(hql);

if (Filters.Count > 0)
{
foreach (var obj in Filters)
{
if (obj.data.ToString().Trim().Length == 0)
{
iQuery.SetParameter(obj.field, String.Empty);
}
else
{
iQuery.SetParameter(obj.field, obj.data);
}
}
}

IList<T> ListOfObj = iQuery.List<T>();

if (page.pageSize != -1)
{
var list = ListOfObj.Skip((page.pageNo – 1) * page.pageSize).Take(page.pageSize).ToList();
page.totalCount = ListOfObj.Count();
page.result = list;
}
else
{
var list = ListOfObj.ToList();
page.totalCount = ListOfObj.Count();
page.result = list;
}
}

————————————————————————————————————

In controller.cs file

private Page<ClientAccountReport> filterPage(Page<ClientAccountReport> Page, string filters)
{
SystemSeg.GetClientAccountReportByPage(Page, FilterUtil.GetQuery<ClientAccountReport>(filters));
return Page;
}

————————————————————————————————————

Web Programming guide – Inserting data using SQL data source controller

In developing web base system, retrieving and inserting data is a basic thing. As in ASP.NET, it makes development easy. As we’re going to explore one of the control-SqlDataSource control which I have tested it out with a simple web application form name ‘NewContract.aspx’ in SCM test n error 2 project.

NewContract.aspx
NewContract.aspx

Continue reading

Web Programming guide – Creating a Master page in ASP.NET

Currently I’m developing a system using ASP.NET web form model, with 3.5 .NET application framework, Visual Studio 2008 and Microsoft SQL server 2005  .

Let’s get into the topic

What is a master page? According to my understanding, it is a page that allow you to design how to put your content into the pages in a standardize format, is like a basic structure or framework. It enable you to customize your page layout. With this, you can just focus on the content page.

Continue reading