How are Static Variables shared in a Web Session - c#

I have an mvc webapi service setup that pulls and pushes data from an sql server database.
Within the Web project holding the webapi I have a Static class that just holds some global variables that are accessed from the webapi methods. Following is a very cutdown example of the static class:
public static class SystemProperties
{
public static int currentContactID;
}
When the WebApi is accessed I strip the ContactID from the Http Headers of the call and set the SystemProperties.CurrentContactID to it.
Than in the methods of the webapi I access SystemProperties.CurrentContactID for data calls.
I have found a problem when there is concurrent webapi calls the currentContactID is getting mixed up.
My question is, how is the static class members shared between calling sessions? Is it going to be pretty much last in best dressed and if the previous person is still in there than they will get screwed over by the new person who will overwrite the variables with their details?
Should I be using a different method to store these details?
Thanks in advance

You can use the Current HttpContext to store items to use across the lifetime of an HttpRequest
HttpContext.Current.Items["currentContactID"] = value
So you can grab the data from the Request header, and store it here and it will be available for the duration of the current http web request for that user. Every http request has its own Items dictionary so it won't be overwritten by simultaneous requests
If you need to store a variable across several requests for the same user you need to look into cookies or sessions.

Yes, you should be using different method.
With Web API the request comes in as HttpRequestMessage. You can implement a HTTP message handler (inheriting from DelegatingHandler) and from there strip the CurrentContactID from HTTP Headers. You can also take your CurrentContactID value you've stripped out and add it to the HttpRequestMessage objects Properties dictionary.
Here's article on implementing HTTP message handler: http://www.asp.net/web-api/overview/working-with-http/http-message-handlers
Here's article on the Properties property of HttpRequestMessage: http://msdn.microsoft.com/en-us/library/system.net.http.httprequestmessage.properties.aspx
Keep in mind that the Properties property on HttpRequestMessage is available to you at controller as well which is why it is suitable for use in lieu of static class or session.

Related

How to properly make a call to a Web API

In the ASP .NET website they have an example of how to call a Web API from a .NET Client.
They have this method to make a call which creates a new Product:
static async Task<Uri> CreateProductAsync(Product product)
{
HttpResponseMessage response = await client.PostAsJsonAsync("api/products", product);
response.EnsureSuccessStatusCode();
// Return the URI of the created resource.
return response.Headers.Location;
}
This is like the usual way to make any call to any API in any language or framework, but I see a lot of problems in this line:
HttpResponseMessage response = await client.PostAsJsonAsync("api/products", product);
If the "path" parameter is a string, there is no way to detect possible errors in compilation time. Besides, if the API changes and we have a lot of calls, there is no way to rebuild the calls quickly.
Is there a better way to build the call to avoid this kind of problems? I mean, like we do with Web Services, for instance.
Like Nkosi mentioned, that is how it is designed. However you could create a class with the API URI's and use those instead of literals
public class ApiUris
{
public const string Products = "api/products";
public const string Services = "api/services";
public const string Orders = "api/orders";
/* ... */
}
That way you can easily change the path if your webapi changes.
Even Web Service and WCF service does not gurantee build fail if the server changes the URL or type and/or structure of the parameter. You come to know about the changes only when you call the service and it breaks.
In case of calling Web APIs surely there is no way you can figure out that the URL or the paramemeter is incorrect until you call the API.
At the same time, Web API are not built to be changed frequently. If they are not reliable no one would use them. So if you are using an API you can be sure that they will not change their URL or stop supporting certain input parameters overnight making their consumer applications like yours break. They surely woudn't want to be sued by their customers.
Any API would change gradually and with well advanced notice to their customers so that they get time to change their implementation to support new version of API.
So you can rely on the service which you are using and puting values related to it (such as URLs) in the config file would be good enough. Or you can choose to put API Urls in database so that when it changes you just need to update entry in the database and changes will be effective immediately.
Just extending upon Adam's solution you can get a List of your routes using
System.Web.Routing.RouteTable.Routes.ToList();
Then getting the path depends on the concrete implementation of the RouteBase abstract class.

Is HttpContext.Current.Items thread-safe between Requests?

Suppose one has an HttpHandler that processes each request, and suppose each HttpHandler computes an intermediate result for each request and potentially wants to pass this to a page handler eg via Server.Transfer or Server.Execute via the HttpContext.Items collection
Will each request have a separate copy of HttpContext.Items["sameKey"] when they each reach the same .aspx page?
My concern arises from the fact HttpContext.Current is itself a static property
HttpContext Encapsulates all HTTP-specific information about an individual HTTP
request.
Hence each request HttpContext.Items["sameKey"] will be a different copy.
HttpContext.Items is stateless the only way to "share" between requests is Session or higher level state (database)

What's the differences between HttpContext.Current.Items[] and HttpContext.Current.Request[]?

I really can't find out what is really the differences between these two methods in C#/.NET.
In fact they should do the same actions!
The first contains a safe read/write storage location that could be used throughtout the entire HTTP request. You could use it for example to store some object in the Begin_Request method and it will be available up until the page renders. It's like a Session but that lives only for the lifetime of a single HTTP request. You can access it from everywhere during during this request and it is specific to the context of the current request only.
The second is readonly storage for query string, POSTed form parameters, server variables and cookies.
Items is a NameValueCollection useful for storing and sharing data for the life of the HTTP Request. The Request meanwhile provides access and methods specific to the HTTP Request. Neither are methods however.

Global variables in WCF REST services

My applciation works as follows
[user]----username/password/domain----->[WCF service]
then i access the domain server to see to which actual DB the user is associated,
after getting that, i validate the user in his actual DB(DB is per domain)
the problem is that i need a place to store the domain name for the following requests against the db.
for example,if the users calls a WCF service operation:
Test()
first the validation procedure is called, (WCF UserNamePasswordValidator) which validates the user password(which is sent as part of the header for REST or as part of the SOAP), and the next function to be called is the Test, but by then i cant tell the domain of the user(to actually serve the request agains that domain..)
I dont want to change the signature of each domain to
Test(string domain)
I cant simply access the headers since i expose the same methods both as REST and as SOAP and the authentication is different for each of them..(one is with headers as with Amazon S3 and the later is using the SOAP standard)
so basically i'm looking for a global, per call storage.(i want to avoid the Per-Call initiation method)
thanks.
EDIT:
Maybe i should use the ThreadStaticAttribute? will that work?
This will not work. You can't store anything in UserNamePasswordValidator. It even doesn't have access to OperationContext because it runs on different thread.
The way to do this is create custom message inspector and extract the information from custom message header to custom operation context extension as Frank mentioned.
WCF knows a Current OperationContext. You can write your own extensions for it. Unrelated to this issue, I used the same mechanics in this NHibernate Session management here, which may work in its concept for you as well. It accesses the InstanceContext, but the concepts are similar.

Is there a way to access a cache or session from a static method?

How would you access the cache from a jQuery ajax call?
I'm using jquery to do some data verification and quick data access. I have a static web-method that jquery is calling via json to return a value. I don't want to call to the database everytime so I'd like to cache the data I'm hitting, but I can't determine how to call the asp.net cache from within javascript, or a static method.
I'd like to send the page object through to the static method, which would allow me to access page.cache, but don't know how. Barring that, maybe a way to access the cache from javascript itself?
System.Web.HttpContext.Current.Cache
Cache is shared per app domain - not per Page. Page just has a convenience property of Page.Cache to get the current Cache, which means you can just do Cache["key"] from a method in a page.
As you've noticed, if you're in a static method - then you have no Page instance, and you have no Page.Cache property. So, you need to use HttpContext.Cache. But, wait - you have no HttpContext instance either! That's ok, the currently executing instance is stored at the static property of HttpContext.Current.
So - to answer your question - in a static method, use HttpContext.Current.Cache. BTW, you can also access the Request and Response properties from there.
I think calling a PageMethod may be the best you can really do, if you really want to do this:
http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-ajax-page-methods/
Javascript is client side, the Cache is on the Server Side, so you need to do a callback to a method in your asp.net application, that returns the content of the cache.
The ASP.NET Cache API is really good, you can use Cache["Key"] to get the cached content that you like. Read more here : http://msdn.microsoft.com/en-us/library/ms972379.aspx

Categories

Resources