I am writing a ASP.NET ApiController that is hosted on IIS. In an action I need to invoke a Web Service named A provided by a company named Tencent. The service requires that I use a key to authenticate. The key is generate by calling another web interface, named B from Tencent and key is valid for 3 hours. Service B has a limitation on calls per day. Therefore I can't call B whenever I want to use A. I can only call B once and store the key in the database for future use.
That means every time I want to use Service A, I need to check the validation of key from database, and if it's expired, call B and get a new one.
Now, when I need to renew my key by calling B, what if before a new key is returned, the ApiController action is called again? The new request would also find that the key in database is stale, then goes on calling B again, invalidating A's newly gained key, causing A to fetch key again, endless loop.
My questions is, how do you get rid of this kind of worry? How do I start? From SQL or IIS or ASP.NET?
I am reading/writing database with EF6 and using ASP.NET MVC 5.
Thanks for your help!
-- Complement --
I was advised to use lock keyword. However I want to have a peace of mind knowing that lock will safe guard the database read/write piece across all IIS requests. So is there any article about how IIS handles multiple requests to the same ASP.NET module and concurrency control on that?
Use a lock around the code in question. The lock keyword ensures that one thread does not enter a critical section of code while another thread is in the critical section. If another thread tries to enter a locked code, it will wait, block, until the object is released.
See https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx
If it’s in a clustered environment they you will also need to create a transaction at the database level, which will check the last updated/expiry before performing an update.
Related
I have a web application that checks the user accounts from the database to determine their source. I want to make sure that the thread that goes to check the database runs first without any scheduling algorithm of WebSphere server.
More Clarification:
Even if I define the method at first it takes time to gather all information so I want to make sure that the thread completes getting all the information from the database and proceed to other threads in the server.
Have you tried using javax.servlet.ServletContexetListener.contextInitialized ?
Note that the JavaDoc states "All ServletContextListeners are notified of context initialization before any filters or servlets in the web application are initialized."
I am in a situation where requirement is to keep an application level object in web api which can be accessed by all requests. I know one can use HttpContext.Current but that is not required since HttpContext is only for the liftime of request. I need a solution where i can keep an object that all requests can access and update as required.
Use a static class to hold your application level objects. static classes and static data members are created once for the application lifetime and all ASP.NET requests can access them.
I learnt it the hard way. Some time back, I mistakenly created a static field to hold customer-specific database connection string, in a ASP.NET Web API project and it became a mess. On each customer's login it was being set (overridden) in the code and the requests from the previously logged customers were using this newly set static SQL connection string for their queries. It was an embarrassing situation when customer's inadvertently saw each other's data.
You could use SessionState (per session).
I.e.
Session["YourDataKey"] = ApplicationLevelObject;
And then check the session state variable on each request that requires it.
However if you require the object for longer, I.e. every single user session, then I would suggest persisting your object to a database. You could use an ORM such as Entity Framework.
Cheers
I have a requirement where third party software running on a desktop will write to a local database and I need to send some of that information to a remote web service. I don't have any control over the thirdparty software that is doing the insert but I can read the database.
My approach is to have a windows service check the local table every second for an insert, if there is an insert send the webservice request. I don't like checking every second but this whole process needs to happen in a short amount of time after the insert. Is there a better way to go about this? Some kind of listener? I don't think I can use triggers.
This will be .NET and SQL Server if that matters.
Try using the SQLDependency class. Implement the onChange method of the class to handle your processing. The following article describes the process of configuring your environment and has some sample code for this.
http://www.codeproject.com/Articles/144344/Query-Notification-using-SqlDependency-and-SqlCach
I've created web application that has a sub that builds a contacts list. This sub fetches phone numbers and email address from a contacts db based on ids that are provided by a user. At it's fastest, the application will process about four ids per second. With 200-300 ids at any given time, the completion time is long.
Time is not really the problem, it's end user status updates. I've created a very crude web service that reads the "CurrentRecordNumber" that is stored in a session variable as the app loops through the ids. I intend to use javascript to call the webmethod from the app periodically to update status.
My problem is that when debugging, the webmethod call will complete successfully, but not until the app is finished processing.
This seems like a very simple problem. I must not be using the right terms because my results seem overly complicated.
I'm very new to asynchronous features of ASP.NET so please forgive. I have, however, written some Winforms that incorporate multiple threads so I have a basic understanding of threading.
This is due to the way ASP.NET treats session. You haven't said whether you are using webforms or MVC, but MVC has a quick workaround for this.
First, the problem:
SessionState is designed to be accessed by one request at a time, in the order received by the server. Think of this as a queue at the bank with only one bank teller available. The first person in line is the first to be helped (though this is on a per-session basis, not a per-user).
ASP.NET locks all other requests that require SessionState from executing until the previous one is done.
I haven't tried to correct this problem in web forms, but the easiest way I know of would be to not require SessionState on your progress check.
In MVC, there's a SessionState attribute that can be applied to the controller or method, indicating that there's no chance of a call to that method overwriting SessionState. As long as your call is read-only, you can make your controller code use this attribute to allow multiple async requests simultaneously:
<SessionState(SessionStateBehavior.ReadOnly)>
Public Class MyController
I have a program in which it insert a raw in a table after certain operations. I wan to call a web service in code behind to do some special tasks by the using of info that there is in the inserted row.
How I can do that?
Is it good idea to invoke this web service from a stored procedure or not? What are the other options?
More Details: Actually, I have an operation in my web application that take a long time to be completed and it is seriously time consuming operation. I don't want client wait until this process finish. That is why I decide write a web service to do this process in the background.
Therefore, I think it may be a good idea that when client request receive I insert his request in a table and call a web service to handle it. Moreover, I do not want to wait until web service return the result, so I will aware client from its result through the report. I do not know what is the best solution to handle it.
I usually keep myself far away from table triggers(it sounds like you're about to use an on insert trigger for a table).
I don't know your specific situation but you could either :
Call the webservice before or after you call the stored procedure, this way the data layer(stored proc) only handles data and nothing more. You're logical layer will handle the logic of calling an extra webservice.
Write a service that will periodicly read a table and notify the webservice of the latest modifications. More messy but it resembles more the effect you're trying to achieve.
There are probably more solutions but i'd need more information on what it exactly is you're doing. Right now it's kinda vague :)
It is never a good idea to call webservice from Stored procs or other DB objects. You can call it from your code, just after you execute the insert and commit it.
The problem it sounds like is that you cannot guarantee that the web service will be called unless you call it before committing the transaction. However, it sounds like the web service needs to be called after commit. In this case, it sounds like you should use a message queue. You could either build one in your database or you could use one off the shelf (http://aws.amazon.com/sqs/ or http://www.windowsazure.com/en-us/home/features/messaging/).
The steps would be:
Insert message into queue (after this is success you can return the call, depending on what your contract with the caller is)
Read message
Insert into table
Call web service
Delete message
The downside is that you will need to make the operations (inserting into the table and calling the web service) idempotent.