I'm using code first to develop my database for my MVC app. Here's the connection string:
<add name="OrtundWebConnectionString" connectionString="Data Source=.\SQLEXPRESS; Initial Catalog=OrtundWeb; User Id=sa; Password=sa;" providerName="System.Data.SqlClient"/>
It uses SQL Authentication because for reasons I've yet to determine, Windows Auth doesn't allow me to do anything on the server...
Here's Application_Start():
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
OrtundDB.InitializeDB();
}
This class calls db.Database.Initialize(true); and runs a method I wrote to add some default information into the database
public static class OrtundDB
{
private static OrtundDBContext db = new OrtundDBContext();
public static void InitializeDB()
{
db.Database.Initialize(true);
db.InitializeDB();
}
}
Here's the DBContext class I wrote that's being used. This exists in another project which is referenced in the MVC project:
internal class OrtundDBContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// modelBuilder.Configuration.Adds()
}
public OrtundDBContext()
: base("OrtundWebConnectionString")
{
Database.SetInitializer<OrtundDBContext>(new DropCreateDatabaseAlways<OrtundDBContext>());
}
public void InitializeDB()
{
// inserts the default data - an admin user account and information for user roles
}
// DbSet calls here
}
I've previously built an MVC app with this same methodology, and that one works. This, however, doesn't even execute Application_Start() every time.
On the odd occasion where it has executed Application_Start, it went all the way through to execute db.Database.Initialize(true); at which point, it just never seemed to end. I got no errors, but the action didn't seem to complete.
I'm a bit of a novice when it comes to MVC so I have no idea what the problem could be or how to fix it.
Any assistance to fix the problem (and possibly explanation as to what might cause it) will be greatly appreciated.
Thanks in advance!
Perhaps the issues lies with the expectation you have on Application_Start.
Application_Start is called once for the application being loaded into the app pool on IIS.
Only when the app pool is recycled or IIS is restarted will it be called again.
Take 10-15mins to read IIS pipeline
It will help with what is going on.
I had a nasty bug due to my false expectations about threads and requests.
alternatives to Consider and test in debug to see if they suit you:
The INIT in Global.asax
public override void Init() {
base.Init();
// handlers managed by ASP.Net during Forms authentication
BeginRequest += new EventHandler(BeginRequestHandler);
// PostAuthorizeRequest += new EventHandler(PostAuthHandler);
EndRequest += new EventHandler(EndRequestHandler);
}
Better: A single baseController for all your controllers so as to control bootstrap each call.
public class SomeController : MyBaseMvcController{
// whatever as usual....
}
[System.Web.Mvc.Authorize]
[MyMVCFilter] // see the filter below. Get the MVC pipeline to call your code on Executing
public abstract class MyBaseMvcController : Controller
{
protected MyBaseMvcController () {
// a place to get a NEW uow or new Context ....
}
}
public class MyMVCFilter : System.Web.Mvc.ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext) {
// a useful bootstrap option when you need the httpContext for bootstrap.
BootStrapHttp(filterContext.HttpContext);
base.OnActionExecuting(filterContext);
}
}
Related
This question covers how to manually notice errors in NewRelic in Ruby.
I need to do the same thing in C#.
How can I manually send errors to NewRelic in .NET?
According to NewRelic's .NET Api, you can do this with
NewRelic.Api.Agent.NewRelic.NoticeError(ex);
where ex is an Exception.
In order to do this across all WebApi as an ExceptionLogger to log errors into New Relic
Add the following class to your project
public class NewRelicExceptionLogger : ExceptionLogger
{
public override void Log(ExceptionLoggerContext context)
{
NewRelic.Api.Agent.NewRelic.NoticeError(context.ExceptionContext.Exception);
}
}
and register it Global.asax.cs under Application_Start():
protected void Application_Start()
{
//...
GlobalConfiguration.Configuration.Services.Add(typeof(IExceptionLogger), new NewRelicExceptionLogger());
}
i need to hit DB and load the settings file before every page loads. Am currently using MVC and am creating that call in constructor in All controllers.
Am not sure of what is the better way to handle this scenario ?? I read like we can use singleton class in this scenario.
Is it possible to have the data once and reuse across pages ? What is the best way ?
Some sample code snippets will help !
Option one: you can used Application_BeginRequest in Global.asax.cs:
protected void Application_BeginRequest(object sender, System.EventArgs e)
{
//something
}
Option two: create a global filter:
public class ActionLogFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext filterContext)
{
// do your stuff. This is run before control is passed to controller
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
// do stuff here - control here is passed after controller is done with the action execution
}
}
and then add controller to execution stack in Global.asax.cs:
FilterConfig.RegisterGlobalFilters(GlobalFilterCollection filters)
and FilterConfig is usually looks like this:
public static class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new MyFilter());
}
}
Option three: Create your global controller that overrides OnActionExecuting (see the filter example). Make your controllers to inherit from that global base controller.
I prefer option with filters. Favour composition over inheritance
Is there a way to setup some default settings for webpages being ran on debug mode?
For example, I'd like to set a default session userid on debug mode, but trying this in Application_Start() causes errors:
protected void Application_Start()
{
#if DEBUG
Session["User"] = "1"
#endif
}
I could instead choose to place that in controllers, but that'd require a lot of code duplication.
The reason that this throws an error is because the Session object is associated with a request. There is no request in the Application_Start event. You could move this logic to the Application_AcquireRequestState event handler and it would work fine.
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
if (HttpContext.Current.IsDebuggingEnabled)
{
HttpContext.Current.Session["user"] = "1";
}
else
{
HttpContext.Current.Session["user"] = "0";
}
}
EDIT
After further research, I was mistaken. In the .NET pipeline, the above event handler is the first place that you can access the session object. It has not been retrieved from the server in the Application_BeginRequest which is why you are getting a NullReferenceException still. I tested the above code in MVC 5 and had no issues.
Also, instead of having to rely on compiler constants, you can easily tell if you are in debug mode or not using the above syntax of HttpContext.Current.IsDebuggingEnabled. This basically is a wrapper for checking the web.config attribute on the compilation tag and seeing if debug="true"
Note - You have to use the fully qualified name of HttpContext.Current.Session (as above) since the global event handlers do not have a direct inheritance of the current HttpContext.
You could use the Conditional attribute and put it on a method in your base controller. Something like this:
public class BaseController : Controller {
public BaseController() {
SetupDebugData();
}
[Conditional("DEBUG")]
public void SetupDebugData() {
Session["User"] = "1";
}
}
The call to SetupDebugData will be optimized away for Release builds. Then you just inherit from this controller in your other controllers:
public class AdminController : BaseController {
// ...
}
Yes, off-course.
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
#if(DEBUG)
Console.WriteLine("This is debug mode");
#else
Console.WriteLine("This is release mode");
#endif
base.OnActionExecuting(filterContext);
}
This code will be work in MVC ( I use it since MVC3). Remember that you need to set release build and debug false in web.config when you deploy your asp.net app on server.
Is there any possibility to find function like Page_Load? I have MVC application and I need run some code every page is loaded, or reloaded, or I call some controller. One shared function for everything classes?
I try Application_Start, but this execute only for first time application run. I search some like BeginRequest, but this function have been call several times, I need only first, when I load page and I need end function, like constructor and destructor for whole project.
Here is sample code.
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
}
document.ready isn't my case. And call function every controller is last option. The code must be executed before any other function have been called. And before all end, i need run end function. For example, at first I need created mysql connector shared for all classes. And at end I need close mysql connection.
Make all your controllers inherit from a custom BaseController:
public class BaseController : Controller
{
protected override void OnActionExecuting(ActionExecutingContext context)
{
base.OnActionExecuting(context);
// your code here
}
}
public class HomeController : BaseController // instead of Controller
{
// ...
}
An update to Jan's answer. The onExecutingAction abstract method is public now not protected.
public virtual void OnActionExecuting(ActionExecutingContext context);
So, you can't use the protected access modifier when you override. Make it public instead.
public class BaseController : Controller
{
public override void OnActionExecuting(ActionExecutingContext context)
{
base.OnActionExecuting(context);
}
}
Is there an equivalent for MVC.NET's OnActionExecuting in standard asp.NET? ?
I thought it would be Page_Load since OnActionExecuting would be called each time an action is executed (or the page loads). But I'm running into inheritance issues when I try to use Page_Load instead.
Since it is very difficult to make my solution work with a Page_Load I'm thinking I might not have the best ... solution.
Any thoughts on whether they are equivalent or close enough?
Background:
I'm converting a piece of an MVC3 application into a standard .NET to wrap in a SharePoint Web Part.
Here's the MVC code I'm trying to translate, as you can see its the user security bits I'm translating:
protected override void OnActionExecuting(ActionExecutingContext filterContext) {
if (!SiteCacheProvider.ItemCached(enmCacheKey.SiteSetting)) {
if (filterContext.IsImplementedGeneralPrincipal()) {
IUserProfile userProfile = ((IGeneralPrincipal)filterContext.HttpContext.User).UserProfile;
SiteCacheProvider.ChangeSiteSetting(userProfile.SiteID);
}
}
base.OnActionExecuting(filterContext);
}
First, take on account that no Actions are in ASP.NET because the model is different (Event-Based) - There're no methods(actions) which you can decorate with Action Filters, it's all about the Page-Cycle events.
Second, In ASP.NET, you may use HTTP modules (HttpApplication.BeginRequest particularly) in order to intercept incoming requests to your application pages by adding your required logic.
From MSDN:
HTTP Modules use to intercept HTTP requests for modifying or utilize
HTTP based requests according to needs like authentication,
authorization, session/state management, logging, modifying Response,
URL rewriting, Error handling, Caching....
For example:
using System;
using System.Web;
using System.Collections;
public class HelloWorldModule : IHttpModule
{
public string ModuleName
{
get { return "HelloWorldModule"; }
}
public void Init(HttpApplication application)
{
application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
application.EndRequest += (new EventHandler(this.Application_EndRequest));
}
private void Application_BeginRequest(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write("<h1>HelloWorldModule: Beginning of Request</h1><hr>");
}
private void Application_EndRequest(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write("<hr><h1>HelloWorldModule: End of Request</h1>");
}
public void Dispose()
{
}
}