Keep the Session[] variable after a new build - c#

I wanted to know if it was possible to keep the Session variable thought builds in a ASP.NET + C#?
I ask this because every time I make a minor change to my application and need to rebuild it, I need to login again and do a nunch of operation after that... it's taking a lot of my time.
If there is no way around I can set up a testing mode where I'll always be logged in, or automatize the log in procedure... but it would save me time to just keep the Session after a build.

You could change your test server to use the State Server or SQL Server session state modes, which will survive an application restart.

I have used this hack when I didn't want to deal with authentication during development:
protected void Page_PreInit(object sender, EventArgs e)
{
// Fake authentication so I don't have to create a damn Login page just for this.
System.Web.Security.FormsIdentity id = new FormsIdentity(new FormsAuthenticationTicket("dok", false, 30));
string[] roles = { "a" };
HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(id, roles);
}
This is only going to work on the page you put it on, though you could add it to a base page.
You definitely have to remember to remove this before you promote the code to test/QA/UAT/prod!

This answer is community wiki so as not to generate any reputation, as it's effectively a reworking of DOK's answer. If you like it, please upvote DOK's answer.
#Dok, if you want to edit your answer to incorporate any of this, please do, and I'll gladly delete this answer. :)
DOK, as mentioned in my comments to your answer (and possibly some help for your own solution), you might want to do the following:
#if DEBUG //As mentioned by DOK in the comments. If you set debug to false when building for deployment, the code in here will not be compiled.
protected void Page_PreInit(object sender, EventArgs e)
{
bool inDevMode = false;
inDevMode = bool.Parse(ConfigurationManager.AppSettings["InDevMode"]); //Or you could use TryParse
if(inDevMode)
{
// Fake authentication so I don't have to create a damn Login page just for this.
System.Web.Security.FormsIdentity id = new FormsIdentity(new FormsAuthenticationTicket("dok", false, 30));
string[] roles = { "a" };
HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(id, roles);
}
}
#endif
To further ensure that you do not accidentally deploy with this active, then you would have your app settings in seperate config files (as well as your debug section). If you use Web Deployment projects, then you can put your dev config settings in one file, and your live config files in another (this is usually dev.config and live.config!).
eg, in your web.config:
<appSettings file="dev.config"/>
In your dev.config:
<appSettings>
<add key="InDevMode" value="true" />
</appSettings>
In your live.config:
<appSettings>
<add key="InDevMode" value="false" />
</appSettings>

Related

How to display errors with ASP.NET Core

I have a fairly simple website that I am playing with using ASP.NET Core. I am running the application from the command line and the website is returning static files but I keep getting 500 errors when I attempt to make a request that should get handled by MVC. How do I see what the error is? Whether the error is displayed to the browser or logged to the console doesn't matter I just want a way to see what the error is.
Add the error page middleware as shown here:
app.UseDeveloperExceptionPage();
Update for beta8:
In beta8 Microsoft changed the name to UseDeveloperExceptionPage. So if you want to use the ErrorPage, call:
app.UseDeveloperExceptionPage();
Here is the link to the related Github issue.
The ErrorPageOptions are the same as in beta6/7.
You can use
app.UseErrorPage(ErrorPageOptions.ShowAll)
until beta5 of Asp.Net Mvc.
As of beta6, ErrorPageOptions.ShowAll has been removed. You can now use the version without parameters
app.UseErrorPage();
or create an ErrorPageOptions object and specify how many lines around the error you want to display by setting SourceCodeLineCount.
app.UseErrorPage(new ErrorPageOptions() {SourceCodeLineCount = 100});
Additional Information
They removed multiple properties of ErrorPageOptions in this commit.
Before:
public class ErrorPageOptions
{
private bool _defaultVisibility;
private bool? _showExceptionDetails;
private bool? _showSourceCode;
private bool? _showQuery;
private bool? _showCookies;
private bool? _showHeaders;
private bool? _showEnvironment;
...
}
After:
public class ErrorPageOptions
{
public int SourceCodeLineCount { get; set; }
public IFileProvider FileProvider { get; set; }
...
}
So now you can only set how many lines of source code are printed.
If you don't care that your error details would be exposed to the world, you can enable the error details, right in the browser without any code changes. (This was only tested in IIS 8.5):
In IIS Manager, in the left Connections section, left-click select your Site.
In the right side Feature View open Error Pages.
On the far right Actions section, click on Edit Feature Settings
In the Error Responses, select the 2nd, Detailed errors, option then Ok (or if you are worried about exposing stuff to the world, start with the 3rd option, if you can open a local browser... ie, localhost:...)
This should be enough for you to be able to see the exact error... Important: If you had to use the middle Detailed errors option, be sure to turn it off once you debug the problem. This can give a hacker all he needs to break into your server.
If it is not important to expose the detail of the error to the world, then you can activate detailed error page in web.config.
Just add <customErrors mode="Off"/> in the <configuration> / <system.web> of your web.config file located in root folder of your web site.
For more detailed explanation:
How to Use Web.Config customErrors for ASP.NET
This has the advantage that you don't have to redeploy your site

How to remove X-AspNetMvc-Version from header response without touching source code file (Global.asax.cs)?

I need to disable the X-AspNetMvc-Version from the response header of a large number of applications. The server where the applications are hosted has just the content and config files Global.asax, web.config, app.config for the application and source code files (*.cs) reside with some other team.
I could only find the solution as adding
MvcHandler.DisableMvcResponseHeader = true;
to Global.asax.cs.
Any alternative solution(s) that involves working with any config file(s)?
Set enableVersionHeader to false in your web.config is an alternate, I would prefer the web.config change to a handler solution like you have, obviously, since you will not need to access global.asax.cs to make the change:
just copy this line into the web.config’s <system.web> section:
<httpRuntime enableVersionHeader="false" />
http://msdn.microsoft.com/en-us/library/system.web.configuration.httpruntimesection.enableversionheader(v=vs.110).aspx
http://madskristensen.net/post/Remove-the-X-AspNet-Version-header
Unfortunately the only way is to use the following code in your Global.asax:
MvcHandler.DisableMvcResponseHeader = true;
This is an old post but no marked answer. I was able to achieve this using the code below. In your global.asax.cs we can remove any header.
protected void Application_PreSendRequestHeaders()
{
if (HttpContext.Current != null)
{
HttpContext.Current.Response.Headers.Remove("x-aspnet-version");
}
}

PhluffyFotos does not work on Azure SDK 1.3

I have tried PhluffyFotos example on Azure SDK 1.2 and it works perfect. Today I have installed on another (clen) computer Azure SDK 1.3 and I have also want to try PhluffyFotos on it but it does not work. I have problem with this part:
if (!Roles.GetAllRoles().Contains("Administrator"))
{
Roles.CreateRole("Administrator");
}
It seems it somehow does not load the custom RoleProvider (TableStorageRoleProvider). Do you have any idea what it could be?
I get the following error: "The Role Manager feature has not been enabled.", because of the following exception "'System.Web.Security.Roles.ApplicationName' threw an exception of type 'System.Configuration.Provider.ProviderException'".
Can someone test this example and see what is the problem? http://phluffyfotos.codeplex.com/
Firsty I have the "SetConfigurationSettingPublisher" problem with this example, but I have successfully resole it.
EDIT:
I have look deeper into it and I am sure there are a problem with Role provider. Somehow the Roles class do not read config file. Have anyone any idea why?
I have the exact same problem with my own project. I verified with Fusion logs that the assembly which contains the custom providers dont even load. so it seems the problem is somehow related to the web.config settings being ignored.
To run PhluffyFotos example on Azure SKD 1.3 you have to the following:
Change reference Microsoft.WindowsAzure.StorageClient from 1.0 to 1.1
Move "GetConfigurationSettingValue" to the Global.asax "Application_Start" event.
Move Role related initialization to the Global.asax "Application_BeginRequest" event, but you have to ensure that it executes only once. Example:
private static object gate = new object();
private static bool initialized = false;
protected void Application_BeginRequest()
{
if (initialized)
{
return;
}
lock (gate)
{
if (!initialized)
{
// We need to check if this is the first launch of the app and pre-create
// the admin role and the first user to be admin (still needs to register).
if (!Roles.GetAllRoles().Contains("Administrator"))
{
Roles.CreateRole("Administrator");
}
if (!Roles.GetUsersInRole("Administrator").Any())
{
Roles.AddUserToRole(RoleEnvironment.GetConfigurationSettingValue("DefaultAdminRoleUser"), "Administrator");
}
initialized = true;
}
}
}
I posted a version of the code with the fixes suggested by Peter to rapidshare here:
http://rapidshare.com/files/434649379/PhluffyFotos.zip
For those who don't want to fuss around fixing the dependencies etc.
Cheers,
Daniel

Get values from the web.config section in an app.config file?

I'm trying to unit test values that will eventually wind up in a web.config file. In my test project, I created an app.config file with a web.config section to hold the settings. In a normal situation, I would call System.Configuration.ConfigurationSettings.AppSettings, but in this case, that doesn't work. I saw this question, which is very similar, but doesn't address how to get the NameValueCollection out of the config file. Here is an example of the config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<membership defaultProvider="CustomMembershipProvider">
<providers>
<clear/>
<add
name="CustomMembershipProvider"
applicationName="SettlementInfo"
enablePasswordRetrieval="false"
enablePasswordReset="false"
requiresQuestionAndAnswer="true"
writeExceptionsToEventLog="true" />
</providers>
</membership>
</system.web>
</configuration>
Has anyone dealt with this before?
I guess I'm confused here; it looks like you're trying to test that ASP.NET is using your custom membership provider appropriately. Correct?
If so, I'm 99.999% sure that you cannot unit test this using the MS framework; you must integration test it by deploying it to the webserver (or running Cassini in VS) and typing a username/password into your login page.
Now, it's possible I've misunderstood your request. If so, let me know and I'll edit my answer accordingly.
Edit:
For right now, I'm really just trying
to test the NameValue pairs coming out
of the config file, to make sure that
if the values aren't present, my
defaults are being applied. In other
words, I want to try to pull
applicationName, and verify that it
equals "SettlementInfo", and so on.
After that, I will be using
integration testing to ensure that
ASP.NET is using the custom framework
in place of the default one. Does that
make sense?
I need more than a comment to reply, so I'm editing. If I read you correctly, you are wanting to unit test your program to ensure that it deals with configuration correctly, yes? Meaning you want to ensure that your code grabs, for example, the correct AppSettings key and handles a null value therein, correct?
If that's the case, you're in luck; you don't need an app.config or web.config at all, you can set the values you need as part of your test setup.
For example:
[TestMethod]
public void Test_Configuration_Used_Correctly()
{
ConfigurationManager.AppSettings["MyConfigName"] = "MyConfigValue";
MyClass testObject = new MyClass();
testObject.ConfigurationHandler();
Assert.AreEqual(testObject.ConfigurationItemOrDefault, "MyConfigValue");
}
[TestMethod]
public void Test_Configuration_Defaults_Used_Correctly()
{
// you don't need to set AppSettings for a non-existent value...
// ConfigurationManager.AppSettings["MyConfigName"] = "MyConfigValue";
MyClass testObject = new MyClass();
testObject.ConfigurationHandler();
Assert.AreEqual(testObject.ConfigurationItemOrDefault, "MyConfigDefaultValue");
}
I believe you only have access to the webconfig file while your application is actually beeing started up. The solution is rather easy -> "Fake" your config. Use a NameValueCollection and use that instead:
private static NameValueCollection CreateConfig()
{
NameValueCollection config = new NameValueCollection();
config.Add("applicationName", "TestApp");
config.Add("enablePasswordReset", "false");
config.Add("enablePasswordRetrieval", "true");
config.Add("maxInvalidPasswordAttempts", "5");
config.Add("minRequiredNonalphanumericCharacters", "2");
config.Add("minRequiredPasswordLength", "6");
config.Add("requiresQuestionAndAnswer", "true");
config.Add("requiresUniqueEmail", "true");
config.Add("passwordAttemptWindow", "10");
return config;
}
Now you could easily pass that collection into your class that parses data from it.
You should be able to use the ConfigurationManager.GetSection() method to pull out whatever you want.
Actually, if you are using NUnit, you can stick that in an App.config in your test project.
Then add this line to your Post-build event:
copy /Y “$(ProjectDir)App.config” “$(TargetDir)$(TargetFileName).config”
When you create the new provider in your tests, NUnit will pass the values in your app.config to the provider in the initialize method.
Why not just stick it in the web.config file?

Is there any way to programmatically set the application name in Elmah?

I need to change the app name based on what configuration I'm using in Visual Studio. For example, if I'm in Debug configuration, I want the app name to show as 'App_Debug' in the Application field in the Elmah_Error table. Does anyone have any experience with this? Or is there another way to do it?
This can now be done purely in markup. Just add an applicationName attribute to the errorLog element in the <elmah> section of the web.config file. Example:
<errorLog type="Elmah.SqlErrorLog, Elmah"
connectionStringName="connectionString" applicationName="myApp" />
I've tested this and it works both when logging an exception and when viewing the log via Elmah.axd.
In the case of the OP, one would imagine it can be set programatically too but I didn't test that. For me and I imagine for most scenarios the markup approach is sufficient.
By default, Elmah uses the AppPool's application GUID as the default application name. It uses this as the key to identify the errors in the Elmah_Error table when you look at the web interface that's created through it's HTTP Module.
I was tasked to explore this option for my company earlier this year. I couldn't find a way to manipulate this by default since Elmah pulls the application name from HttpRuntime.AppDomainAppId in the ErrorLog.cs file. You could manipulate it by whatever key you want; however, that is the AppPool's GUID.
With that said, I was able to manipulate the ErrorLog.cs file to turn Elmah into a callable framework instead of a handler based one and allow for me set the ApplicationName. What I ended up doing was modifying ErrorLog.cs to include a property that allowed me to set the name as below:
public virtual string ApplicationName
{
get
{
if (_applicationName == null) { _applicationName = HttpRuntime.AppDomainAppId; }
return _applicationName;
}
set { _applicationName = value; }
}
What you will probably need to do is adjust this differently and set the ApplicationName not to HttpRuntime.AppDomainAppId but, instead, a value pulled from the web.config. All in all, it's possible. The way I did it enhanced the ErrorLog.Log(ex) method so I could use Elmah has a callable framework beyond web applications. Looking back I wish I did the app/web.config approach instead.
One thing to keep in mind when changing the application name in Elmah. The http handler that generates the /elmah/default.aspx interface will no longer work. I'm still trying to find time to circle back around to such; however, you may need to look into creating a custom interface when implementing.

Categories