i through i will call SQL Dependency related code Application_Start event and my objective will be completed. my scenario is i have a routine in my web application which i invoke manually just clicking on a button when data updated in sql server table. i was told to make this process automated.
so i go through couple of article on SQL Dependency and through i can make my manual process automated by SQL Dependency because we can monitor table change by SQL Dependency and SQL Dependency can notify us when change done.
please see my code
protected void Application_Start(Object sender, EventArgs e)
{
System.Data.SqlClient.SqlDependency.Stop(connectionString);
System.Data.SqlClient.SqlDependency.Start(connectionString);
RegisterNotification();
}
static SqlDependency dep;
private static void RegisterNotification()
{
string tmpdata = "";
try
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT ActivityDate FROM [bba-reman].ContentChangeLog";
dep = new SqlDependency(cmd);
dep.OnChange += new OnChangeEventHandler(OnDataChange);
SqlDataReader dr = cmd.ExecuteReader();
{
while (dr.Read())
{
if (dr[0] != DBNull.Value)
{
tmpdata = dr[0].ToString();
}
}
}
dr.Dispose();
cmd.Dispose();
}
}
finally
{
//SqlDependency.Stop(connStr);
}
}
static void OnDataChange(object sender, SqlNotificationEventArgs e)
{
SqlDependency dep = sender as SqlDependency;
dep.OnChange -= new OnChangeEventHandler(OnDataChange);
SiteSearch.CreateIndex(false);
RegisterNotification();
}
protected void Application_End(Object sender, EventArgs e)
{
System.Data.SqlClient.SqlDependency.Stop(connectionString);
}
the above code was running fine but i faced a good problem. suppose no visitor is visiting our web site and at the same time if some one change sql data by a win apps then i saw OnDataChange() event is not firing but if at least one visitor is with our site then OnDataChange() event is firing properly.
may be this is default nature of asp.net engine. i could use SQL Dependency in win service or in winform apps but i have some constrain because the routine which i am calling after detection of data change in db that is in our web application.
So please guide me what i can do as a result OnDataChange() event should always fire if no visitor is visiting our web site.
thanks
Related
Im trying to make a aspx application that connects to a access database on a share.
the path is correct, when i copy paste it in a run screen it opens a database right away.
The weird thing is that the exception that im getting is this, however the database is not a mdb and not in that location either.(it was dutch I translated it, might not be 100% correct translation):
Cant find file C:\Program Files (x86)\IIS Express\dbo.mdb
This is my code:
The exception is fired on the ExecuteReader
namespace AssetDB
{
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btn_zoek_Click(object sender, EventArgs e)
{
if (txt_name.Text.Length < 4)
return;
using (OleDbConnection conn = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\\netwerk\data\TeamFolders\ICT\Asset Database\_Backend\Assets_be.accdb; "))
using (OleDbCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "Select * from dbo.Bruikleen_Laptops where Laptop_id = #id";
cmd.Parameters.AddWithValue("#id", txt_name.Text);
conn.Open();
using (OleDbDataReader r = cmd.ExecuteReader())
while(r.Read())
{
drop_gevonden.Items.Add(r["Laptop_id"].ToString());
}
conn.Close();
}
}
}
}
I'm developing website with query notification using SqlCacheDependency. When the website loads for the first time, if there is any cache, it retrieves the data from the cache while the opposite, if there is no cache, it retrieves data from database and then insert the cache.
When the user inserts data, and clicks a button, the website stores the data to the database, removes the cache, so when the page redirects to itself, there is no cache, which makes the website should retrieve the new data.
Here is the following code:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
return;
this.BindGrid();
System.Diagnostics.Debug.WriteLine(Cache.Count);
//cache counts : -4; I don't even know why
}
protected void btnSave_Click(object sender, EventArgs e)
{
this.Insert(this.txtTitle.Text, Convert.ToInt32(this.txtDescription.Text));
//insert just function to update the database
Cache.Remove("Messages");
this.BindGrid();
}
private void BindGrid()
{
DataTable dtMessages = (DataTable)Cache.Get("Messages");
if (dtMessages == null)
{
dtMessages = this.LoadMessages();
lblDate.Text = string.Format("Last retrieved DateTime : {0}", System.DateTime.Now);
}
else
{
lblDate.Text = "Data Retrieved from Cache";
}
grdMessages.DataSource = dtMessages;
grdMessages.DataBind();
}
private DataTable LoadMessages()
{
DataTable dtMessages = new DataTable();
dtMessages = new DataTable();
using (SqlConnection connection = new SqlConnection(this.ConnectionString))
{
SqlCommand command = new SqlCommand("select * from blablabla", connection);
SqlCacheDependency dependency = new SqlCacheDependency(command);
if (connection.State == ConnectionState.Closed)
connection.Open();
dtMessages.Load(command.ExecuteReader(CommandBehavior.CloseConnection));
if (Cache.Get("Messages") == null)
{
Cache.Insert("Messages", dtMessages, dependency);
}
}
return dtMessages;
}
The problem is, looks like the cache hasn't been made/inserted. Because the value of Cache.Count is negative number. And whenever I just refresh the page (where the page supposed to retrieve data from cache), the page retrieves the data from database.
What's wrong and what is the solution? There are two important things to know:
Page only retrieves from database when there is no cache (cache'll be removed when user inserts data)
Page retrieves from cache when there is no any updated/new data from user (e.g. user just refreshes the page, page retrieves from cache)
Please help. Thank you for your time and attention.
I am using SQLCacheDependency in my ASP.NET application with Query Notifications.
I followed this article to set up my database with success.However whenever I am trying to store data in the cache object.It just does not hold value.It is always null .I am not getting any errors or exceptions.
Here is my code
Global.asax
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
System.Data.SqlClient.SqlDependency.
Start(ConfigurationManager.ConnectionStrings["McdConn"].ToString());
}
void Application_End(object sender, EventArgs e)
{
// Code that runs on application shutdown
System.Data.SqlClient.SqlDependency.
Stop(ConfigurationManager.ConnectionStrings["McdConn"].ToString());
}
public static class CacheManagement
{
public static DataTable CreateCache(string cacheName, string tableName, string query)
{
DataTable dtResult = new DataTable();
try
{
string connectionString = ConfigurationManager.ConnectionStrings["McdConn"].ToString();
dtResult = HttpContext.Current.Cache[cacheName] as DataTable;
if (dtResult == null)
{
dtResult = new DataTable();
using (var cn = new SqlConnection(connectionString))
{
cn.Open();
var cmd = new SqlCommand(query, cn);
cmd.Notification = null;
cmd.NotificationAutoEnlist = true;
SqlCacheDependencyAdmin.EnableNotifications(connectionString);
if (!SqlCacheDependencyAdmin.GetTablesEnabledForNotifications(connectionString).Contains(tableName))
{
SqlCacheDependencyAdmin.EnableTableForNotifications(connectionString,tableName);
}
var dependency = new SqlCacheDependency(cmd);
//SqlDataAdapter ad = new SqlDataAdapter(cmd);
//ad.Fill(dsResult);
SqlDataReader reader = cmd.ExecuteReader();
dtResult.Load(reader);
HttpContext.Current.Cache.Insert(cacheName, dtResult, dependency);
}
}
}
catch (Exception ex)
{
Exception_Log.ExceptionMethod("Web", "CacheManagement.cs", "CacheManagement", ex);
}
return dtResult = HttpContext.Current.Cache[cacheName] as DataTable;
}
}
Code Behind
var dtCachedCategories = HttpContext.Current.Cache["tbl_CategoryMaster_Cached"] as DataTable;
if (dtCachedCategories == null)
{
dtCachedCategories = CacheManagement.CreateCache("tbl_CategoryMaster_Cached","dbo.tbl_CategoryMaster_Languages", "Select * from dbo.tbl_CategoryMaster_Languages");
}
The above always returns null.
Can anyone help me in pointing out what could be missing?
Well there's a lot you can do to debug your code and arrive at a conclusion. It seems like your cached item is getting removed too frequently.
1.) Use CacheItemPriority.NotRemovable to Cache.Insert() to make sure ASP.NET doesn't removes
your item whenever it feels so. use the Insert() method explained here. Check this MSDN
article too.
2.) To find out the reason why your cached item is getting removed , log this removal action using
CacheItemRemovedCallback delegate option of your Cache.Insert() method. Check this Insert method
overload version and also this link.
3.) Make sure your dtresult as well as your reader is not null. Check the lines:
SqlDataReader reader = cmd.ExecuteReader(); & dtResult.Load(reader); , together with your logs.
4.) Check your application Pool recycle time. This link has everything related to App pool settings ( IIS 7 +).
5.) This link has a solution for App pool of IIS 6: http://bytes.com/topic/net/answers/717129-c-asp-net-page-cache-getting-removed-too-soon
Also, try using HttpRuntime.Cache method to see if it works.
System.Web.HttpRuntime.Cache.Insert(cacheName, dtResult, dependency);
I am building a web application where a job submitted by user is handled by a background service and the communication between web app and background service is done on database. So when a search starts, web application inserts a record into db and waits till the status field of the record changes. As I understand, if I implement this on the request thread, I am blocking one of the pool threads unnecessarily, but cannot get my head around to do this asynchronously. What is the best practice in this case?
SQLDependency is very useful, but on the server side it provided only half the solution. I overcame the other half by using SignalR to signal the client that the query is over. In the end it was quite an efficient and elegant solution. Thanks for the info!
public class KYHub : Hub
{
void OnChange(object sender, SqlNotificationEventArgs e)
{
SqlDependency dependency = sender as SqlDependency;
dependency.OnChange -= OnChange;
if (e.Info != SqlNotificationInfo.Error && e.Info != SqlNotificationInfo.Delete)
{
string connstr = System.Configuration.ConfigurationManager.ConnectionStrings["cnnStr"].ConnectionString;
SqlConnection conn = new SqlConnection(connstr);
conn.Open();
SearchResult result= SearchResult.Parse(conn, Caller.TaskID);
conn.Close();
Caller.endsearch(result);
}
}
public void Search(SearchParam search)
{
string connstr = System.Configuration.ConfigurationManager.ConnectionStrings["cnnStr"].ConnectionString;
SqlConnection conn = new SqlConnection(connstr);
conn.Open();
search.ClientID = Caller.id;
int QueryID = search.Save(conn);
Caller.TaskID = QueryID;
SqlCommand cmd = new SqlCommand(String.Format("SELECT Completed FROM dbo.Tasks WHERE TaskID={0}", QueryID), conn);
SqlDependency dep = new SqlDependency(cmd);
dep.OnChange += OnChange;
cmd.ExecuteReader();
conn.Close();
}
}
If you are using SQL Server as your DB then you can use a ADO.NET feature called SQLDependency,
What this dose when setup correctly is, when ever there is a change in table (which you will configure) a C# event will be raised.
Here is a article that expains it
Note: You will have to setup your SQL server to enable this.
http://www.codeproject.com/Articles/12335/Using-SqlDependency-for-data-change-events
And this one expains how to refresh page after data in table has changed
http://msdn.microsoft.com/en-us/library/e3w8402y%28v=vs.80%29.aspx
I am trying to submit filledin information in the form to the database. I have done the below mentioned coding for the save button. When I click on the save button to save the information, I am getting an error. I need it to be done and for the same need help from the geeks around here.
COde for SAVE button data from database
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string conn = ConfigurationManager
.ConnectionString("welcome").ConnectionString;
SqlConnection con=new SqlConnection(conn);
SqlCommand cmd = new SqlCommand("Insert into abhishek(pr_name,Add,add2) values(#ah,#Ap,#qe)",con);
cmd.CommandType = CommandType.Text;
cmd.Parameter.Addwithvalue("#ah", TextBox1.Text.Trim());
cmd.Parameter.Addwithvalue("#ap", TextBox2.Text.Trim());
cmd.Parameter.Addwithvalue("#qe", TextBox3.Text.Trim());
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
Check the error in the image below:
You are missing an 's' from the ConnectionStrings indexed property. Once you fix that error, however, you will also find you are missing more 's' from the SqlCommand.Parameters property.
To reveal these issues, open Properties of your code-behind file, and choose Build Action of Compile. (Also, I can see from your image that it looks like your project is setup as a Web Site rather than a Web Application; if possible, look into converting this over to a Web Application, as it offers a number of benefits.)
Once you get your syntax corrected, then you should change your code so that the update is invoked through the button click handler, rather than on page load.
In your markup code in the aspx:
<asp:Button runat="server" ID="btnSave" Text="Save" OnClick="btnSave_Click" />
In your code-behind:
protected void btnSave_Click(object sender, EventArgs e)
{
string conn = ConfigurationManager.ConnectionStrings["welcome"].ConnectionString;
using (SqlConnection con = new SqlConnection(conn))
{
SqlCommand cmd = new SqlCommand("Insert into abhishek(pr_name,Add,add2) values(#ah,#Ap,#qe)", con);
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#ah", TextBox1.Text.Trim());
cmd.Parameters.AddWithValue("#ap", TextBox2.Text.Trim());
cmd.Parameters.AddWithValue("#qe", TextBox3.Text.Trim());
con.Open();
cmd.ExecuteNonQuery();
}
}
Note that I have moved the code into the button click event handler, and out of the Page_Load. The Load event handler should only be used for initialization items needed unconditionally on the execution path of the page (i.e., regardless of whatever button was clicked on the page), and should look something like the following:
protected void Page_Load(object sender, EventArgs e)
{
// Code to run every time the page is created, both initially and on postback
if (IsPostBack)
{
// Code to run every time the page is posted back (any submit event)
}
else
{
// Code to run on the initial creation of the page
}
}