2

I am using angularJS with ASP.NET. When I run my Web application, all links are working and there is no 500 error.

But when I refresh page I got 500 error like this one:

The partial view 'Contacts' was not found or no view engine supports the searched locations. The following locations were searched:

I am using angularJS controller to load template from ./templates folder and angularJS is doing that job very well...

Does someone knows why I am getting this error and how to fix it?

Also inside View folder there is only Index.cshtml file because because I load templates from ./templates directory Here is RouteConfig.cs code:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute("templates", "templates/{action}.html",
         new { controller = "Home", action = "Templates", name = "" }
        );
        routes.MapRoute("contacts","contacts",
           new { controller = "Home", action = "Contacts", id = UrlParameter.Optional }
       );
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

Controller class:

public ActionResult Index()
{
    return View();
}

// ActionResult prikazan ispod služi da bi angularJS 
// mogao lodati HTML template u template folderu
public ActionResult Contacts()
{
    return PartialView();
}

public ActionResult Templates()
{
    return PartialView();

}

and here is angularJS route config:

app.config(function ($routeProvider, $locationProvider) {
    $routeProvider
        .when('/contacts',
            {
                controller: 'ContactsController',
                templateUrl: 'templates/contacts.html'
            })
        .when('/add-contact',
            {
                controller: 'ContactAddController',
                templateUrl: 'templates/addContact.html'
            })
        .when('/edit-contact/:contactId',
            {
                controller: 'ContactEditController',
                templateUrl: 'templates/editContact.html'
            })
        .when('/display-contact/:contactId',
            {
                controller: 'ContactDetailsController',
                templateUrl: 'templates/displayContact.html'
            })

        .when('/bookmarked-contacts',
            {
                controller: 'ContactsController',
                templateUrl: 'templates/bookmarkedContacts.html'
            })
        .when('/search-contacts',
            {
                controller: 'SearchContactsController',
                templateUrl: 'templates/searchContacts.html'
            })
        .otherwise({ redirectTo: '/contacts' });
    $locationProvider.html5Mode(true);

});
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
jureispro
  • 1,342
  • 5
  • 22
  • 43

1 Answers1

4

The issue is related to improperly set server side. Firstly try to turn off the html5 mode

//$locationProvider.html5Mode(true);
$locationProvider.html5Mode({enabled: false});

And check that after refresh all is working. It should.

Change the routing like this:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("fonts*.woff");
routes.IgnoreRoute("*.js");
routes.IgnoreRoute("*.html");
routes.IgnoreRoute("*.css");
routes.IgnoreRoute("api/*");

routes.MapRoute(
    name: "Default",
    url: "{dummyController}/{dummyAction}/{dummy1}/{dummy2}/{dummy3}",
    defaults: new { controller = "Home", action = "Index"
        , dummyController = UrlParameter.Optional
        , dummyAction = UrlParameter.Optional
        , dummy1 = UrlParameter.Optional
        , dummy2 = UrlParameter.Optional
        , dummy3 = UrlParameter.Optional
    }
);

This should do what we need. Whenever there is anything comming to server:

  • it ends with js, html, css ... it is returned
  • /api/ (ASP.NET Web API) is also skipped here
  • and any url like /somestuff/somepart is treated as Home/Index

This setting url: "{dummyController}/{dummyAction}/{id}", makes the above. any part coming from html5mode is treated as a route key "dummyController", "dummyAction", while the Home and Index are passed as controller and action in the defaults: new { controller = "Home", action = "Index" ...

And because your application is expecting some parts of your routing, you should use it like this:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.IgnoreRoute("fonts*.woff");
    routes.IgnoreRoute("*.js");
    routes.IgnoreRoute("*.html");
    routes.IgnoreRoute("*.css");
    routes.IgnoreRoute("api/*");

    // keep this application special settings
    routes.MapRoute("templates", "templates/{action}.html",
     new { controller = "Home", action = "Templates", name = "" }
    );
    routes.MapRoute("contacts","contacts",
       new { controller = "Home", action = "Contacts", id = UrlParameter.Optional }
    );

    // this should do the job on F5
    routes.MapRoute(
        name: "Default",
        url: "{dummyController}/{dummyAction}/{dummy1}/{dummy2}/{dummy3}",
        defaults: new { controller = "Home", action = "Index"
            , dummyController = UrlParameter.Optional
            , dummyAction = UrlParameter.Optional
            , dummy1 = UrlParameter.Optional
            , dummy2 = UrlParameter.Optional
            , dummy3 = UrlParameter.Optional
        }

);

Also check this

How to: Configure your server to work with html5Mode

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • I tried your code and I got error: Server Error in '/' Application. . If I remove html5mode # will appear on my URL which I don't want to. I want "pretty" links. Do I need to rewrite rules inside my application? – jureispro Dec 30 '14 at 14:42
  • You have to learn your server how to behave, when reload (F5) happens, and server recieves your "nice url link". So you have to create some mechanism, how to redirect in that case to /Home/Index ... does it help? I told you to use "not nice url link" (turn off the html5 mode) to help you to see: client is set properly. Problem is on the server side. Only on the server side. Also, here I tried in more detail settings which I am using http://stackoverflow.com/a/27675441/1679310 - but honestly I like # style ;) – Radim Köhler Dec 30 '14 at 14:44
  • If I turn off html5 mode it's working and when I refresh page there is no error. I guess that I will need to turn off html5 mode. I created rewrite rules and my pretty links was working but then AJAX calls was bugged and angularJS pop ups many errors... – jureispro Dec 30 '14 at 14:51
  • I used your code (replaced my original RouteConfig with one that you provided). When I run application I got error 403 (forbidden) and when I navigate to /contacts I got eror 404 (not found) :-( – jureispro Dec 30 '14 at 15:14
  • The point is, that I tried that locally and skipped your part with "templates" and "contacts". These should be used before my last part: `routes.MapRoute( name: "Default",` ... because your app is expecting that these routes will work. My edit shows, how we will solve the issue on F5 ... does it help? – Radim Köhler Dec 30 '14 at 15:15
  • Thank you for your help. Do I need to create new controller (i.e. dummyController) to handle page refresh? I modify {dummyController}{dummyAction} to {controller}{action} because without that I got 403 error. But if I do that, when I refresh page it gives me 500 error – jureispro Dec 30 '14 at 15:25
  • What about ISS rewrite rules? I used rewrite rule from URL that you included in your post but when I do that AJAX CALLS are not working. Do I need to modify my AJAX URLS? – jureispro Dec 30 '14 at 15:30
  • Look, I do not use html5 mode. Exactly for this reason. But I would say that now I found solution (see my last edit). You can use any way. Even rewrite rules, if you like... At the end what we have to do is: in case user refreshes (F5) and sends to server "weird" url ... we have to redirect him to Home/Index. Any way which will work for you is ok. I am pretty sure that my last update is the way. Sorry for ... so many tries ;) but ... ;) Good luck sir – Radim Köhler Dec 30 '14 at 15:33
  • The only solution that I can think of is disable html5 mode. With your last modification I can't AJAX Calls. I am calling ajax from Home/AJAXCALL() where AJAXCALL() is function that's inside controller class from MVC. Thank you for help but from now I think that I will use disable html5mode – jureispro Dec 30 '14 at 15:38