Cannot access text file in ASP.Net MVC 3 test project - asp.net-mvc-3

I am trying to access a text file in asp.net mvc3 test project, the common way I know to access it is through HttpContext class like this
HttpContext.Current.Server.MapPath("Temp.txt");
But it returns "Current" as null!
After a little search I found few reasons of Current being null, in my case it is I guess using a router handler to route requests.
But not getting the way to do it for my case.
Can anyone help me on that?

HttpContext is not available on test context, only on web enviroment. You need an HttpContext stub. Avoid this direct dependence.
http://vkreynin.wordpress.com/2009/03/23/stub-htttpcontext/

Related

Session object not available in WebAPI

I've got a webAPI that uses Entity Framework. I'm trying to cache some data in the session variable following along in this article:
https://msdn.microsoft.com/en-us/library/system.web.httpcontext.session(v=vs.110).aspx
I can't seem to do it though. The Session object isn't available.
In my controller, I try this:
Session["mappings"] = mappings;
...but it doesn't recognize what Session is.
I also try this:
HttpContext.Current.Session["mappings"] = mappings;
...and this:
Page.Session["mappings"] = mappings;
...but it doesn't know what HttpContext or Page are.
I'm including System.Web in my project references. I'm also including this in my web.config:
...just like this article says:
https://msdn.microsoft.com/en-us/library/ms178581(v=vs.110).aspx
...but to no avail.
My work colleague suggests it's because our webAPI is RESTful which means it's stateless, so no session object. However, we know there are ways around this. What I need is simply some way of persisting data in some kind of cache that will survive across several requests.
I also need something that will be available inside EF entities (not just the webAPI controller) is that's possible.
Does anyone know how to solve this problem? Thanks.
As your colleagues correctly suggested, an API is stateless, each request is separate and needs to have all the data required to complete the request.
You can add a caching layer however, but that is not going to be done via the Session object. Session makes no sense in an API.
Have a look here for some ideas: Caching Data in Web API

"Default principal object cannot be set twice" error implementing WEB API with CSLA backend

Can anyone save some of my hair? :)
I'm trying to create an asp.net WEB API interface for an older CSLA (1.x/2.x era) project. I am testing by hard coding the login on every request in various ways (once in the startup code, as an authorization request filter, inside the individual route request etc etc). All the ways I tried work exactly once perfectly and then I get the infamous:
'Default principal object cannot be set twice.'
exception in BusinessPrincipal.vb (yeah I know it's very old, but it's released software, I can't upgrade CSLA)
I know that there is an issue where you need to set HttpContext.Current.User = Thread.CurrentPrincipal; due to some internal workings of the web API and I do that already, that has not resolved the issue.
I'd like to know if anyone has implemented a web api front end and how they handled this issue or any pointers as to what could be the solution.
Worst case scenario if I could at least just login once and keep that same principal without losing it I could implement a second layer of security, that woudld be acceptable, barring anything else is there some way to just login once and not lose that principal?
That BusinessPrincipal class would be in your code base, not in CSLA itself. The Csla.Security namespace does include a BusinessPrincipalBase that is probably the base class for your BusinessPrincipal.
Classes in that namespace are here in GitHub
It is true that you can only call AppDomain.SetPrincipalPolicy one time, but you should be able to set the Thread.CurrentPrincipal and HttpContext.Current.User multiple times.

ASP.NET MVC 3: Purpose of IgnoreRoute("{resource}.axd/{*pathInfo}"); ? deprecated?

Do I even need this rule anymore?
I don't see any requests incoming for resource.axd files (as opposed to when I ran webform applications)
WebResource.axd is an HTTP Handler that is part of the .NET Framework
that does one thing and one thing only – it is tasked with getting an
embedded resource out of a DLL and returning its content. What DLL to
go to and what embedded resource to take are specified through the
querystring. For instance, a request to
www.yoursite.com/WebResource.axd?d=EqSMS…&t=63421… might return a
particular snippet of JavaScript embedded in a particular assembly.
Its still part of the framework and you can still retrieve embedded resources using the above handler. You dont want your route handler to handle such requests and that is why it is ignored. My guess is that you can get rid of it if you are completely sure that your app/libraries that you use dont use it.

ASP.NET MVC 3, RavenDB, & Autofac Issue Plus 2 Other Autofac Questions

NOTE: There are 3 questions in here and I did not make separate questions since they are all somewhat related to the same code.
I have the following code that registers the connection to my RavenDB in the Application_Start once per the application's life cycle:
var store = new DocumentStore { Url = "http://localhost:8080" };
store.Initialize();
builder.RegisterInstance(store).SingleInstance();
Now this works fine and this is something that should be created only once per the application's life cycle. Now I wanted to add in the DocumentSession to Autofac so I tried to add in this in the Application_Start:
var session = store.OpenSession();
builder.RegisterInstance(session).SingleInstance();
In my UserRepository I have the following constructor:
public UserRepository(DocumentStore store, DocumentSession session)
When I try to run this, I get the follow runtime error:
Cannot resolve parameter 'Raven.Client.Document.DocumentSession Session' of constructor 'Void .ctor(Raven.Client.Document.DocumentStore, Raven.Client.Document.DocumentSession)'
That error to me sounds like Autofac does not think it has a DocumentSession however that is what store.OpenSession() returns so it should. Anyone know what would be causing this error? Am I not setting the session variable correctly (it is the same as the store variable which works fine)?
Another thing which may or may not be related to the above issue is how do I add an instance of an object to Autofac per request instead of per the applications life cycle? While the RavenDB DocumentStore object should only be created once be the life application cycle, the DocumentSession should be created once per the request (maybe creating it per application level is causing the error above).
One last question I will throw there about Autofac (mildly related to the code above) is about releasing the objects. If you take a look at this tutorial:
http://codeofrob.com/archive/2010/09/29/ravendb-image-gallery-project-iii-the-application-lifecycle.aspx
The last piece of code:
ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
and the point of this code is to prevent leaking the sessions. Now is this something I also need to worry about for Autofac and if so, how would I do this in Autofac?
I'm guessing you want something like:
builder.Register(c => c.Resolve<DocumentStore>().OpenSession()).InstancePerLifetimeScope();
"The default ASP.NET and WCF integrations are set up so that InstancePerLifetimeScope() will attach a component to the current web request or service method call." - Autofac: InstanceScope
Basically, in a web app, InstancePerLifetimeScope handles the one per HTTP context aspect, and also disposes any types that implement IDisposable.
There was also the issue that OpenSession returns a IDocumentSession instead of a DocumentSession. Changing my class to look for a IDocumentSession along with doing what Jim suggested worked, thanks.

Generating urls from MVC Routes in a Management layer...

So... I have a business object/manager which is going to generate emails.
These emails will contain links to various content on the website... and therefore needs to understand about MVC routing.. or at least how to generate URLs for the website...
However my business object will not have access to a RequestContext etc and the email generation is not necessarily the result of a web request to a website (I have a dispatcher which runs on a background thread which will be generating the emails)
Any ideas how I can generate my urls without having access to a request - and therefore being unable to use URLHelper...
Thoughts?
In order to get at the UrlHelper outside of the controller, you need to feed it and the routing data the HttpContext. Here's an example:
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
HttpContextBase context = new HttpContextWrapper(HttpContext.Current);
UrlHelper helper = = new UrlHelper(new RequestContext(context, RouteTable.Routes.GetRouteData(context)));
I prefer to define schema and make both routing and business logic aware of it. Means different implementations of the same URL schema.
Some reasons why:
Your routing mechanism could change. For example in feature you can switch to url_rewrite module.
Possible issues with load-balanced installation.
You do not need even to try to use URLHelper in undocumented way.
BTW, you can replace HttpRequest from URLHelper easily. We used to use this for unit-testing. For more information just search for unit testing of the HttpContextBase or look at examples in source code of the MvcContrib. This can help to instantiate URL helper and all related stuff in non hosted environment. But I still do not think that this is a good idea.
In ASP.NET MVC5 (and possibly MVC4 - I'm not sure when it was introduced), you can do this more directly using HttpRequest.RequestContext. Eg:
var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);

Resources