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.
Related
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.
Lets say I have two .dlls, Dll1 and Dll2.
DLL1 uses or makes calls into DLL2.
Is there a way I can ensure that it is DLL1 and only DLL1 who's making the calls into DLL2?
UPDATE 1
The reason behind this is:
I have a WinForms solution, and to keep it simple, it consists of a view project and a controllers project (which generates a seperate .dll). After installing the application on a client machine, I realise it is possible to view the application .dlls in it's "Program Files" folder. Somebody could potentially add a reference to the controller's .dll. I'd like to avoid this so that it's the view project and only the view project who's making the calls.
UPDATE 2
One of the reasons I like separating controllers into a separate project is that I could potentially have many different view projects calling into and using the same controllers. I then would only need to maintain one controller project for all views. For instance a win forms application and a test project or even a web site using the same controller project. But taking this approach , I would then be faced with the security problem I mention (avoiding and controlling improper use of my dll).
So I have one approach, compiling to one .dll, by using different folders, which I believe is correct and solves my security problem, but it conditions me to only having one view.
On the other hand if I have separate projects I am faced with the security issue.
I am still dubious as to how I should go about this as I would still like to continue using different projects for the reasons I mention.
UPDATE 3
Any suggestions on using the StrongNameIdentityPermission permission demand?
http://msdn.microsoft.com/en-us/library/ff648663.aspx (see: Restrict Which Code Can Call Your Code)
http://blogs.msmvps.com/manoj/2004/10/20/tip-strongnameidentitypermission/ http://www.morganskinner.com/Articles/StrongNameIdentityPermission/
Thanks
You can make all types in DLL2 internal and use InternalsVisibleToAttribute in it set to DLL1.
To ensure that this will not be subverted, you should sign DLL1 and make sure you use its public key in the attribute.
Alternatively, as the author of both DLLs, consider combining the projects into one - set all the public methods that exist in DLL2 to internal, as before, but now only DLL1 exists and they can only be accessed by it.
Note: All the above assumes no reflection is used.
You can using Reflection to check the current callstack. Said that I probably wouldn't do it as it's costly and slow.
You can get the stacktrace this way:
using System.Diagnostics;
// get call stack
StackTrace stackTrace = new StackTrace();
// get calling method name
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);
You could merge the output into a single exe with ILMerge
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)
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.
I want to know if its possible and how to do the following , i have a basic MVC application (ASP.Net) that i have modified to work for me. Now the application already handles authentication perfectly fine but i need to use this authentication in another app.
Without creating a webservice is it possible for me to make calls to the applications authcontroller , if so how
You can't directly call a controller in another application because it is in a separate AppDomain. If you just want to reuse the existing code, you could refactor it into a separate assembly (library project), include that assembly in your new application, and just reference it from your logon controller. If you are trying to do single-sign on, then you may want to look at existing SSO solutions, such as JA-SIG CAS 2.0.
Authentication is a cross-cutting concern that shouldn't be embedded into a single use case/controller. AOP afficionados would say it should be encapsulated in an aspect.
Whoa guys slow down , im still beginning MVC and all its related details , the single sign on looks promising , the reason i dont want to go that route yet or even refactor the code and include it in the second project is because its way too simple a project.