BASEER ULHASSAN BASEER ULHASSAN - 1 month ago 11
C# Question

One View And One Controller with Two Variable Time Queries

I am confused about achieving afollowing functionality in my C# Application.


  1. There are two Queries directed to run from there on my Database.

  2. Query1 runs in 0.2 sec maximum, Query2 takes 0.5 sec - 1.5 min not fixed time.

  3. A single View to display numeric information returned from both Queries, is attached to this controller.

  4. Half View content comes from Query1 and rest from Query2.

  5. Controller Refreshes after 5 minutes, Fresh data from DB comes in.

  6. I need to show first half of View as Query1 runs quickly and check if Query2 has completed then show its results as well on View ?



My solution is to :
Hide Second Half of view and wait till the Query2 runs. Once Query2 data is in ViewBag; unhide and display Second half of view as well. I am unable to come back to controller to see Query2 results once I leave controller and display half View. Please advise any solution, hope I am able to convey my question rightly.

Adding Controller Code:

public ActionResult Show()
{
bool dataComing = false;
logger.AddLog("Show Mehtod Activated");

if (dbConn1 == true)
{
try
{
logger.AddLog("DB Connection 2 Data Reading Started.");
cmd = DBConnection.CreateCommand();
logger.AddLog("DB Connection 2 CReateCommandCalled.");
cmd.CommandText = myQuery;
logger.AddLog("DB Connection 2 CommandText is set to Query.");
cmd2.CommandText = myQuery2;
DbReader = cmd.ExecuteReader();
DbReader2 = cmd2.ExecuteReader();
dataComing = true;
DbReader.Read();
}
catch (Exception e)
{
dataComing = false;
logger.AddLog("ERROR while intiating DB Connection 1, error is:" + e.ToString());
return View();
}

logger.AddLog("DB Connection 2 Reading Data...");
}

if (dataComing == true)
{
LoggedInAgents = DbReader["loggedinagent"].ToString();
logger.AddLog("DB Connection 2 Data : LoggedInAgents = " + LoggedInAgents);
ViewBag.loggedInAgents = LoggedInAgents;
DbReader.Close();
SecondData = DbReader2["second"].ToString();
logger.AddLog("DB Connection 2 Data : LoggedInAgents = " + SecondData );
ViewBag.second= SecondData;
DbReader2.Close();
logger.AddLog("DB Reader Closing");
cmd.Dispose();
cmd2.Dispose();
DBConnection.Close();
logger.AddLog("DB Connection Closed");
}
else
{
ViewBag.loggedInAgents = "00";
ViewBag.second= "00";

}

logger.AddLog("PAGE Refresh Set to 5 minutes");
logger.AddLog("Before Refresh Time"+ DateTime.Now.ToString("h:mm:ss tt"));
Response.AddHeader("Refresh", "300");
logger.AddLog("PAGE Refresh Called");
logger.AddLog("After Refresh Time" + DateTime.Now.ToString("h:mm:ss tt"));
logger.AddLog("Returning From Show Function");

return View();


}

Answer

When you execute return View(), razor will execute the code in your view (with the model data passed to it if any) and render the output to the browser, which is pure HTML.

If you want to the behavior you are after, you should use ajax to get the second query execution result. Have your action method returns the data for your first action method and in the view you can make an ajax call to server on the document ready event. When the result comes back, append it to the DOM.

You can use $.get method to make the ajax call for your second query data. so in your view, add this code

<div id="dataForSecond"></div>
@section scripts
{
  <script>
    $(function(){
      $.get("@Url.Action("GetData","Home")",function(data){
          $("#dataForSecond").html(data);
      });
    });
  </script>
}

Assuming you have an action method called GetData in your HomeController which executes your second query and return the data

public ActionResult GetData()
{
  var secondData="ReplaceThisWithValueComingFromYourQuery";
  return Json(secondData,JsonRequestBehavior.AllowGet);
}

If you want to refresh the data in a specific interval, you might consider using setInterval method to make an ajax call to get data.

The below code will update the div content in every 5 seconds.

$(function(){
   var refreshInterval = 5000;
   var url="@Url.Action("GetData","Home")";

   setInterval(function () {
        $("#dataForSecond").load(url);         
    }, refreshInterval);   
});