Access current request headers from inside a dll function - c#

I think this should be fairly simple but I can't find anything on google on this for some reason
I have a WebAPi 2.0 controller (type:ApiController) that can read the read the request headers
Request.Headers.GetValues("SomeHeader");
In the same project I have another class (AccessFactory) that I would like to access the headers from.
Reason being that I would not want to do the same code for every function call to read all the needed headers at the point where they are actually needed.

Within a separate project / DLL you can still get access to the current HTTP context (and thus the request headers) using the System.Web.HttpContext.Current object.
As an aside, I would add that if this DLL is meant to be re-usable across different applications, then consider whether it will be used on non-web applications, and if so you should avoid making dependencies on a web-based context like this. Instead you might consider passing in the header values you need as simple types, or in a custom object. That way they can indicate the context, but a non-web app could pass in equivalent contextual values of its own. But that's a separate design decision depending on the exact purpose and how you intend to use this DLL library in future.

Related

get information on an assembly

I want to get information on an Assembly in my C# application. I use the following:
Assembly.GetCallingAssembly();
This works perfectly returning information on the calling Assembly.
I want to share this functionality with other applications, so I include this in a class in my class library.
I reference this class library in multiple applications. When I make a call to this method from my applications, it returns information on the class library and not the application. Is there a way I can alter my above code to return information on the web applications assembly while still having the code included in the class library?
Instead of having the class library being intelligent why don't you have the caller pass an Assembly as argument to the method? So when you call the method from within some application you would pass Assembly.GetExecutingAssembly() and the method within the class library will now be able to fetch the assembly of the actual caller.
I'm not sure what you provide on top of reflections, but maybe you're abstracting a facility that doesn't need to be abstracted. Reflections already handles this, so why not let it do its job?
But if this API gives you back some useful information (such as plugging nicely into your database, etc), then maybe your approach makes some sense. But I still recommend that you refactor it:
Put this code in only one shared project/assembly, and just link that project/assembly when you need to call that functionality. Needing to duplicate code to get your job done is considered code smell.
Take an Assembly object as a parameter, rather than trying to determine the current assembly. This will allow more flexibility in case you come up with some code that wants to get data on a bunch of other assemblies, and will still allow you to pass the current assembly. (Note: Darin already made this point)

Access ASP.NET MVC paths from outside the hosting environment

Background:
I have a ASP.NET MVC3 app, with a database. I also have a complex console app, which (amongst other things) initialises the web app's database: generate, add constraints, add sprocs, add triggers, seed, etc. I cannot move the console logic into the web app (doesn't make sense in our architecture).
Problem:
The console app is obviously not running in a hosted environment, so does not have access to HostingEnvironment, MapPath, HttpContext.Current, Server.MapPath, ~, etc. But I need access to the web app's paths from the console app. Also, the console app calls into the web app, which then uses these classes normally, but which are of course all null or undefined.
Question:
Is there some way to spoof one of these classes so that I can access the hosting environment's path mechanism, even though it's not running?
I can hardcode all the paths I need into the console app, but that is highly undesirable.
I'm under the impression that this should be possible, because the same need would be required for unit testing.
TIA
Write a small web service and expose the desired data from the web app, then just call it from the console app
What I've done (though I don't really like it):
Instead of scattering various paths around the web app, we have a single static Paths class, which contains private static readonly strings for every major resource path in the system (paths that T4MVC doesn't help us with). Whenever I need a path to anything, I ask that class, and it performs the necessary Path.Combine() etc. on the strings within -- so the result is that all hardcoded strings are present in one clean and easy to maintain class.
So I added a property public static string ApplicationRootPath { get; } to that class (note the public, and lack of readonly), and a static constructor which initialises it to ApplicationRootPath = HostingEnvironment.MapPath("~"); or "/" depending on your use case.
Then, from the console app, I can override that "root" directory by Paths.ApplicationRootPath = "some absolute or relative path here";. After that single line, I can then access all the paths in the web app, which work.
Actually it's quite neat, but still not ideal. I'll accept this as the answer unless someone has a better idea.
Moq is great for mocking the MVC3 contexts that you require. It's fairly easy to setup and you can override the methods and properties that would usually run under a web context to return the objects you desire.
Rather than attempting to explain further, start here:
How do I mock the HttpContext in ASP.NET MVC using Moq?
MVC 3 Unit Test - Get Actual Response Data
http://www.sharpedgesoftware.com/Blog/2011/03/14/mocking-a-controllercontext-with-authenticated-user-with-moq-for-aspnet-mvc-3
http://code.google.com/p/moq/
You could try out a StructureMap (or some other IoC framework) for this to work.
In a project I'm currently working on we've wired the HttpContextBase to the HttpContext.Current object in a website.
This way we can use the HttpContext features within any environment.
For our unit-tests we're using some stub/mock object which overrice from the HttpContextBase. Most of the objects you want to use got an interface or base class you can use to set up the wiring.
For mocking the .NET Framework you could try out Pex & Moles. It should be able to do such, or so I'm told. Haven't used that myself, but it looks pretty neat!
Got a few of these floating around. In most cases you really just need 1 or 2 configuration values then you can calculate your paths pretty effectively. Value #1 is the root of the web application -- from there you can easily build out a url to any resource. Value #2 is the physical location of the web app if that in fact matters in this context.

How to determine which page opened a class in another project?

I use a separate project for my data layer and call one class within it clsData.cs. I'd like to know which page from the Presentation Layer (in another project within the solution) has referenced it from the clsData side, if that's possible
Use a dedicated library like log4net, or use new StackTrace().GetFrames(), to get a reference to the current stack; that holds all the information you need, including page, method, line numbers etc.
You might want to handle the Application_Error method in your global.asax; as all uncaught exception will route to that method.
Why can't you keep the public properties inside your data access layer,which you can set from the calling class for the logging purpose?
May be you need to first understand the reason behind why you created layers in application. As far as my understanding you want to know what exactly caused a particular error. For that may be you need to think about a different solution instead of logging error in your data layer by accessing the information about the caller.
If we take a case of using the same data layer project in some other solution in different UI layer or may be a console application then would you prefer rewriting the entire data layer again to support logging who is calling your data layer class?
Whenever you make a class library (data layer) I would suggest you do the error logging related to error/exception in that scope only, and throw the error/exception as is to the caller so that the caller can get the correct idea on what happened and caller can take necessary steps.
I'm not sure what your requirement is but it is always advisable to throw the exception to the caller and log at the caller end.

Can I use ASP.NET Session[] variable in an external DLL

I have two projects, the DLL project which has all my logic and data access stuff, and the ASP.NET project which does my forms etc.
I am a bit confused. I thought if I added the System.Web namespace reference to the DLL project I would be able to reference the Session state information of the ASP.NET page.
I could use each page to get the session info out and pass it to the DLL for the processing but would love to be able to process things directly from the DLL class(s).
Is this possible?
I have fiddled with the System.Web namespace and just seem able to get a reference to the Session variable.
Thanks all.
Jon
As long as the Assembly is loaded in the scope of the Session, it will have access.
Although this type of tight coupling isn't really recommended.
You should be able to use HttpContext.Current.Session
Edit
While yes I agree you should not tightly couple your Business Logic DAL or etc assemblies to ASP.Net session. There are plenty of valid cases for accessing HTTP Context outside of a web project.
Web Controls is probably one of the best examples, reusable HTTP modules, etc..
Now one option, if you want to have your DLL pull the stuff from Session, is to abstract out session. So you could define an interface like IStorage, that your library will know how to use. Then you can have a SessionStorage or MemoryStorage class and use IoC to inject the appropriate class into your library classes. This gives you the freedom to code it how you wanted it to be coded without tying your code to Session. Oh and one other benefit if done properly can be used to not tie your code to the session on the web either.
You can always use HttpContext.Current.Session in your DLL but this is considered as bad practice. A better approach would be to pass the values stored in the session dictionary to your DLL instead of it referencing the session. Another benefit you will gain is that the code in your DLL won't be coupled to the ASP.NET runtime meaning it will be easier to test.
As said by the others, you can always use HttpContext.Current.Session in your DLL, I assume it's your BAL, but you need to be really carefull. What if your DLL is later consumed by a windows service, or some other app that doesn't have an HTTPContext? Whenever I've done this it's always been in a property get method where I wrap the attempt to access HttpContext.Current.Session in a try catch block and if anything goes wrong I repull the needed data from the db.
Do not use HttpContext.Current.Session as your dll will not run always with the Web Application. It may run with any other application like Windows,Console itc.
It is better to use a Method which is actully accept a parameter, which will come form Session Value, if you are using ASP.Net Application, otherwise there will not be any dependency of the application. If your dll project already developed and you are trying to modify the exsiting business logic then no, dont modify your exsiting method, use an Overload method.

ASP.NET Web Service Results, Proxy Classes and Type Conversion

I'm still new to the ASP.NET world, so I could be way off base here, but so far this is to the best of my (limited) knowledge!
Let's say I have a standard business object "Contact" in the Business namespace. I write a Web Service to retrieve a Contact's info from a database and return it. I then write a client application to request said details.
Now, I also then create a utility method that takes a "Contact" and does some magic with it, like Utils.BuyContactNewHat() say. Which of course takes the Contact of type Business.Contact.
I then go back to my client application and want to utilise the BuyContactNewHat method, so I add a reference to my Utils namespace and there it is. However, a problem arises with:
Contact c = MyWebService.GetContact("Rob);
Utils.BuyContactNewHat(c); // << Error Here
Since the return type of GetContact is of MyWebService.Contact and not Business.Contact as expected. I understand why this is because when accessing a web service, you are actually programming against the proxy class generated by the WSDL.
So, is there an "easier" way to deal with this type of mismatch? I was considering perhaps trying to create a generic converter class that uses reflection to ensure two objects have the same structure than simply transferring the values across from one to the other.
You are on the right track. To get the data from the proxy object back into one of your own objects, you have to do left-hand-right-hand code. i.e. copy property values. I'll bet you that there is already a generic method out there that uses reflection.
Some people will use something other than a web service (.net remoting) if they just want to get a business object across the wire. Or they'll use binary serialization. I'm guessing you are using the web service for a reason, so you'll have to do property copying.
You don't actually have to use the generated class that the WSDL gives you. If you take a look at the code that it generates, it's just making calls into some .NET framework classes to submit SOAP requests. In the past I have copied that code into a normal .cs file and edited it. Although I haven't tried this specifically, I see no reason why you couldn't drop the proxy class definition and use the original class to receive the results of the SOAP call. It must already be doing reflection under the hood, it seems a shame to do it twice.
I would recommend that you look at writing a Schema Importer Extension, which you can use to control proxy code generation. This approach can be used to (gracefully) resolve your problem without kludges (such as copying around objects from one namespace to another, or modifying the proxy generated reference.cs class only to have it replaced the next time you update the web reference).
Here's a (very) good tutorial on the subject:
http://www.microsoft.com/belux/msdn/nl/community/columns/jdruyts/wsproxy.mspx

Categories

Resources