I've got a table in my blazor webassembly client side application which broadcasts data from an sql server.
I've set up signalr to every 5 seconds which will grab the new data and push the data to the table so the clients get real time data every 5 seconds.
Blazor radzen provides an edit table function which allows users to edit the details of certain columns and then save that change and push it to the database.
But everytime that I use this edit function and save, I get an error saying:
"Exception thrown: System.InvalidOperationException in Microsoft.EntityFrameworkCore.dll".
Here is my code:
Radzen Grid Table:
<div class="row">
<h1>Servers</h1>
<RadzenGrid #ref="serversGrid" AllowFiltering="true"
FilterCaseSensitivity="Radzen.FilterCaseSensitivity.CaseInsensitive"
AllowPaging="true" AllowSorting="true" Data="#serverData" TItem="Server"
ColumnWidth="200px" RowUpdate="#OnUpdateRow" PageSize="10">
<Columns>
<RadzenGridColumn TItem="Server" Property="ServerIp" Title="IP" />
<RadzenGridColumn TItem="Server" Property="Status" Title="Status">
<EditTemplate Context="server">
<RadzenDropDown #bind-Value="server.Status" Data="#statusList" Style="width:100%"/>
</EditTemplate>
</RadzenGridColumn>
</Columns>
</RadzenGrid>
SignalR timer code:
public partial class Startup
{
System.Timers.Timer _timer;
public Startup(IConfiguration configuration)
{
Configuration = configuration;
StartTimer();
}
private void StartTimer()
{
_timer = new System.Timers.Timer();
_timer.Interval = 5000;
_timer.Elapsed += TimerElapsedHandler;
_timer.Start();
}
On elapsed, the timer will call signalr to get data and replace the data with the newer version of it.
public async Task BroadcastServers()
{
var data = _serverService.GetServers().Result; //get data from service
await _hubContext.Clients.All.SendAsync("ServerBroadcast", data); //send data to all clients
}
I also get another error which says:
The instance of entity type cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached entity framework core.
I've searched this error up and still I've got no solution.
Please help! Thank you
Related
I have an ASP.NET MVC application. When a new customer is created via CustomerController I run a new background task (using HostingEnvironment.QueueBackgroundWorkItem) to create a new Azure SqlDatabase for that customer.
I use Entity Framework Code First to create/initialize the new database. Here's the code:
// My ConnectionString
var con = "...";
// Initialization strategy: create db and execute all Migrations
// MyConfiguration is just a DbMigrationsConfiguration with AutomaticMigrationsEnabled = true
Database.SetInitializer(strategy: new MigrateDatabaseToLatestVersion<CustomerDataContext, MyConfiguration>(useSuppliedContext: true));
using (var context = new CustomerDataContext(con))
{
// Neither 'Connection Timeout=300' in ConnectionString nor this line helps -> TimeoutException will rise after 30-40s
context.Database.CommandTimeout = 300;
// create the db - this lines throws the exception after ~40s
context.Database.Initialize(true);
}
My Problem is that I always get a TimeoutException after about 40secs. I think that happens because Azure cannot initialize the new database within this short period of time. Don't get me wrong: The database will be created well by Azure but I want to wait for that point / get rid of the TimeoutException.
Edit1:
I'm using Connection Timeout=300 in my ConnectionString but my app doesn't really care about that; after about 40s I'm always running into an SqlError.
Edit2:
The exception that raises is an SqlException. Message: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. Source: .Net SqlClient Data Provider
Edit3:
I can confim now that this has nothing to do with ASP.NET/IIS. Even in a simple UnitTest method the code above fails.
It seems that there is another CommandTimeout setting that is involved in database initialization process when using Code First Migrations. I want so share my solution here just in case anybody encounters this problem too.
Thanks to Rowan Miller for his hint pointing me to the solution.
Here's my code:
// Initialisation strategy
Database.SetInitializer(strategy: new CreateDatabaseIfNotExists<MyDataContext>());
// Use DbContext
using (var context = new MyDataContext(myConnectionString))
{
// Setting the CommandTimeout here does not prevent the database
// initialization process from raising a TimeoutException when using
// Code First Migrations so I think it's not needed here.
//context.Database.CommandTimeout = 300;
// this will create the database if it does not exist
context.Database.Initialize(force: false);
}
And my Configuration.cs class:
public sealed class Configuration : DbMigrationsConfiguration<MyDataContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
AutomaticMigrationDataLossAllowed = false;
// Very important! Gives me enough time to wait for Azure
// to initialize (Create -> Migrate -> Seed) the database.
// Usually Azure needs 1-2 minutes so the default value of
// 30 seconds is not big enough!
CommandTimeout = 300;
}
}
The command timeout and the connection timeout are two different settings. In this case you only increase the commandtimeout. You can increase the connection timeout in the web.config: Connection Timeout=120. The only time you want to increase the connection timeout is when you are creating the database.
I have an ASP.Net website where I am downloading a large zip file to the server from a remote site. This file is not transferred to the client, but will remain on the server. I would like to provide progress updates to the user using SignalR. When I use the code below:
public class InstallController : Hub
{
public void Send( string message )
{
Clients.All.AddMessage( message );
}
public void FileDownload()
{
WebClient client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler( client_DownloadProgressChanged );
client.DownloadFileCompleted += new AsyncCompletedEventHandler( client_DownloadFileCompleted );
client.DownloadFileAsync( new Uri( "http://someserver.com/install/file.zip" ), #"\file.zip" );
}
/* callbacks for download */
void client_DownloadProgressChanged( object sender, DownloadProgressChangedEventArgs e )
{
double bytesIn = double.Parse( e.BytesReceived.ToString() );
double totalBytes = double.Parse( e.TotalBytesToReceive.ToString() );
double percentage = bytesIn / totalBytes * 100;
this.Send( String.Format( "Download progress: {0}%", percentage.ToString() ) );
}
void client_DownloadFileCompleted( object sender, AsyncCompletedEventArgs e )
{
this.Send( "Finished downloading file..." );
}
}
I get the exception:
An exception of type 'System.InvalidOperationException' occurred in
System.Web.dll but was not handled in user code
Additional information: An asynchronous operation cannot be started at
this time. Asynchronous operations may only be started within an
asynchronous handler or module or during certain events in the Page
lifecycle. If this exception occurred while executing a Page, ensure
that the Page is marked <%# Page Async="true" %>. This exception may
also indicate an attempt to call an "async void" method, which is
generally unsupported within ASP.NET request processing. Instead, the
asynchronous method should return a Task, and the caller should await
it.
I've seen several mentions to use the HttpClient instead of the WebClient, but I don't see how to get the progress from that.
"It's All About the SynchronizationContext"
http://msdn.microsoft.com/en-us/magazine/gg598924.aspx
This phrase is becoming quite common since the addition of new technology and features in .NET.
Briefly.. There are several components, such as BackgroundWorker and WebClient, thats hiding the SynchronizationContext to the capture and usage, it means that you need to respect the life cycle of requests, the life cycle of ASP.NET components.
Speaking specifically, the HTTP methods (GET and POST) always keep working in the same way, the client submits a HTTP request to the server, then the server returns a response to the client, and the application will try to ensure that this occurs, the SynchronizationContext of ASP.NET was designed for this.
More information:
http://codewala.net/2014/03/28/writing-asynchronous-web-pages-with-asp-net-part-3/
Which ASP.NET lifecycle events can be async?
http://evolpin.wordpress.com/2011/05/02/c-5-await-and-async-in-asp-net/
Even the requests using SignalR contains the same ASP.NET SynchronizationContext, because of it you need to work "outside" the current SynchronizationContext or use it in the right way.
SignalR was designed to use asynchronous programming, using TPL as default, you can take benefits of it, check in http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server#asyncmethods and http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server#asyncclient
You can solve your problem in many ways.
If you want to use SignalR to show the progress.. I would do something like the code below (I'm still using .NET 4.0, bu it is more easy with .NET 4.5 with TaskAsync methods).
public Task<string> FileDownload()
{
var client = new WebClient();
client.DownloadProgressChanged += (sender, args) => client_DownloadProgressChanged(sender, args, this.Context.ConnectionId);
client.DownloadFileAsync(new Uri("https://epub-samples.googlecode.com/files/cc-shared-culture-20120130.epub"), #"C:\temp\file.zip");
var result = new TaskCompletionSource<string>();
AsyncCompletedEventHandler clientOnDownloadFileCompleted = (sender, args) =>
{
client.Dispose();
if (args.Error != null)
{
result.SetException(args.Error); //or result.SetResult(args.Error.Message);
return;
}
result.SetResult("Downloaded");
};
client.DownloadFileCompleted += clientOnDownloadFileCompleted;
return result.Task;
}
private static void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e,
string connectionId)
{
GlobalHost.ConnectionManager.GetHubContext<SomeHub>()
.Clients.Client(connectionId)
.NotifyProgress(e.ProgressPercentage);
}
Keep in mind that this is just an example, you could improve the way they treat the disconnection, and cancellation, among other things that can occur (depends on your application logic).
Also it is possible to use a "workaround" (not recommended):
Fire and forget async method in asp.net mvc
How to execute async 'fire and forget' operation in ASP.NET Web API
The code would be very similar to the above.
I want to make a simple Silverlight application in ASP.NET and LINQ. I have two talbe
Student :[student_id,student_name,address, phone,country_id] Country
:[country_id,country_name]
Thiw tow table is join by country_id.
I have inluced a LINQ Data Class in my project.
I have included a Silverlight-Enabled-WCF-Serfice. In this service I have made tow method and there code is like
[OperationContract]
public List<Country> LoadCountry()
{
var result = from coun in oLINQDataClassesDataContext.Countries
select coun;
return result.ToList();
}
[OperationContract]
public IList<Student> LoadStudent()
{
var result = from std in oLINQDataClassesDataContext.Students
select std;
return result.ToList();
}
Then I add a service reference of that WCF service. Then I include a DataGrid in my silverlight .xml file.
Now I want to show all the students in that DataGrid. For this I have written the following code
WCFServiceReference.WCFServiceClient oWCFServiceClient = new WCFServiceReference.WCFServiceClient();
public Home()
{
InitializeComponent();
oWCFServiceClient.LoadStudentCompleted += new EventHandler<WCFServiceReference.LoadStudentCompletedEventArgs>(oWCFServiceClient_LoadStudentCompleted);
oWCFServiceClient.LoadStudentAsync();
}
void oWCFServiceClient_LoadStudentCompleted(object sender, WCFServiceReference.LoadStudentCompletedEventArgs e)
{
dataGrid1.ItemsSource = e.Result;
}
Then I build the whole project and found no error. If I run the project then I found an error and it is--
An exception occurred during the operation, making the result invalid.
Check InnerException for exception details. at
System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary()
at
Silverlight.WCFServiceReference.LoadStudentCompletedEventArgs.get_Result()
at Silverlight.Home.oWCFServiceClient_LoadStudentCompleted(Object
sender, LoadStudentCompletedEventArgse) at
Silverlight.WCFServiceReference.WCFServiceClient.OnLoadStudentCompleted(Object
state)
If I remove county table form the LINQ class and remove LoadCountry() method form the service and call LoadStudent() method form silverlight form then it runs accurately and all the data is displayed in my DataGrid.
If I remove student table form the LINQ class and remove LoadStudent() method form the service then LoadCountry() method runs accurately. Both methods are not work if the present same time in LINQ & WCF Service .
NB: Both tables has data. If I run a SQL join query then it returns data
I can’t understand what the problem is.
Is there anyone to help me regarding this problem?
Thanks in advance.
Rashed
go to properties of dbml file and change the Serialization mode to unidirectional
I am making a very simple Lightswitch project which will connect to a table I have in an Oracle 11g database. I add an editable grid to the project and build the project. When I try to add or edit data in the grid I get the following error:
An error occurred while starting a transaction on the provider connection. See the inner exception for details.
Inner exception message:
Connection is already part of a local or a distributed transaction
There is no custom code in the project. My perception was that Lightswitch was supposed to make forms over data very easy. I've looked around for help but nothing so far.
//You need to clean up or the txn will fail..
partial void SaveChanges_Executed()
{
tx.Complete();
tx.Dispose();
}
If you get this error, "Inner exception message: Connection is already part of a local or a distributed transaction"
you can resolve the issue by following the second post by BScholz, https://forums.oracle.com/forums/thread.jspa?threadID=2263095
Basically, you need to implement SaveChanges_Excuting and SaveChanges_Excuted for the Oracle Data Source.
Switch to "File View" (LightSwitch will display "Logical View" by default).
Add a reference to "System.Transactions" in Server project.
Switch back to "Logical View"
Right Click the Data Source Name and click "View Code" to edit partial class.
Copy-and-paste the code below:
private TransactionScope _tscope;
partial void SaveChanges_Executing()
{
_tscope = new TransactionScope(TransactionScopeOption.Required,
new TransactionOptions
{
IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted
});
}
partial void SaveChanges_Executed()
{
_tscope.Complete();
_tscope.Dispose();
}
Try adding this code to your datasource code. (right click on the Oracle datasource and choose "View Code")
Make sure you remember to change the class name to match your datasource.
using System.Transactions;
namespace LightSwitchApplication
{
public partial class <ChangeThisToYourClassName>
{
private TransactionScope tx;
partial void SaveChanges_Executed()
{
tx.Complete();
}
partial void SaveChanges_Executing()
{
tx = new TransactionScope(TransactionScopeOption.Required,
new TransactionOptions {
IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted
});
}
}
}
Help me solve next problem.
I have ASP .NET MVC2 application. I run it on IIS 7.5. In one page user clicks button and handler for this button sends request to server (jquery.ajax). At server action in controller starts new thread (it makes long time import):
var thread = new Thread(RefreshCitiesInDatabase);
thread.Start();
State of import is available in static variable. New thread changes value of variable in the begin of work.
User can check state of import too with the help of this variable, which is used in view. And user sees import's state.
When I start this function few minutes everything is okey. On page I see right state of import, quantity of imported records is changed, I see changes in logs. But after few minutes begin troubles.
When I refresh page with import state sometimes I see that import is okey but sometimes I see page with default values about import (like application is just started), but after that again I can see page with normal import's state.
I tried to attach Visual Studio to IIS process and debug application. But when request comes to controller sometimes static variables have right values and sometimes they have default values (static int has 0, static string has "" etc.).
Tell me what I do wrong. May be I must start additional thread in other way?
Thanks in advance,
Dmitry
I add parts of code:
Controller:
public class ImportCitiesController : Controller
{
[Dependency]
public SaveCities SaveCities { get; set; }
//Start import
public JsonResult StartCitiesImport()
{
//Methos in core dll, which makes import
SaveCities.StartCitiesSaving();
return Json("ok");
}
//Get Information about import
public ActionResult GetImportState()
{
var model = new ImportCityStatusModel
{ NowImportProcessing = SaveCities.CitiesSaving };
return View(model);
}
}
Class in Core:
public class SaveCities
{
// Property equals true, when program are saving to database
public static bool CitiesSaving = false;
public void StartCitiesSaving()
{
var thread = new Thread(RefreshCitiesInDatabase);
thread.Start();
}
private static void RefreshCitiesInDatabase()
{
CitiesSaving = true;
//Processing......
CitiesSaving = false;
}
}
UPDATE
I think, I found problem, but still I don't know how solve it. My IIS uses application pool with parameter "Maximum Worker Processes" = 10. And all tasks in application are handled by few processes. And my request to controll about import's state always is handled by different processes. And they have different static variables. I guess it is right way for solving.
But I don't know how merge all static values in one place.
Without looking at the code, here are the obvious question. Are you sure your access is thread safe (that is do you properly use lock to update you value or even access it => C# thread safety with get/set) ?
A code sample could be nice.
thanks for the code, it seem that CitiesSaving is not locked properly before read/write you should hide the instance variable behind a property to handle all the locking. Marking this field as volatile could also help (see http://msdn.microsoft.com/en-us/library/aa645755(v=vs.71).aspx )