Update View with new data MVC - c#

I'm working on a project where I have to keep data that is up to date. I've been working on using a Timer to keep the data that my controller has synced with my DB every x seconds.
My problem is that I can't get my View to Update/Refresh/Reload when the data is updated.
I don't have to get the page to update without clicking anything on the page.
Index method
public ActionResult Index()
{
if (aTimer.Enabled == false)
{
initTimer();
}
var ordersLinks = db.OrdersLinks.Include(o => o.List).Include(s => s.Order_Stop_Link).Include(i => i.OrdersInfoes);
return View(ordersLinks.ToList());
}
Timer Event Timer is a System.Timers.Timer
public void TimerEvent(object sender, ElapsedEventArgs e)
{
var OldDB = db.OrdersLinks.FirstOrDefault().OrderNr;
foreach (var entity in db.ChangeTracker.Entries())
{
entity.Reload();
}
var NewDB = db.OrdersLinks.FirstOrDefault().OrderNr;
if (OldDB != NewDB)
{
Index(); //This calls into the Index Method but doesnt update the view
//RedirectToAction("Index");
}
}
SOLVED
I used SignalR thanks to the comments, special thanks to #Stephen Muecke.

Related

How to redirect to another page in mvc?

I have a timer in my mvc4 controller I want to redirect to another page if condition satisfies in Timer_Elapsed event. The Timer_Elapsed event is-
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
using (MavenifyEntities db = new MavenifyEntities())
{
timer.Stop();
string tempId = TempData.Peek("TempId").ToString();
bool Ispresent = db.DataSyncs.Any(d => d.TempId == tempId);
if (Ispresent)
{
// redirect to another view
}
else
{
timer.Start();
}
}
}
You can use Response.Redirect like following:
Response.Redirect(Url.Action("YourAction", "YourController"));
I think best solution is that doing this job in JavaScript.
For example like this:
redirectURL = "http://x.com/ShowData";
function timedRedirect() {
//Check Server for redirect
setTimeout("location.href = redirectURL;",redirectTime);
}
return RedirectToAction("ActionName","ControllerName");

problem with RX and web service collection loading wp7

I'm beginner with C# and wp7 platform and I have some problem with good idea to get request from web service.
I made webservice in PHP (nusoap - WSDL) and everything is working fine in "normal" using.
Now I have ObservableCollection saved in IsolatedStorage with I load when Page is open (List of watched stacks exchange). Then I want to refresh data for every item from web service.
I don't know whether this is a good idea.
Code:
private GPWWebservicePortTypeClient client = new GPWWebservicePortTypeClient();
private ObservableCollection<WebServiceClass.ItemGetValues> StoredStock =
new ObservableCollection<WebServiceClass.ItemGetValues>();
public const string _fileName = "listaObserwowanych.xml";
public Page()
{
InitializeComponent();
DataContext = App.ViewModel;
this.Loaded += new RoutedEventHandler(Page_Loaded);
client.GetLastValueCompleted +=
new EventHandler<GetLastValueCompletedEventArgs>(client_GetLastValueCompleted);
foreach (var itemGetValuese in App.ViewModel.Items)
{
client.GetLastValueAsync(itemGetValuese.name);
}
var o =
Observable.FromEvent<GetLastValueCompletedEventArgs(client,"GetLastValueCompleted")
.Subscribe(setList);
}
void client_GetLastValueCompleted(object sender, GetLastValueCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(Convert.ToString(e.Error));
}
else
{
ObservableCollection<WebServiceClass.ItemGetValues> ListValues =
(ObservableCollection<WebServiceClass.ItemGetValues>)
JsonConvert.DeserializeObject(e.Result,
typeof(ObservableCollection<WebServiceClass.ItemGetValues>));
StoredStock.Add(ListValues[0]);
}
}
private void setList(IEvent<GetLastValueCompletedEventArgs> ex)
{
List.ItemsSource = StoredStock;
}
void Page_Loaded(object sender, RoutedEventArgs e)
{
App.ViewModel.LoadData();
List.ItemsSource = App.ViewModel.Items;
}
Like u see I use RX to call method client_GetLastValueCompleted add store result to auxiliary variable (StoredStock). Then refresh List in setList method, but that method is client_GetLastValueCompleted what is not soo good idea, becouse I need to run that method only when all of runned GetLastValueAsync in foreach is completed.
Second problem: becouse of async web service method StoredStock sometime have different order than App.ViewModel.Items .
Any good idea how to do that in right way?
Best regards,
Lukas
You're really mixing up a number of ways to call web services and Rx. You really need to decide on a single way and stick to it.
If you're going to use Rx, then you'll have something like this:
public Page()
{
InitializeComponent();
DataContext = App.ViewModel;
this.Loaded += new RoutedEventHandler(Page_Loaded);
}
void Page_Loaded(object sender, RoutedEventArgs e)
{
App.ViewModel.LoadData();
var storedStock =
new ObservableCollection<WebServiceClass.ItemGetValues>();
List.ItemsSource = storedStock;
var values =
Observable.Using<WebServiceClass.ItemGetValues, GPWWebservicePortTypeClient>
(() => new GPWWebservicePortTypeClient(), ws =>
{
var clientGetLastValue = Observable
.FromAsyncPattern<string, GetLastValueResponse>
(ws.BeginGetLastValue, ws.EndGetLastValue);
Func<string, WebServiceClass.ItemGetValues> deserializeFirst = r =>
((List<WebServiceClass.ItemGetValues>)JsonConvert
.DeserializeObject(r,
typeof(List<WebServiceClass.ItemGetValues>)))
.First();
return
from item in App.ViewModel.Items
from e in clientGetLastValue(item)
select deserializeFirst(e.Result);
});
values.Subscribe(storedStock.Add);
}
You'll have to get the right method call names for your web service client, but the code should roughly be right. Let me know how you go.
I corrected the code above. Should have returned the query inside the Using call rather than assign it to values.
I corrected the call to FromAsyncPattern to use the correct method names and return type from the actual web service reference class sent via email.
It should look like this:
Observable.FromAsyncPattern<string, GetLastValueResponse>
(ws.BeginGetLastValue, ws.EndGetLastValue);
If you're a beginner with C#, try to avoid RX for the time being. It is a cool technology, but if you use it without clear understanding of what is going on, it will bring more problems than solve.
Use a simple event, and when each async item arrives, locate and update the correspondent one in the stored list.

How to use effective caching in .NET?

i try to use effective caching but i face to face a problem. For example; i have 5 user they have used my app. user1,2,3,4 only fill grid by searcing(Caching is run!!!). on the other hand user5 adding new row. i want to refresh my cach data when adding new row. i read Multi threading to do that
code>using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Threading;
using System.Collections;
namespace WebApp.Caching.Threading
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Init(object sender, EventArgs e)
{
FillCache();
}
void FillCache()
{
using (var myCtx = new DataClasses1DataContext())
{
if (!(FlyAntCache.Exists("test")))
{
List<Table_1> toolStoreList = myCtx.Table_1s.ToList();
FlyAntCache.Add(toolStoreList, "test");
}
}
}
protected void Page_Load(object sender, EventArgs e)
{
WaitCallback method1 = new WaitCallback(ControlAllChanging);
bool isQueued = ThreadPool.QueueUserWorkItem(method1, new ManualResetEvent(false));
}
protected void ControlAllChanging(object state)
{
if (FlyAntCache.Exists("test"))
{
using (var myCtx = new DataClasses1DataContext())
{
List<Table_1> list;
list = myCtx.Table_1s.ToList();
List<Table_1> listCache = FlyAntCache.Get<List<Table_1>>("test");
bool IsIntersect = list.Except(listCache).Count() > 0;
if (IsIntersect)
{
FlyAntCache.Clear("test");
FillCache();
}
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
// Search
using (var myCtx = new DataClasses1DataContext())
{
var Qry = myCtx.Table_1s.
FromCache<Table_1>("test").
AsQueryable().Where(t => t.ad == TextBox1.Text.Trim());
GridView1.DataSource = Qry;
GridView1.DataBind();
}
}
}
}
My Scenario:
LOOK please :http://i53.tinypic.com/20pdc41.png
i really control if another user change my data, i must refresh my cache. is there any sensitivity to CAPTURE any new changing update new row save. for example :
1) i must capture new update . this mechanizm must run when changes occurs
2) i must capture new save. this mechanizm must run when new row adds
I'm still not quite sure what you're asking. My best guess is it sounds like you're trying to let a cache know when its data is stale.
Most caching implementations have this built in. Basically, you can expire a cache item (usually be removing it from the cache) when it has been updated.
For example, if you're just using the plain old built in caching that comes with ASP.net:
private static Cache Cache;
public void AddItem(string data)
{
//Do a database call to add the data
//This will force clients to requery the source when GetItems is called again.
Cache.Remove("test");
}
public List<string> GetItems()
{
//Attempt to get the data from cache
List<string> data = Cache.Get("test") as string;
//Check to see if we got it from cache
if (data == null)
{
//We didn't get it from cache, so load it from
// wherever it comes from.
data = "From database or something";
//Put it in cache for the next user
Cache["test"] = data;
}
return data;
}
UPDATE I updated the code sample to return a list of strings instead of just a string. This should make it more obvious what is happening.
To reiterate, the GetItems() call retrieves a list of strings. If that list is in cache, the cached list is returned. Otherwise, the list is retrieved and cached / returned.
The AddItem method explicitly removes the list from the cache, forcing the requery of the data source.
Not sure but are you looking for events? You could set up events in your caching mechanism to fire when an update occurs.
Here is a googled example

strange session problem

I have this field in my session class:
public bool IsCartRecentlyUpdated
{
get
{
if (this.session["IsCartRecentlyUpdated"] != null)
{
return (bool)this.session["IsCartRecentlyUpdated"];
}
else
{
this.session["IsCartRecentlyUpdated"] = false;
return (bool)this.session["IsCartRecentlyUpdated"];
}
}
set
{
this.session["IsCartRecentlyUpdated"] = value;
}
}
Whenever a user adds a product to the cart I put this value on true:
public void AddToCart(Product product, int quantity)
{
IsCartRecentlyUpdated = true;
//other code for updating the cart
}
Adding a product to the cart does a postback so I can show a message (ëg: Product added succesfully) in Page_Load of the General Master page where the shopping cart is located, when a product has just been added to the cart:
protected void Page_Load(object sender, EventArgs e)
{
if (this.sessionsUtil.IsCartRecentlyUpdated)
{
this.lblCartWarning.Text = (string)GetLocalResourceObject("CartWarning");
imgCardLogos.Visible = false;
}
else
{
this.lblCartWarning.Text = String.Empty;
imgCardLogos.Visible = true;
}
//other code
//put it back to false to not show the message each time the page is loaded
this.sessionsUtil.IsCartRecentlyUpdated = false;
}
Well this code works great locally but on the server it does not show the message after adding the product to the cart but on the second page loading...
(I guess that on the server somehow the page is loading before the session var is updated - extremely strange)
Do you know why? I do not see any problem in the code...
Strange issues like this might be easier to solve using IIS express
http://weblogs.asp.net/scottgu/archive/2011/01/03/vs-2010-sp1-beta-and-iis-developer-express.aspx

C# Silverlight - Delay Child Window Load?

The Scenario
Currently I have a C# Silverlight Application That uses the domainservice class and the ADO.Net Entity Framework to communicate with my database. I want to load a child window upon clicking a button with some data that I retrieve from a server-side query to the database.
The Process
The first part of this process involves two load operations to load separate data from 2 tables. The next part of the process involves combining those lists of data to display in a listbox.
The Problem
The problem with this is that the first two asynchronous load operations haven't returned the data by the time the section of code to combine these lists of data is reached, thus result in a null value exception.....
Initial Load Operations To Get The Data:
public void LoadAudits(Guid jobID)
{
var context = new InmZenDomainContext();
var imageLoadOperation = context.Load(context.GetImageByIDQuery(jobID));
imageLoadOperation.Completed += (sender3, e3) =>
{
imageList = ((LoadOperation<InmZen.Web.Image>)sender3).Entities.ToList();
};
var auditLoadOperation = context.Load(context.GetAuditByJobIDQuery(jobID));
auditLoadOperation.Completed += (sender2, e2) =>
{
auditList = ((LoadOperation<Audit>)sender2).Entities.ToList();
};
}
I Then Want To Execute This Immediately:
IEnumerable<JobImageAudit> jobImageAuditList
= from a in auditList
join ai in imageList
on a.ImageID equals ai.ImageID
select new JobImageAudit
{
JobID = a.JobID,
ImageID = a.ImageID.Value,
CreatedBy = a.CreatedBy,
CreatedDate = a.CreatedDate,
Comment = a.Comment,
LowResUrl = ai.LowResUrl,
};
auditTrailList.ItemsSource = jobImageAuditList;
However I can't because the async calls haven't returned with the data yet...
Thus I have to do this (Perform the Load Operations, Then Press A Button On The Child Window To Execute The List Concatenation and binding):
private void LoadAuditsButton_Click(object sender, RoutedEventArgs e)
{
IEnumerable<JobImageAudit> jobImageAuditList
= from a in auditList
join ai in imageList
on a.ImageID equals ai.ImageID
select new JobImageAudit
{
JobID = a.JobID,
ImageID = a.ImageID.Value,
CreatedBy = a.CreatedBy,
CreatedDate = a.CreatedDate,
Comment = a.Comment,
LowResUrl = ai.LowResUrl,
};
auditTrailList.ItemsSource = jobImageAuditList;
}
Potential Ideas for Solutions:
Delay the child window displaying somehow?
Potentially use DomainDataSource and the Activity Load control?!
Any thoughts, help, solutions, samples comments etc. greatly appreciated.
First of there is no point in delaying the display of a window. Instead you should design your code to be able to handle asynchronous updates to the data. In this case you have a somewhat interesting situation where you are performing two asynchronous load operations and you are only able to create the data for display when both operations have completed.
One solution to this problem is to move the query where you combine the data to the server side. Then instead of retrieving Image and Audit objects from the server in two separate operations you can retrieve JobImageAudit objects.
Another solution is to create something similar to a view-model for the data you retrieve. Here is a rough sketch to get you started:
public class JobImageAuditViewModel : INotifyPropertyChanged {
IEnumerable<Image> images;
IEnumerable<Audit> audits;
IEnumerable<JobImageAudit> jobImageAudits;
public void GetData() {
this.images = null;
this.audits = null;
this.jobImageAudits = null;
OnPropertyChanged("JobImageAuditList");
// Load images by using GetImageByIDQuery()
// Load audits by using GetAuditByJobIDQuery()
}
void LoadImageCompleted(Object sender, EventArgs e) {
// Store result of query.
this.images = ...
UpdateJobImageAuditList();
}
void LoadAuditCompleted(Object sender, EventArgs e) {
// Store result of query.
this.audits = ...
UpdateJobImageAudits();
}
void UpdateJobImageAudits() {
if (this.images != null && this.jobs != null) {
// Combine images and audits.
this.jobImageAudits = ...
OnPropertyChanged("JobImageAudits");
}
}
public IEnumerable<JobImageAudit> JobImageAudits {
get {
return this.jobImageAudits;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(String propertyName) {
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
You then have to databind auditTrailList.ItemsSource to JobImageAuditViewModel.JobImageAudits. You can do this by setting the DataContext of the ChildWindow or UserControl that contains auditTrailList to an instance of JobImageAuditViewModel and add this attribute to the auditTrailList XAML:
ItemsSource="{Binding JobImageAudits}"
Actually the .NET RIA framework is designed to let the client-side generated entitiy classes assume the role of the view-model in an MVVM application. They can be extended on the client side and they support INotifyPropertyChanged. However, in your case you are using an entity on the client side that doesn't exist on the server side. Combining my first suggestion with data-binding is probably the ultimate solution to your problem.

Categories

Resources