14

Before I ask my question I have already gone through the following posts:

  1. Can't get the OWIN Startup class to run in IIS Express after renaming ASP.NET project file and all the posts mentioned in the question.
  2. OWIN Startup Detection
  3. OwinStartupAttribute required in web.config to correct Server Error #884
  4. OWIN Startup class not detected

Here is my project's folder layout:

enter image description here
Currently there is no controller or view. Just the Owin Startup file.


Startup.cs

using System;
using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(Bootstrapper.Startup))]

namespace Bootstrapper
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.Run(async context =>
            {
                await context.Response.WriteAsync(GetTime() + " My First OWIN App");
            });
        }

        string GetTime()
        {
            return DateTime.Now.Millisecond.ToString();
        }
    }
}


Web.config

<appSettings>
    <add key="owin:AutomaticAppStartup" value="true" />
    <add key="owin:appStartup" value="Bootstrapper.Startup" />
    <add key="webpages:Version" value="2.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="PreserveLoginUrl" value="true" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
  </appSettings>


I have the following reference in the Bootstrapper project:

  1. Microsoft.Owin
  2. Microsoft.Owin.Host.SystemWeb
  3. Owin
  4. System
  5. System.Core


UPDATE: Forgot to add the error message:

enter image description here


Now,

  1. WHY is it not working?
  2. What is the step-by-step process of adding and using an Owin Startup class in a very basic project(like accessing Home/Index)?
  3. How and when does Configuration method in Owin Startup class is called/executed?


UPDATE: on 10-Dec-2016

Check the Project-Folder-Layout. In Bootstrapper project I have the following file:
IocConfig.cs

[assembly: PreApplicationStartMethod(typeof(IocConfig), "RegisterDependencies")]

namespace Bootstrapper
{
    public class IocConfig
    {
        public static void RegisterDependencies()
        {
            var builder = new ContainerBuilder();

            builder.RegisterControllers(typeof(MvcApplication).Assembly);
            builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource());
            builder.RegisterModule<AutofacWebTypesModule>();

            builder.RegisterType(typeof(MovieService)).As(typeof(IMovieService)).InstancePerRequest();
            builder.RegisterType(typeof(MovieRepository)).As(typeof(IMovieRepository)).InstancePerRequest();

            var container = builder.Build();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
        }
    }
}

Now I want to execute IocConfig.RegisterDependencies() in OWIN Startup class. I am doing using Bootstrapper in Startup at the top but, it is not working. I mean I am unable to reference IocConfig in Startup. How to resolve this?

Community
  • 1
  • 1
phougatv
  • 321
  • 1
  • 5
  • 17

3 Answers3

9
  1. Create an empty web application project
  2. Install the OWIN using NuGet (install-package Microsoft.Owin.Host.SystemWeb)
  3. Add an empty class into the project root called "Startup.cs"

Here I will answer your third question. The startup class is an entry point of OWIN and is being looked up automatically. As stated in official docs:

Naming Convention: Katana looks for a class named Startup in namespace matching the assembly name or the global namespace.

Note, that you can also choose your own name of Startup class but you have to set this up using decorators or AppConfig. As stated here: https://www.asp.net/aspnet/overview/owin-and-katana/owin-startup-class-detection

This is everything you need for a basic and working OWIN test:

using Owin;
using System;

namespace OwinTest
{
    public class Startup
    {
        public static void Configuration(IAppBuilder app)
        {
            app.Use(async (ctx, next) =>
            {
                await ctx.Response.WriteAsync(DateTime.Now.ToString() + " My First OWIN App");
            });
        }
    }
}

If you wish to use MVC (I guess by "Home/Index" you mean MVC), follow these steps:

  1. Install MVC NuGet (install-package Microsoft.AspNet.Mvc).
  2. Add a "Controllers" folder into your project.
  3. Create a new empty controller under the new "Controlles" folder (right click -> add -> MVC 5 Controller - Empty) and name it "HomeController".
  4. Create a view page under newly created "Views/Home" folder. Right click -> add -> View. Name it "Index" and uncheck the "use layour page".

Make the page inherit from WebViewPage. It should all look like this:

@inherits System.Web.Mvc.WebViewPage
@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <div> 
        <h1>Owin Hello</h1>
    </div>
</body>
</html>
  1. Add a global.asax to set up routes. Right click on the project -> add -> New Item -> Global Application Class.

Add the routes definition to the Application_Start method:

protected void Application_Start(object sender, EventArgs e)
{
    RouteTable.Routes.MapRoute(name: "Default",
        url: "{controller}/{action}",
        defaults: new { controller = "Home", action = "Index" });
}
  1. Do not forget to comment out the above "..await ctx.Response.WriteAsync..." middleware. It would interfere with the MVC otherwise.
  2. Run the project. Should be working.
Ivan Sivak
  • 6,104
  • 3
  • 28
  • 39
  • What if I disobey the third point `Add an empty class into the project root called "Startup.cs"`? I mean I do add a Startup class but not in the root, instead I do the way I have asked in question. Look at the `project-folder-layout` for reference. – phougatv Dec 09 '16 at 14:15
  • @barnes then you will get `System.EntryPointNotFoundException` exception. OWIN simply needs an entry point. – Ivan Sivak Dec 09 '16 at 14:18
  • I never saw that exception, instead, on every call, `Application_Start()` in `Global.asax` was called. No exception was thrown. Later I moved my `Startup` file to the project (Mvc) and then it started executing. – phougatv Dec 09 '16 at 14:20
  • So according to you the `Owin Startup` file must be included in the project root folder which is `Mvc` in my case. Otherwise `Startup` file and its methods will not be executed. Is that correct? – phougatv Dec 09 '16 at 14:23
  • Could you also provide me with some references on - How to manage `project folder layout`? I know there will be `class libraries` for `Services` and `Repositories`, how do I manage them in terms of folders. – phougatv Dec 09 '16 at 14:28
  • 2
    @barnes Your presentation layer should contain a main web front end with OWIN and MVC. Any additional business logic or data layer or infrastructure can be a separate service library. These additional projects contain the code. Inside the OWIN you should always only call what is needed. If single OWIN middleware would get complicated itself - you can always put the code into separate class and use just `app.Use()` instead. The key for successful project is always simplicity and clean elegant code. Separation of concerns. – Ivan Sivak Dec 09 '16 at 14:52
  • 1
    Thanks a lot for your time and help. I do appreciate it. :) – phougatv Dec 09 '16 at 14:58
  • Hey there! could you look up at my update at the very end of the question? – phougatv Dec 10 '16 at 17:21
  • Thanks, but I am not using ASP.NET Core. I am currently using VS 2013. – phougatv Dec 11 '16 at 10:37
2

It's a little bit late, but I found the solution how to put OWIN Startup class in separate project. Everything you did in your project is correct, you must only apply one change in the properties of your Bootstrapper project. Right click on Bootstrapper project, enter properties, click Build tab and look for Output path. You should see standard output path bin\debug\ which means that your Bootstrapper dll will land in this folder. You must change this to the bin folder, where your whole web app is.

For example, I've created a simple solution with two projects, first is an empty web app, and the second is a library with an OWIN Startup class. In properties of the second project I've changed the output path to ..\OwinTest.Web\bin. This will cause all dlls to land in one folder after the build. You can now run your app and OWIN Startup should work right.

Below is the screen of properties settings of Bootstrapper project:

enter image description here

clairestreb
  • 1,126
  • 10
  • 24
Roman Suska
  • 370
  • 2
  • 4
  • 18
  • If I am not wrong is this is what we call bootstrapping? Bootstrap the OWIN Startup file to project other than source project? – phougatv Sep 08 '17 at 11:52
  • 1
    Honestly, I'm don't know excatly, but I've found this answer on a question about what is bootstrapping: https://stackoverflow.com/a/1255796/3872681. Based on this answer I think, that bootstrapping in web apps means loading of all helper frameworks, like for example IoC containers or ASP.NET Identity module before the real application starts, so OWIN is itself a bootstraper. Therefore the project, where you moved OWIN startup file is called bootstrapper because it holds all OWIN modules, not becouse you bootstrapped OWIN there. But I'm not 100% sure about it. – Roman Suska Sep 08 '17 at 17:14
0

The WebApp class uses reflection to get a pointer to the Configuration(IAppBuilder) method then calls it. If the class you provide as the generic type argument does not have a Configuration method with the expected arguments then you get an error at run time.

clairestreb
  • 1,126
  • 10
  • 24