0

I've looked some time for a good explanation about the association between ASP.NET (MVC/WebAPI) as server-side and AngularJS as the client. But I'm still uncertain whether is it the correct way to implement a SPA with both technologies.

My idea is, to use ASP.NET as REST service. But I'm impressed about the Bundle in ASP.NET. To use it I need ASP.NET MVC and its Razor templates. Is that a good practice for building an application with angularjs as client?

I guess I only need MVC for authorization if the user is allowed to go on relevant pages. Or is there a better way with angular to find out the windows user? Because I need the account of the windows login user.

I hope anyone can help me to find out the right way.

yuro
  • 2,189
  • 6
  • 40
  • 76
  • I would recommend you use something like Webpack and split the front end and back end code if for nothing else other than maintainability – Dan Aug 04 '16 at 22:00
  • @DanPantry Thanks for your comment. Could you please explain shortly, what `Webpack` exactly is? I mean, what I can see is, that I can bundle all files and it generates static assets. But my question is, whether the combination between ASP.NET and angular is useful. – yuro Aug 04 '16 at 22:12
  • 1
    I can definetely advise [aspnetboilerplate][1]. It implements the all of best practices almost. [1]: https://github.com/aspnetboilerplate/aspnetboilerplate – Oğuzhan Soykan Aug 04 '16 at 22:13
  • @OğuzhanSoykan Thanks for the link. it sounds good. But is it a good practice to use both technologies? Or is there another way to define authorization with windows accounts without asp.net mvc and just with angular and asp.net webapi? – yuro Aug 04 '16 at 22:15
  • @yuro I would prefer AngularJS + WebApi + Mvc and for authorization and user management Aspnet Identity based on owin middleware. For the windows accounts also aspnetboilerplate has a module-zero extension which is providing LDAP authentication that you said, ref: https://github.com/aspnetboilerplate/module-zero/tree/dev/src/Abp.Zero.Ldap – Oğuzhan Soykan Aug 04 '16 at 22:20

2 Answers2

1

I assume you are using Angular 1.x. I don't see any constraints in using both razor and the template provided by angular, but generally you'd be better off in sticking with angular's template system. Here's some pointers:

  1. You'll use 2 razor views - _Layout.cshtml and Index.cshtml. These 2 will bootstrap the application.
  2. You'll need at least an MVC home controller that maps to your Index.cshtml.
  3. You'll need to configure your MVC routes to all point to your home controler using catch-all. Refer to this link for more details (go to RouteConfig.cs section of the article)
  4. For bundling javascript you can use MVC's bundling and minification and use the @Scripts.Render in your MVC view. There will be a performance penalty in the initial load since you'll be loading the minified scripts all at the same time. If your app is too large then you can use something like require js. Here's some links for a more detailed explanation:

Bundling and Minifying an AngularJS Application with ASP.NET MVC

Bundling and Minifying an AngularJS Application with ASP.NET MVC

  1. For authentication you can use Token-Based authentication here's a link for configuring it.
james
  • 216
  • 4
  • 12
1

The stack you're suggesting is perfectly good to use.

My team has built an application in the past where we had 2 razor pages, the one was basically the external app (by external I mean non-logged in user) which was quite light weight and only handled signup, then the other acted as an internal shell for the rest of the app (once logged in).

  • The .NET bundling allowed us to do some cool things like only delivering certain scripts to certain razor pages. EG a non-logged in user didn't need to be served the whole internal app.
  • Using this method also allows you to utilize the built in ASP.NET auth framework.

I recently stumbled across a really cool bootstrap project that can help you construct a boilerplate app. My suggestion is just download this, and have a look through the boilerplate app to give you more clarity on its usage. (Then it's up to you if you want to use it or not, but it'll give you more clarity on solution construction)

Thus your final app would have one (or 2) MVC controller(s) that deliver your shell pages, and all other calls would be done via WebAPI endpoints. See rough example below:

..\Controllers\RootController.cs

public class RootController : Controller
{
    // we only utilize one server side rendered page to deliver out initial
    // payloads; scripts; css; etc.
    public ActionResult Index()
    {
        // using partial view allows you to get rid of the _layout.cshtml page
        return PartialView();
    }
}

..\Views\Root\Index.cshtml

<html ng-app="MyAngularApp">
<head>
    @Styles.Render("~/content/css")
    @Scripts.Render("~/bundles/js")
    @Scripts.Render("~/bundles/app")
</head>
<body>
    <div class="container">
        <div ng-view></div>
    </div>
</body>
</html>

..\WebAPI\SomethingController.cs

public class SomethingController : ApiController
{
    private readonly IRepository _repo;

    public SomethingController(IRepository repo)
    {
        _repo = repo;
    }

    // GET: api/Somethings
    public IQueryable<Something> GetSomethings()
    {
        return _repo.GetAll();
    }
}

Tip: The easiest way I've found to construct projects like this is to use the Visual Studio's New Project Wizard. Select Web Project -> MVC, Make sure to Select WebAPI. This will ensure that App_Start has all the required routes & configs pre-generated.

enter image description here

Rohan Büchner
  • 5,333
  • 4
  • 62
  • 106
  • Thanks Rohan. It's a good explanation. One question. The `PartialView()` method will needed to load only the content and not the whole page isn't it? What I've wondered, why I need to define `private readonly IRepository...`? – yuro Aug 05 '16 at 07:28
  • 1
    Oh... erm, the repository is just an example of a dependency I had on the controller, you don't need it specifically. Are you familiar with IOC? (Related / unrelated.. check out the repository pattern too.. http://www.codeproject.com/Articles/526874/Repository-pattern-done-right ) – Rohan Büchner Aug 05 '16 at 08:10
  • 1
    Regarding the partial... I believe its a bit of a hack, but if you had to return `View()` only, the view would expect a container page, thus you'd need the `_Layout.cshtml`... but since we're using the partial as our container for the Angular `ng-view`, I didn't see any need to have another level of nesting without any purpose... – Rohan Büchner Aug 05 '16 at 08:17
  • many thanks for your advice. It helps me to imagine more clearer. – yuro Aug 05 '16 at 08:21
  • I have another question. You've written in your answer that only index.cshtml need to define as start page. But what is with `_Layout.cshtml` and do I need to define in `ViewStart.cshtml` the path to inde.cshtml? – yuro Aug 15 '16 at 17:59
  • @yuro I'll pop online tomorrow in a chat before 6/7 GMT +2, then I'll explain (instead of in the comments). Basically _Layout.cshtm is your classic master page. But because (in my example) index.cshtml contains the ng-view, index.cshtml acts as the angular master page. You'll notice in my controller I returned a PartialView(), and not View()... Doing so to enabled me to not need _Layout.cshtml anymore. Hope that helps for now? – Rohan Büchner Aug 15 '16 at 18:17
  • Ok, that means `_Layout.cshtml` isn't mandatory? I've defined in `ViewStart.cshtml` => `Layout = "~/Views/Home/Index.cshtml";` Is this also a good practice? – yuro Aug 15 '16 at 18:29
  • Could you help me in this thread : http://stackoverflow.com/questions/39453756/how-to-define-angular-routing-in-asp-net-mvc – yuro Sep 13 '16 at 14:52