Controller other than Home will not pass MvcIntegrationTesting tests - asp.net-mvc

I am using an adaptation of Steve Sanderson's wonderful MVC Integration Testing Framework.
If I take any view in my application and serve it through this framework (which basically creates a 'fake' worker request through HttpRuntime.ProcessRequest()) I can host it within the ASP.NET Runtime in the context of my integration test.
My question is why would any view from the HomeController go nicely through this process but any other controller give a response with
Path 'get' is forbidden
I can move any view to the HomeController and test it without issue. I see no difference (url not withstanding) of the worker request fake between the two calls. I am at a loss!
Stack trace in test output:
ContentControllerTwitterReturnsTheTwitterView :
FailedSystem.NullReferenceException : Object reference not set to an
instance of an object.
Server stack trace: at
website.tests.ContentControllerTwitterTests.b__0(BrowsingSession
session) at
MvcIntegrationTestFramework.Hosting.AppDomainProxy.RunBrowsingSessionInAppDomain(SerializableDelegate`1
script) in AppDomainProxy.cs: line 19 at
System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr
md, Object[] args, Object server, Int32 methodPtr, Boolean
fExecuteInContext, Object[]& outArgs) at
System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage
msg, Int32 methodPtr, Boolean fExecuteInContext)
Exception rethrown at [0]: at
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage
reqMsg, IMessage retMsg) at
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(ref
MessageData msgData, Int32 type) at
MvcIntegrationTestFramework.Hosting.AppDomainProxy.RunBrowsingSessionInAppDomain(SerializableDelegate1
script) at MvcIntegrationTestFramework.Hosting.AppHost.Start(Action1
testScript) in AppHost.cs: line 34 at
website.tests.ContentControllerTwitterTests.ContentControllerTwitterReturnsTheTwitterView()
in HomeControllerTwitterTests.cs: line 25

Problem was naming ... answer is
Do not name your controllers with same name as a folder within solution!
Old fool :)

Related

Generate a URL inside Application_Start()

ASP.NET MVC 5
T4MVC (https://github.com/T4MVC/T4MVC)
ABP (http://aspnetboilerplate.com/)
I know it is possible to use T4MVC to generate a URL based on a specific action using UrlHelper(). See SO and here. However I ultimately need to do this during Application_Start() due to ABP requirements.
So in essence within Application_Start() I have:
//Areas
AreaRegistration.RegisterAllAreas();
//Routes
RouteConfig.RegisterRoutes(RouteTable.Routes);
//Get the URL
var urlHelper = new UrlHelper();
var url = urlHelper.ActionAbsolute(MVC.Home.Index())
however this blows up with the following exception:
'UrlHelper.ActionAbsolute(MVC.Home.Index())' threw an exception of type 'System.NullReferenceException'
Data: {System.Collections.ListDictionaryInternal}
HResult: -2147467261
HelpLink: null
InnerException: null
Message: "Object reference not set to an instance of an object."
Source: "T4MVCExtensions"
StackTrace: " at System.Web.Mvc.T4Extensions.ActionAbsolute(UrlHelper urlHelper, ActionResult result)"
TargetSite: {System.String ActionAbsolute(System.Web.Mvc.UrlHelper, System.Web.Mvc.ActionResult)}
however if I inspect the contents of things (at runtime) they appear to all be populated:
MVC.Home.Index()
{T4MVC_System_Web_Mvc_ActionResult}
Action: "Index"
Controller: "Home"
Protocol: null
RouteValueDictionary: {System.Web.Routing.RouteValueDictionary}
MVC.Home.Index().GetRouteValueDictionary()
{System.Web.Routing.RouteValueDictionary}
Count: 3
Keys: Count = 3
Values: Count = 3
Results View: Expanding the Results View will enumerate the IEnumerable
So can anyone shed any light on why this is blowing up? Or put another way how do I get the absolute url for an action using T4MVC inside Application_Start()?
The common theme between the links you provided were that those calls were made in an action which means that a request has already been materialized. Meaning that a context already exists. At startup there are no requests as yet. That is why you are getting the error.

WebSecurity.InitializeDatabaseConnection method can be called only once

I'm trying Windows Azure to host an MVC4 web application.
I've created a test app, using VS2012 MVC4 internet application template and added a custom Model and Controller to it.
I've published it on Azure and managed to get 'update-database' apply migrations to the Azure Database.
When i try the app locally, but using the Azure SQL database, it works fine.
I can login/register and use my test controller.
When i try the app online, i can use the test controller but login or register links give the following exception:
Server Error in '/' Application.
The "WebSecurity.InitializeDatabaseConnection" method can be called only once.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: The "WebSecurity.InitializeDatabaseConnection" method can be called only once.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[InvalidOperationException: The "WebSecurity.InitializeDatabaseConnection" method can be called only once.]
WebMatrix.WebData.WebSecurity.InitializeMembershipProvider(SimpleMembershipProvider simpleMembership, DatabaseConnectionInfo connect, String userTableName, String userIdColumn, String userNameColumn, Boolean createTables) +123
WebMatrix.WebData.WebSecurity.InitializeProviders(DatabaseConnectionInfo connect, String userTableName, String userIdColumn, String userNameColumn, Boolean autoCreateTables) +51
WebMatrix.WebData.WebSecurity.InitializeDatabaseConnection(String connectionStringName, String userTableName, String userIdColumn, String userNameColumn, Boolean autoCreateTables) +52
MembershipTest2.Filters.SimpleMembershipInitializer..ctor() +193
Do you have any idea where that comes from ?
If i debug (the local version), this method is only called once.
Thanks.
You could try encapsulating the call(s) to that method to ensure it's not called more then once
if (!WebMatrix.WebData.WebSecurity.Initialized)
{
WebSecurity.InitializeDatabaseConnection(...);
}
in my case I had both
(in web.config)
<add key="enableSimpleMembership" value="true" />
and
(in _ViewStart.cshtml)
WebSecurity.InitializeDatabaseConnection("club", "Account", "UserID", "UserName", autoCreateTables: true);
Solution: it seems you cannot have both, so remove one
Does the following SO discussion help you?
Cannot seed Users & Roles
I did find the following article helped me lot to use newer MVC4 & EF together with Simple Membership Provider so if you haven't read it please take a look:
SimpleMembership, Membership Providers, Universal Providers and the new ASP.NET 4.5 Web Forms and ASP.NET MVC 4 templates

ASP.Net MVC, JS injection and System.ArgumentException - Illegal Characters in path

In my ASP.Net MVC application, I use custom error handling.
I want to perform custom actions for each error case I meet in my application.
So I override Application_Error, get the Server.GetLastError();
and do my business depending on the exception, the current user, the current URL (the application runs on many domains), the user IP, and many others.
Obviousely, the application is often the target of hackers.
In almost all the case it's not a problem to detect and manage it, but for some JS URL attacks, my error handling does not perform what I want it to do.
Ex (from logs) :
http://localhost:1809/Scripts/]||!o.support.htmlSerialize&&[1
When I got such an URL, an exception is raised when accessing the ConnectionStrings section in the web.config, and I can't even redirect to another URL.
It leads to a "System.ArgumentException - Illegal Characters in path, etc."
The screenshot below shows the problem :
http://screencast.com/t/Y2I1YWU4
An obvious solution is to write a HTTP module to filter the urls before they reach my application, but I'd like to avoid it because :
I like having the whole security being managed in one place (in the Application_Error() method)
In the module I cannot access the whole data I have in the application itself (application specific data I don't want to debate here)
Questions :
Did you meet this problem ?
How did you manage it ?
Thanks for you suggestions,
Mose
PS : here is the stack trace :
System.ArgumentException: Illegal characters in path.
at System.IO.Path.CheckInvalidPathChars(String path)
at System.IO.Path.Combine(String path1, String path2)
at System.Web.Configuration.UserMapPath.GetPhysicalPathForPath(String path, VirtualDirectoryMapping mapping)
at System.Web.Configuration.UserMapPath.GetPathConfigFilename(String siteID, VirtualPath path, String& directory, String& baseName)
at System.Web.Configuration.UserMapPath.MapPath(String siteID, String path)
at System.Web.Hosting.HostingEnvironment.MapPathActual(VirtualPath virtualPath, Boolean permitNull)
at System.Web.Hosting.HostingEnvironment.MapPathInternal(VirtualPath virtualPath, Boolean permitNull)
at System.Web.CachedPathData.GetPhysicalPath(VirtualPath virtualPath)
at System.Web.CachedPathData.GetConfigPathData(String configPath)
at System.Web.CachedPathData.GetVirtualPathData(VirtualPath virtualPath, Boolean permitPathsOutsideApp)
at System.Web.HttpContext.GetFilePathData()
at System.Web.HttpContext.GetConfigurationPathData()
at System.Web.Configuration.RuntimeConfig.GetConfig(HttpContext context)
at System.Web.HttpContext.get_ImpersonationToken()
at System.Web.ClientImpersonationContext.Start(HttpContext context, Boolean throwOnError)
at System.Web.HttpApplication.ThreadContext.Enter(Boolean setImpersonationContext)
at System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationContext)
at System.Web.HttpApplication.ApplicationStepManager.ResumeSteps(Exception error)

2 asp.net mvc sites conflicting with each other

i have deployed an asp.net mvc site a few days ago and everything is going fine. I just deployed a second website (totally unrelated)
i just went to the first website and i am now getting an error below. Can anyone help me determine what is going on. I dont understand why they would know anything about each other.
The controller name 'Home' is ambiguous between the following types:
Site.netmvc.Controllers.HomeController
SalemGolf.Controllers.HomeController
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: The controller name 'Home' is ambiguous between the following types:
Site.netmvc.Controllers.HomeController
SalemGolf.Controllers.HomeController
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[InvalidOperationException: The controller name 'Home' is ambiguous between the following types:
Site.netmvc.Controllers.HomeController
SalemGolf.Controllers.HomeController]
System.Web.Mvc.DefaultControllerFactory.GetControllerTypeWithinNamespaces(String controllerName, HashSet`1 namespaces) +417
System.Web.Mvc.DefaultControllerFactory.GetControllerType(String controllerName) +286
System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +57
System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase h
Make sure you don't have the assembly of the other site in your Bin directory.

ASP.NET MVC / Castle Windsor / IIS6 / Modified MapRoute {controller}.aspx

I've written a web application with ASP.NET MVC. The default ControllerFactory has been replaced with Castle Windsor's Controller
ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory());
The problem is that I'm using shared hosting which runs II6 so in order to get the MVC working I've had to replace the default MapRoute with
routes.MapRoute(
"Default",
"{controller}.aspx/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
[ NOTE THE: {controller}.aspx ]
When I upload a newly created "ASP.NET MVC Web Application" with this modified MapRoute it works fine ... but when I upload my MVC Web Application (that uses the Castle Windsor)
I get the following error in my browser:
URL[ http://10.0.0.9/LoseOnlyToday/Home.aspx ]
Server Error in '/LoseOnlyToday' Application.
The IControllerFactory 'WebUI.WindsorControllerFactory' did not return a controller for a controller named 'Home.aspx'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: The IControllerFactory 'WebUI.WindsorControllerFactory' did not return a controller for a controller named 'Home.aspx'.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[InvalidOperationException: The IControllerFactory 'WebUI.WindsorControllerFactory' did not return a controller for a controller named 'Home.aspx'.]
System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext) +304
System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext httpContext) +54
System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext) +7
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75
Version Information: Microsoft .NET Framework Version:2.0.50727.3053; ASP.NET Version:2.0.50727.3053
I assume Castle Windsor does not like interpreting "Home.aspx" as the controller ...
How can I fix this ?
Ok so I found out why its not working ... when you I uploaded the website files originally I uploaded everything - but after making some changes I only uploaded the "Global.asax" and "Global.asax.cs". The thing is the .cs files should not even be uploaded ... the project gets compiled and stored in the bin folder as ".dll" and its this file that must be uploaded for the changes to take effect ...

Resources