Fullcalendar is not showing the events fetched by ajax. The events is successfully passed because I can display it by pop up but it is not showing in the calendar. The fullcalendar will show events if i manually set the events but once i use the data pass from .cs file it cannot render.
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Web.Services;
using System.Linq;
using System.Web.UI.WebControls;
using System.Web.Script.Serialization;
using System.Collections;
using System.Data;
namespace TravelPlannerO
{
public partial class Schedule : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
public class Event
{
public string id { get; set; }
public string title { get; set; }
public string start { get; set; }
public string end { get; set; }
public string desc { get; set; }
public string status { get; set; }
public Event(string id, string title, string start, string end,string desc,string status)
{
this.id = id;
this.title = title;
this.start = start;
this.end = end;
this.desc = desc;
this.status = status;
}
};
[WebMethod]
public static string GetEvent()
{
string strSelect;
SqlCommand cmdSelect;
SqlDataReader dtr;
SqlConnection conn;
string connStr = ConfigurationManager.ConnectionStrings["plannerdb"].ConnectionString;
conn = new SqlConnection(connStr);
strSelect = "Select * from [Source.SavedPlan]";
cmdSelect = new SqlCommand(strSelect, conn);
conn.Open();
dtr = cmdSelect.ExecuteReader();
<script src="Scripts/moment.min.js"></script>
<script src="Scripts/jquery-ui.custom.min.js"></script>
<script src="Scripts/fullcalendar.min.js"></script>
<script type="text/javascript">
var listofevent;
$(document).ready(function () {
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
events:function (id,title,start, end, callback) {
$.ajax({
type: "POST ",
url: '<%=Microsoft.AspNet.FriendlyUrls.FriendlyUrl.Resolve(" /Schedule.aspx / GetEvent ")%>',
data: {},
contentType: "application / json;charset = utf - 8 ",
dataType: "json ",
success: function (list) {
listofevent = list.d;
alert(listofevent);
var events = [];
alert(list.d);
var obj = $.parseJSON(list.d);
console.log(obj);
$(list).find('event').each(function () {
events.push({
title: $(this).attr('title'),
start: $(this).attr('start'),
end: $(this).attr('end')
});
console.log(obj.calEvent);
});
//callback(events);
callback && callback(events);
},
error: function (xhr, status, error) {
alert(xhr.responseText);
}
});
},
defaultDate: '2015-1-1',
selectable: true,
editable: true,
selectHelper: true,
eventLimit: true, // allow "
more " link when too many events
</script>
<link href="Content/fullcalendar.css" rel="stylesheet" /> <link href="Content/fullcalendar.print.css" rel="stylesheet" media="print" /> <link href="Content/jquery-ui.min.css" rel="stylesheet"/>
<div id='calendar'></div>
List<object> array = new List<object>();
if (dtr.HasRows)
{
var index_id = dtr.GetOrdinal("PlanId");
var index_title = dtr.GetOrdinal("Name");
var index_start = dtr.GetOrdinal("DateFrom");
var index_end = dtr.GetOrdinal("DateTo");
var index_desc = dtr.GetOrdinal("Description");
var index_status = dtr.GetOrdinal("Status");
while (dtr.Read())
{
var id = dtr.GetValue(index_id).ToString();
var title = dtr.GetValue(index_title).ToString();
var datestart = dtr.GetValue(index_start).ToString();
var dateend = dtr.GetValue(index_end).ToString();
var desc = dtr.GetValue(index_desc).ToString();
var status = dtr.GetValue(index_status).ToString();
DateTime RealStartDate = Convert.ToDateTime(datestart);
DateTime RealEndDate = Convert.ToDateTime(dateend);
string start = RealStartDate.ToString("s");
string end = RealEndDate.ToString("s");
Event eventrows = new Event(id, title, start, end,desc,status);
array.Add(eventrows);
}
}
string myJsonString = (new JavaScriptSerializer()).Serialize(array);
return myJsonString;
}
private static DateTime ConvertFromUnixTimestamp(double timestamp)
{
var origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
return origin.AddSeconds(timestamp);
}
}
}
In my visual studio there are no spaces between the I think I might accidentally space it while I paste it here. I dont understand why the events is not showing. While i print 'list.d' from success: function(list), the result is
[{"id:"1","title":"testoh","start":"2015-01-01T00:00:00","end":"2015-01-02T00:00:00","desc":"abaaba","status":"first "},
[{"id:"2","title":"okok","start":"2015-05-01T00:00:00","end":"2015-05-02T00:00:00","desc":"fdgd","status":"second "}]
Is the format correct?. I noticed my callback function is not called but i dunno why
I solved this by editing the argument in the events:function (id,title,start, end, callback) to events:function (start, end,timezone, callback). btw thanks for the reply..
Related
I am trying to populate a DataTable from google chart to generate a chart. So far, I was able to get the information to travel from the database (MySQL) to the controller, and from there to the view using an ArrayList but when reading the dates, something happens and controls are subtracted:
In summary: I am sending an Array with data in the 2019-05-21 format and JavaScript interprets it as a mathematical operation, leaving 1,993.
I understand that it may be seen as a basic error, but it is my first time working with JavaScript and I have already spent several hours reading documentation and have not found any solution.
Controller:
#Controller
#RequestMapping
public class indexController {
#Autowired
private IAccionService service;
#GetMapping("chart_index")
public String profileSettings(Model model) {
String msg="holasoyundatodeprueba";
String msg2="Fecha1";
model.addAttribute("msg", msg);
model.addAttribute("msg2", msg2);
List<Acciones>accioneslst=service.listar_acciones();
Acciones[] arrayAcciones = new Acciones[accioneslst.size()];
arrayAcciones=accioneslst.toArray(arrayAcciones);
ArrayList<String> arrayFechas = new ArrayList<String>();
ArrayList<Integer> arrayOpen = new ArrayList<Integer>();
ArrayList<Integer> arrayClose = new ArrayList<Integer>();
for (Acciones acciones : arrayAcciones) {
arrayFechas.add(acciones.getFecha().toString());
arrayOpen.add(acciones.getOpen_value());
arrayClose.add(acciones.getClose_value());
System.out.println(arrayFechas.toString());
}
model.addAttribute("fechaGrafico",arrayFechas);
model.addAttribute("openGrafico",arrayOpen);
model.addAttribute("closeGrafico",arrayClose);
return "chart_index";
}
JavaScript code (Google Chart: Line Chart) added to the view:
<!DOCTYPE html>
<html>
<head xmlns:th="http://www.thymeleaf.org">
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Gráfico de acciones</title>
<link rel="stylesheet" type="text/css" href="CSS/styles_chart.css" />
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var Fecha=[[${fechaGrafico}]];
var Open=[[${openGrafico}]];
var Close=[[${closeGrafico}]];
var data = new google.visualization.DataTable(); //Cambiado a DataTable
data.addColumn('string','Fecha');
data.addColumn('number','Open');
data.addColumn('number','Close');
for(i=0;i<Fecha.length;i++)
data.addRow(["'"+Fecha[i]+"'",Open[i],Close[i]]);
console.log(Fecha);
var options = {
title : "[[${msg}]]",
curveType : 'function',
backgroundColor : '#EDEEF0',
width : '1323',
height : '855',
legend : 'none',
chartArea : {
width : '1200',
height : '800'
},
colors : [ '#A6CEE3', '#1F78B4' ]
};
var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));
chart.draw(data, options);
}
</script>
Class:
Package com.amsterdam.springboot.v1.app.models;
import java.sql.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table (name="accion") //Nombre de la tabla
public class Acciones {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Date fecha;
private int open_value;
private int high_value;
private int low_value;
private int close_value;
private int adj_close;
private int volume;
private String enterprise;
public Acciones() {
// TODO Auto-generated constructor stub
}
public Acciones(Date fecha, int open_value, int high_value, int low_value, int close_value, int adj_close,
int volume, String enterprise) {
super();
this.fecha = fecha;
this.open_value = open_value;
this.high_value = high_value;
this.low_value = low_value;
this.close_value = close_value;
this.adj_close = adj_close;
this.volume = volume;
this.enterprise = enterprise;
}
public Date getFecha() {
return fecha;
}
public void setFecha(Date fecha) {
this.fecha = fecha;
}
public int getOpen_value() {
return open_value;
}
public void setOpen_value(int open_value) {
this.open_value = open_value;
}
public int getHigh_value() {
return high_value;
}
public void setHigh_value(int high_value) {
this.high_value = high_value;
}
public int getLow_value() {
return low_value;
}
public void setLow_value(int low_value) {
this.low_value = low_value;
}
public int getClose_value() {
return close_value;
}
public void setClose_value(int close_value) {
this.close_value = close_value;
}
public int getAdj_close() {
return adj_close;
}
public void setAdj_close(int adj_close) {
this.adj_close = adj_close;
}
public int getVolume() {
return volume;
}
public void setVolume(int volume) {
this.volume = volume;
}
public String getEnterprise() {
return enterprise;
}
public void setEnterprise(String enterprise) {
this.enterprise = enterprise;
}
}
for my website, I am using ASP.net Core MVC on Visual Studios 2019 and SQL Server Management Studio for my database.
I am trying to display markers using data(Latitude and Longitude) from my Database onto a Leaflet map. I came across a website providing a solution for this. However, it was using ASP.net instead of Asp.net Core.
Which parts of the code do I have to change for it to work on my side?
Controller:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using WebApplication1.Models;
namespace WebApplication1.Controllers
{
public class MapsController : Controller
{
private test2Entities db = new test2Entities();
// GET: Maps
public ActionResult Index()
{
return View(db.Maps.ToList());
}
#region [Map]
[HttpPost]
public JsonResult GetMap()
{
var data1 = Map();
return Json(data1, JsonRequestBehavior.AllowGet);
}
public IEnumerable<Map> Map()
{
return (from p in db.Maps
select new
{
Name = p.Name,
Latitude = p.Latitude,
Longitude = p.Longitude,
Location = p.Location,
Description = p.Description,
Id = p.Id
}).ToList()
.Select(res => new Map
{
Name = res.Name,
Latitude = res.Latitude,
Longitude = res.Longitude,
Location = res.Location,
Description = res.Description,
Id = res.Id
});
}
#endregion
}
}
View:
#model IEnumerable<WebApplication1.Models.Map>
#{
Layout = null;
}
<link rel="stylesheet" type="text/css" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />
<script type='text/javascript' src='http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js?2'></script>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<div id="map" style="height: 440px; border: 1px solid #AAA;"></div>
<script type="text/javascript">
$(document).ready(function () {
var map = L.map('map', {
center: [10.1102278, 77.8958904],
minZoom: 4,
zoom: 6
});
$.ajax({
type: "POST",
url: '/Maps/GetMap',
success: function (data) {
var result = JSON.stringify(data);
for (var i = 0; i < result.length; ++i) {
var popup ='<b>Name:</b> '+ data[i].Name +
'<br/><b>Latitude:</b> ' + data[i].Latitude +
'<br/><b>Longitude:</b> ' + data[i].Longitude+
'<br/><b>Location:</b> ' + data[i].Location;
L.marker([data[i].Latitude, data[i].Longitude])
.bindPopup(popup)
.addTo(map);
}
},
error: function (xhr) {
console.log(xhr.responseText);
alert("Error has occurred..");
}
});
L.tileLayer('http://{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors | Tiles Courtesy of MapQuest <img src="http://developer.mapquest.com/content/osm/mq_logo.png" width="16" height="16">',
subdomains: ['otile1', 'otile2', 'otile3', 'otile4']
}).addTo(map);
});
</script>
As far as I know, if you want to migrate from asp.net mvc to asp.net core mvc, it's easily.
You should firstly make sure you have know how to use EF core in asp.net core.
You should firstly create a model in asp.net core and create the dbcontext:
public class TestDbcontext: DbContext
{
public DbSet<Map> Documents { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
optionsBuilder.UseSqlServer(#"Your connection string");
}
}
Map class:
public class Map
{
public string Name { get; set; }
public string Latitude { get; set; }
public string Longitude { get; set; }
public string Location { get; set; }
public string Description { get; set; }
public string Id { get; set; }
}
Then you could use VS management console and type in:
add-migration initialcreate
update-database
Then add below codes in startup.cs :
services.AddDbContext<TestDbcontext>();
In MVC controller:
public class HomeController : Controller
{
private readonly ILogger _logger;
private TestDbcontext _dbContext;
public HomeController(ILogger<HomeController> logger, TestDbcontext dbContext)
{
_logger = logger;
_dbContext = dbContext;
}
public IActionResult ShowMap()
{
return View(_dbContext.Maps.ToList());
}
[HttpPost]
public IActionResult GetMap()
{
var data1 = Map();
return Json(data1);
}
public IEnumerable<Map> Map()
{
//return (from p in _dbContext.Maps
// select new
// {
// Name = p.Name,
// Latitude = p.Latitude,
// Longitude = p.Longitude,
// Location = p.Location,
// Description = p.Description,
// Id = p.Id
// }).ToList()
// .Select(res => new Map
// {
// Name = res.Name,
// Latitude = res.Latitude,
// Longitude = res.Longitude,
// Location = res.Location,
// Description = res.Description,
// Id = res.Id
// });
};
}
}
View html:
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>ShowMap</title>
</head>
<body>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.6.0/dist/leaflet.css"
integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
crossorigin="" />
<script src="https://unpkg.com/leaflet#1.6.0/dist/leaflet.js"
integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew=="
crossorigin=""></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.js"></script>
<div id="map" style="height: 440px; border: 1px solid #AAA;"></div>
<script type="text/javascript">
$(document).ready(function () {
var map = L.map('map', {
center: [10.1102278, 77.8958904],
minZoom: 4,
zoom: 6
});
$.ajax({
type: "POST",
url: '/Default/GetMap',
success: function (data) {
var result = JSON.stringify(data);
for (var i = 0; i < result.length; ++i) {
var popup = '<b>Name:</b> ' + data[i].Name +
'<br/><b>Latitude:</b> ' + data[i].Latitude +
'<br/><b>Longitude:</b> ' + data[i].Longitude +
'<br/><b>Location:</b> ' + data[i].Location;
L.marker([data[i].Latitude, data[i].Longitude])
.bindPopup(popup)
.addTo(map);
}
},
error: function (xhr) {
console.log(xhr.responseText);
alert("Error has occurred..");
}
});
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors | Tiles Courtesy of MapQuest <img src="http://developer.mapquest.com/content/osm/mq_logo.png" width="16" height="16">',
}).addTo(map);
});
</script>
</body>
</html>
I have to know file downloaded status in clientside and I am using ASP.NET MVC to do the task. I cannot use cookies to know the status as the page is opening in iframe in some other application which doesn't allow me to keep cookies.
I would like to access the QueryString from RedirectToAction Url which is "DownloadUrl". My screenshot to get the value and respected view and controler code is as below. How can I achieve the "downloadStatus" querystring in my case? Please help.
Index.cshtml
#{
ViewBag.Title = "Home Page";
}
<script type="text/javascript">
$(document).ready(function () {
$("#download").on("click", function () {
$('#statusDiv').show();
setTimeout(checkDownloadStatus, 1000); //Initiate the loop to check the downloadStarted value.
});
var checkDownloadStatus = function () {
// Get querystring value for downloadStarted
if (getUrlParameter("downloadStatus") == 1) {
$('#statusDiv').hide();
} else {
downloadTimeout = setTimeout(checkDownloadStatus, 1000); //Re-run this function in 1 second.
}
};
// get querystring value
var getUrlParameter = function getUrlParameter(sParam) {
var sPageURL = window.location.search.substring(1),
sURLVariables = sPageURL.split('&'),
sParameterName,
i;
for (i = 0; i < sURLVariables.length; i++) {
sParameterName = sURLVariables[i].split('=');
if (sParameterName[0] === sParam) {
return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]);
}
}
};
});
</script>
#using (Html.BeginForm(null, null, FormMethod.Post, new { #id = "formDownload" }))
{
<div class="row">
<div id="statusDiv" style="display:none;">File is downloading ...</div>
<button type="submit" formaction="~/Home/FileDownload" id="download" value="download" formmethod="post">
Download
</button>
</div>
}
HomeController.cs
using System.Threading.Tasks;
using System.Web.Mvc;
namespace RedirectToActionDemo.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public async Task<ActionResult> FileDownload()
{
var fileStream = System.IO.File.ReadAllBytes(#"D:\Documents\Information.docx");
DownloadFileResult res = new DownloadFileResult();
res.FileResult = fileStream;
res.MimeType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
res.FileName = "Information.docx";
TempData["Result"] = res;
return RedirectToAction("downloadUrl", new { downloadStatus = "1" });
}
public ActionResult DownloadUrl(string downloadStatus)
{
DownloadFileResult res = TempData["Result"] as DownloadFileResult;
return File(res.FileResult, res.MimeType, res.FileName.Replace("\"", ""));
}
}
public class DownloadFileResult
{
public byte[] FileResult { get; set; }
public string FileName { get; set; }
public string MimeType { get; set; }
}
}
This should give you the last part of your url:
#{
var id = Request.Url.Segments.Last();
}
Some info about the above
I'm using Facebook Graph JSON responses in my code to deserialize the JSON string.
I created the class as follow.
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<div id="fb-root"></div>
Login with Facebook
<br /> <br />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
</ContentTemplate>
</asp:UpdatePanel>
<script type="text/javascript">
window.fbAsyncInit = function () {
FB.init({ appId: '<%= ecommerce.fblogin.FaceBookAppKey %>',
status: true, // check login status
cookie: true, // enable cookies to allow the server to access the session
xfbml: true, // parse XFBML
oauth: true // enable OAuth 2.0
});
};
(function () {
var e = document.createElement('script'); e.async = true;
e.src = document.location.protocol +
'//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
} ());
function loginByFacebook() {
FB.login(function (response) {
if (response.authResponse) {
FacebookLoggedIn(response);
} else {
console.log('User cancelled login or did not fully authorize.');
}
}, { scope: 'email' });
}
function FacebookLoggedIn(response) {
var loc = '/fblogin.aspx';
if (loc.indexOf('?') > -1)
window.location = loc + '&authprv=facebook&access_token=' + response.authResponse.accessToken;
else
window.location = loc + '?authprv=facebook&access_token=' + response.authResponse.accessToken;
}
</script>
</form>
namespace ecommerce
{
public partial class fblogin : System.Web.UI.Page
{
public const string FaceBookAppKey = "xxxxxxxxxx";
protected void Page_Load(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(Request.QueryString["access_token"])) return; //ERROR! No token returned from Facebook!!
//let's send an http-request to facebook using the token
string json = GetFacebookUserJSON(Request.QueryString["access_token"]);
//and Deserialize the JSON response
JavaScriptSerializer js = new JavaScriptSerializer();
FacebookUser oUser = js.Deserialize<FacebookUser>(json);
if (oUser != null)
{
Response.Write("Welcome, " + oUser.name);
Response.Write("<br />id, " + oUser.id);
Response.Write("<br />email, " + oUser.email);
Response.Write("<br />first_name, " + oUser.first_name);
Response.Write("<br />last_name, " + oUser.last_name);
Response.Write("<br />gender, " + oUser.gender);
Response.Write("<br />link, " + oUser.link);
Response.Write("<br />updated_time, " + oUser.updated_time);
Response.Write("<br />birthday, " + oUser.birthday);
Response.Write("<br />locale, " + oUser.locale);
Response.Write("<br />picture, " + oUser.picture);
if (oUser.location != null)
{
Response.Write("<br />locationid, " + oUser.location.id);
Response.Write("<br />location_name, " + oUser.location.name);
}
}
}
private static string GetFacebookUserJSON(string access_token)
{
string url = string.Format("https://graph.facebook.com/me?access_token={0}&fields=email,name,first_name,last_name,link", access_token);
WebClient wc = new WebClient();
Stream data = wc.OpenRead(url);
StreamReader reader = new StreamReader(data);
string s = reader.ReadToEnd();
data.Close();
reader.Close();
return s;
}
public class FacebookUser
{
public long id { get; set; }
public string email { get; set; }
public string name
{ get; set; }
public string first_name
{ get; set; }
public string last_name
{ get; set; }
public string gender
{ get; set; }
public string link
{ get; set; }
public DateTime updated_time
{ get; set; }
public DateTime birthday
{ get; set; }
public string locale
{ get; set; }
public string picture
{ get; set; }
public FacebookLocation location
{ get; set; }
}
public class FacebookLocation
{
public string id
{ get; set; }
public string name
{ get; set; }
}
static int a = 0;
protected void Button1_Click(object sender, EventArgs e)
{
a++;
Label1.Text = Convert.ToString(a);
}
}
}
After added update panel my Facebook login function not working after the link is clicked.
I added AJAX page request manager. The post Back settings function it not work as what I expected.
After I remove added update panel works is working as I expect.
/** This is what I try, but not work */
function loginByFacebook() {
var prm = Sys.WebForms.PageRequestManager.getInstance();
if (prm != null) {
prm._postBackSettings(function (sender, e) {
if (sender.loginByFacebook.panelsToUpdate != null) {
loginByFacebook();
}
});
};
}
*/
Below is the screenshot issues i'm stuck.
Update panel events are rendered partially hence the events will looses.
After Login or Register Button is click. The Facebook login will not work as expected. The dialog box will not close automatically.
I am working on a web application developed using Asp.Net MVC which on which I have a page on which data gets updated at realtime whenever data is modified on the database. I have some source on line and tried to implement this feature but it resulted in huge invalid data on the webpage.
I am using SQL dependency and SignalR to achieve this as follows
In Global.asax, I have the following
protected void Application_Start()
{
SqlDependency.Start(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
}
protected void Application_End()
{
SqlDependency.Stop(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
}
and in Models section I have the following classes
public class JobInfo
{
public int JobID { get; set; }
public string Name { get; set; }
public DateTime LastExecutionDate { get; set; }
public string Status { get; set; }
}
public class JobInfoRepository
{
public IEnumerable<JobInfo> GetData()
{
using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand(#"SELECT [JobID],[Name],[LastExecutionDate],[Status]
FROM [dbo].[JobInfo]", connection))
{
// Make sure the command object does not already have
// a notification object associated with it.
command.Notification = null;
SqlDependency dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
if (connection.State == ConnectionState.Closed)
connection.Open();
using (var reader = command.ExecuteReader())
return reader.Cast<IDataRecord>()
.Select(x => new JobInfo(){
JobID = x.GetInt32(0),
Name = x.GetString(1),
LastExecutionDate = x.GetDateTime(2),
Status = x.GetString(3) }).ToList();
}
}
}
private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
JobHub.Show();
}
}
I have created a SignalR Hub class as follows which has the Show() function used in the above class
using Microsoft.AspNet.SignalR.Hubs;
public class JobHub : Hub
{
public static void Show()
{
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<JobHub>();
context.Clients.All.displayStatus();
}
}
And I have the controller in which I am calling GetData() method defined in the JobInfoRepository class
public class JobInfoController : Controller
{
// GET: /JobInfo/
JobInfoRepository objRepo = new JobInfoRepository();
public IEnumerable<JobInfo> Get()
{
return objRepo.GetData();
}
}
I have created an Action named JobInfo in HomeController and returned the following view
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>JobStatus</title>
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/jquery-1.9.1.min.js")" type="text/javascript"></script>
</head>
<body>
<div>
<table id="tblJobInfo" class="clientTable" style="text-align:center;margin-left:10px"></table>
</div>
</body>
</html>
#section scripts {
<script src="~/Scripts/jquery.signalR-2.0.1.min.js"></script>
<script src="/signalr/hubs"></script>
<script src="~/App/JobInfo.js"></script>
}
to retrieve the data and supply it to tblJobInfo id in the above html, a java script function is used
$(function () {
// Proxy created on the fly
var job = $.connection.jobHub;
// Declare a function on the job hub so the server can invoke it
job.client.displayStatus = function () {
getData();
};
// Start the connection
$.connection.hub.start();
getData();
});
function getData() {
var $tbl = $('#tblJobInfo');
$.ajax({
url: '../JobInfo/',
type: 'GET',
datatype: 'json',
success: function (data) {
if (data.length > 0) {
$tbl.empty();
$tbl.append(' <tr><th>ID</th><th>Name</th><th>Status</th></tr>');
var rows = [];
for (var i = 0; i < data.length; i++) {
rows.push(' <tr><td>' + data[i].JobID + '</td><td>' + data[i].Name + '</td><td>' + data[i].Status + '</td></tr>');
}
$tbl.append(rows.join(''));
}
}
});
}
As in the demo I found it to be working fine but when I go to http://localhost:57044/Home/JobInfo/ I get invalid data on the page besides not getting the realtime notifications as in the following image
reference to the source I found online is http://techbrij.com/database-change-notifications-asp-net-signalr-sqldependency