How to test a single page in .aspx.net project - c#

The project contains files of .aspx.cs , .aspx , .htm , .cs etc. As far as I understand, it is a web application project. I am working on a base page named PageBase.cs which includes features that all other pages would inherit from. I want to test how this page works and I am stuck.
There's no "Start Debug" nor "Run" options. The only one I get is "Attach to a Process". When I attached this .cs file to a process, VS shows that debug is ready but no outcomes are shown. I'm not even sure what outcomes I am expecting though so I can only stop debugging. The followings are the links I found in my research, hopefully they would be helpful in some way:
https://msdn.microsoft.com/en-us/library/3s68z0b3.aspx
https://msdn.microsoft.com/en-us/library/df5x06h3(v=vs.110).aspx
I know this question is trivial but I am totally new to .Net. Please help.

Since you've only created a class, you need to have a way to reach that code. Have one of your pages inherit from that class, and make sure that your custom class is wired into the Page Life cycle events properly (Page_Load, Init etc) depending on when you want the code to execute.
Assuming you set up the inheritance properly, and that your debugger is attached to the process, your breakpoints in the class will be hit when you access that page and hit the appropriate stages in the page lifecycle.

This is what I did for PageBase.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Test.Lib.Base
{
public class PageBase : System.Web.UI.Page
{
#region Method
protected override void OnInit(EventArgs e)
{
AutocompleteOff();
base.OnInit(e);
if (User.Identity.IsAuthenticated)
ViewStateUserKey = Session.SessionID;
}
protected override void AutocompleteOff()
{
Page.Form.Attributes.Add("autocomplete", "off");
}
#endregion
}
}
And then for other pages under test folder, (Body.aspx.cs for instance) I added PageBase as the following:
public partial class PostLogin : Lib.Base.PageBase
{
# Method
...
}

Related

Problems at "Getting started with ANTLR" (Not able to create SpeakVisitor class)

I'm currently going through this tutorial:
https://tomassetti.me/getting-started-with-antlr-in-csharp/#note1
But I've issues at the point where I want to create the SpeakVisitor class, in the tutorial the class is inheriting from a class called SpeakBaseVisitor which was generated by ANTLR itself.
So I looked through my whole solution and I couldn't find this created class...
All I got are two pretty much empty class files called SpeakLexer and SpeakParser which got created after I selected Combined Grammar in the "Add → New Item" dialog.
SpeakLexer.cs
namespace _006_ANTLR
{
partial class SpeakLexer
{
}
}
SpeakParser.cs
namespace _006_ANTLR
{
partial class SpeakParser
{
}
}
Do you got any idea why there is no SpeakBaseVisitor automatically generated in my case?
Greetings! :-)

Embed Global.asax in assembly

Is it possible to embed the Global.asax file into an assembly? Currently it is represented as a file in the web root directory. But I want to store it as a resource in an assembly.
I'm not sure. Have you tried setting Build Action to Embedded Resource? You can do that by selecting the global.asax file and then the option should appear in your property window.
Ali Reza Dehdar's answer is correct (just change Compile to Embedded Resource in file's properties) and the result can be seen using a decompiler:
Yes you can. You have three options as far as I know:
Use HttpModule but be aware that there are some tricky parts about it. For example the HttpModule Init method might be triggered multiple times (this is based on the number of application instances in the app pool)
Use OWIN
Alternate the HttpApplication type - this one works best for me but I haven't tested it in too many different situations and framework versions. The only thing you need to do in your assembly is paste the following:
.
using System.Web;
using System.Web.UI;
[assembly: PreApplicationStartMethod(typeof(MyAssembly.MyHttpApplication), nameof(MyAssembly.MyHttpApplication.Application_Register)]
namespace MyAssembly
{
public class MyHttpApplication : HttpApplication
{
public static void Application_Register()
{
PageParser.DefaultApplicationBaseType = typeof(MyHttpApplication);
}
protected void Application_Start()
{
// TODO: Your application startup magic :)
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
// TODO:
}
}
}
Trace (or something like that):
System.Web.UI.PageParser.DefaultApplicationBaseType
System.Web.Compilation.BuildManager.GetGlobalAsaxType()
System.Web.HttpApplicationFactory.CompileApplication()
Hope that helps :)

Calling a Function in MasterPage code behind from App_Code .cs file?

I have a file in the App_Code file which is some legacy code, that I use to control Login and sessions. Ideally, once I am logged in, I wish to update the ..Master.cs to fire a function to update the layout (some panels, become enabled etc).
I can access App_Code easily from Code Behind, though I'm unable to figure out how to do this the other way round.
MasterPage.master.cs (code behind)
public static class MasterPage : System.Web.UI.MasterPage{
...
public static void LogInCB{
//stufff
}
...
}
App_Code (something.cs)
public static string(){
//Master.LogInCB(); -tried
//System.Web.UI.MasterPage.LogInCB(); -tried
return something;
}
I'm happy to accept links to official MS documents on things about this.
The code-behind doesn't know what master page you are using. One way to fix this is to cast the Page.Master as your master page class. Once you do that, it will intellisense available functions:
YourNameSpace.MasterPage m = (YourNameSpace.MasterPage)Page.Master;
m.LogInCB();

Dynamically load ASP.NET Page from DLL

I want to create a modular ASP.NET application. Something like, I have a main application that is just some kind of module loader. It only have the one "Default.aspx" page. And, based on the loaded modules, this page will create a menu and links to the pages found in the modules.
I want the modules to be ASP.NET projects packed into dll. So, I want to drop that dll into the "Modules" folder of my main application, it will identify the module, and use reflection to load the modules, inspect them to find the pages, and build a menu from that.
What I've done so far:
In my solution, I have a "DummyModule" project. This project have only 3 pages. Nothing special about it.
And I have another project called "MainApp". Here is the "big deal".
In this project I have a "ModuleLoader" class. When the "LoadModules" method is called, it search for "dll" files in the "Modules" folders of my application. And, using reflection, load these modules. Foreach of these modules, still using reflection, it searches all "Page" types, and stores the names into a list.
On the "Page_Load" method of the "Default.aspx" page, it call de "ModuleLoader" class, gets all modules names and all pages names for each module, and build a menu from that. I created a hyperlink pattern, that have all the information I need to load the right page. That is : "/ModuleName/PageName".
I'm not using the "aspx" extension. OK, so far, so good.
Here is the tricky part.
I've created a HTTPModule called "PageLoaderModule". This modules intercepts all requests, so I can read the URL to identify wich page from wich module I have to load.
And that's exactly what I cannot do and I have no idea how to solve this.
What I'm doing:
public class PageLoaderModule : IHttpModule
{
#region IHttpModule Members
public void Dispose()
{
//clean-up code here.
}
public void Init(HttpApplication context)
{
context.BeginRequest += context_BeginRequest;
}
private void context_BeginRequest(object sender, EventArgs e)
{
var application = (HttpApplication)sender;
if (Regex.IsMatch(application.Request.RawUrl, #"/.+/.+"))
{
var parts = application.Request.RawUrl.Split('/').Where(u => !string.IsNullOrWhiteSpace(u)).ToList();
IHttpHandler page = ModuleManager.GetPage(parts[0], parts[1]);
page.ProcessRequest(application.Context);
}
}
#endregion IHttpModule Members
}
The "GetPage" method, find the correct "Page" type in the specified assembly, create an instance and return the that Page instance.
But when I call the "ProcessRequest" method of the IHTTPHandler interface, it doesn't load the page.
It's possible to do that? Any thoughts?
Edit:
I've tried #Slavo suggestion.
While searching for an anwser, I've found and tried a similar solution, implementing my own VirtualPathProvider and VirtualFile.
It almost worked. The virtual path handle and load the correct page but, when the page is loaded, I got the following error in my browser:
Parser Error Message: Could not load type 'DummyModule.Pages.DummyPage3'.
Source Error:
Line 1: <% # Page Language="C#" AutoEventWireup="true" CodeBehind="DummyPage3.aspx.cs" Inherits="DummyModule.Pages.DummyPage3" %>
So, I don't know if I've done something wrong, or this isn't the solution I'm looking for. So, I tried other option.
I correctly marked the "Build Action" of the ".aspx" file as "Embedded Resource", so it can be accessible as a virtual path. But I still got the error above.
This looks like a case where you would want to write a VirtualPathProvider. This class lets you control the logic, which provides components to the compilation system.
When ASP.NET compiles a page to handle the request, by default it only uses the ASPX file and the code-behind. If you write a custom VirtualPathProvider, you will be able to tell it to do otherwise. So whenever ASP.NET needs to compile a page for a particular path to handle the request, your provider can extract it from an assembly.
Here is a helpful article: http://support.microsoft.com/kb/910441
You should handle the PostMapRequestHandler event in your module and set a custom IHttpHandler to the application.Current.Handler property. Here is an example.

Extension methods in a class library project

I've implemented some extension methods and put those in separate Class Library project.
Imagine I have a simple extension method like this in class library called MD.Utility:
namespace MD.Utility
{
public static class ExtenMethods
{
public static bool IsValidEmailAddress(this string s)
{
Regex regex = new Regex(#"^[\w-\.]+#([\w-]+\.)+[\w-]{2,4}$");
return regex.IsMatch(s);
}
}
}
But nowhere in the web app like the App_code folder or the WebFroms code-behind page can I use this extension method. If I do something like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using MD.Utility;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string email = "Someone#Somewhere.com";
if (email.IsValidEmailAddress())
{
//To do
}
}
}
The compiler doesn't recognize IsValidEmailAddress() and there's even no IntelliSense support.
While if I put my extension method in the App_Code folder, it's usable in another .cs files in the App_code folder or the WebForms code-behind pages.
Did you remember to add a reference to your class library in the web project ?
You will need that. Other than that, your code looks fine, and should work.
If changes are not getting recompiled when you do a solution rebuild, then it could be the type of reference you are using. If the MD.Utility project is in your web project solution, you should make the reference a "Project Reference." That will cause the build to consider that code as a dependency and therefore rebuild it when you change something. If you just include it as a DLL, then the DLL is considered external and the build will not consider it, even if it is in the same solution.
I was able to resolve it by making the extension module public.
This post may be helpful:
Extension methods in referenced assemblies?
In addition to adding the assembly to the references, what fixed it for me was to explicitly adding it to the file "using MD.Utility".
I've found that this can occur if the Assembly Name and Namespace of the consuming project are the same and the Common library has the same Namespace.
Seems that the compiler gets confused. Try changing them.
As noted elsewhere, you need to add the Common library to each consuming project. And the Module containing the Extension(s) in the Common library must be marked Public. Unlike Classes, Public isn't the default scope for Modules. No idea why.

Categories

Resources