I have a view called DailyVisitSummary
. If I select FromDate
and ToDate
, it will generate the report called rpt.VisitSummaryReport
depending upon the selected dates.
I am using Crystal Reports to generate reports. If I run my application (on my local machine), the report is working fine. But if I check my application after deploying to a local host using IIS Server, the report is not working correctly. It is showing an error. The error which is mentioned in the below image (second one)
My VisitorsViewModel
;:
public DateTime ? FromDate { get; set; }
public DateTime ? ToDate { get; set; }
My view:
<div class="form-group">
@Html.LabelFor(model => model.FromDate)
@Html.TextBoxFor(model => model.FromDate, new { @class = "form-control", type = "text" })
</div>
<div class="form-group">
@Html.LabelFor(model => model.ToDate)
@Html.TextBoxFor(model => model.ToDate, new { @class = "form-control", type = "text" })
</div>
My jQuery code:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"> </script>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<script>
$("#FromDate").datepicker({
dateFormat: "dd/mm/yy",
changeMonth: true,
changeYear: true,
});
$("#ToDate").datepicker({
dateFormat: "dd/mm/yy",
changeMonth: true,
changeYear: true,
});</script>
My controller code:
public ActionResult VisitSummaryReport()
{
return View();
}
[HttpPost]
public ActionResult GetDates(VisitorsViewModel VisitorsVM)
{
var fromdt = Convert.ToDateTime(VisitorsVM.FromDate);
var todt = Convert.ToDateTime(VisitorsVM.ToDate);
SqlConnection con = new SqlConnection(@"Data Source=192.168.0.73\SQLEXPRESS,14330;Initial Catalog=WafeERP_NEW;User ID=sa;Password=wafewin;");
DataTable dt = new DataTable();
try
{
con.Open();
SqlCommand cmd = new SqlCommand("Select * from View_VisitorsForm where VisitingDate >='" + fromdt +"'and VisitingDate <= '" + todt +"'", con);
SqlDataAdapter adp = new SqlDataAdapter(cmd);
adp.Fill(dt);
}
catch (Exception ex)
{
throw;
}
ReportDocument rpt = new ReportDocument();
rpt.Load(Server.MapPath("~/Areas/Sales/CrystalReports/rpt_VisitSummaryCrystalReport.rpt"));
rpt.SetDataSource(dt);
Stream stream = rpt.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
return File(stream, "application/pdf");
}
I tried my level best to explain my issue. Any one understand my issue and help me to resolve this issue.
Thanks in advance.
You have a number of issues.
First, assuming you want the user to select both dates in the view, your properties should be DateTime
(not nullable) and include a@Html.ValidationMessageFor()
for each property Then in the POST method, start with
if(!ModelState.IsValid())
{
return View(VisitorsVM);
}
But more importantly, your opening yourself to SQL injection attacks where a malicious user can gain access to your database, or simply delete it, and I recommend you read these answers and other articles on SQL Injection attacks. You need to modify you code to use parameterized queries
SqlConnection con = new SqlConnection(.....);
DataTable dt = new DataTable();
try
{
SqlCommand command = new SqlCommand();
command.CommandText = "Select * from View_VisitorsForm where VisitingDate >= @fromDate and VisitingDate <= @toDate";
command.Parameters.Add("@fromDate", System.Data.SqlDbType.Date).Value = VisitorsVM.FromDate;
command.Parameters.Add("@toDate", System.Data.SqlDbType.Date).Value = VisitorsVM.ToDate;
command.Connection = con;
// con.Open();
SqlDataAdapter adp = new SqlDataAdapter(command);
adp.Fill(dt);
}
Note there is no need to open the connection - the .Fill()
method will open and close it, but if you do use it, then you need to call con.Close();
after .Fill()
I would also recommend that this code be in a separate service rather than in a controller method
Side note: There is no need for new { type = "text" })
in you view. The TextBoxFor()
method already adds the type="text"
attribute so your just overwriting the existing value.