It's a trap
It's a trap

Reputation: 1353

API controller in MVC App not working

I have created an mvc application with SSO. I have added an Api controller, but whenever i try to get data from it, i get error.
URI= https://localhost:44305/api/graph/get

Error: Server Error in '/' Application. The resource cannot be found. Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.

Requested URL: /api/graph/get Here is my Route config

public class RouteConfig
{
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        //routes.MapRoute(
        //    name: "Default",
        //    url: "{controller}/{action}/{id}",
        //    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });

        routes.MapRoute(
            name: "Default",
            url: "api/{controller}/{action}/{id}",
            defaults: new { controller = "Graph", action = "Get", id = UrlParameter.Optional }
        );
    }
}

This is my web api controller

public JsonResult<List<Claim>> Get()
{
        var principal = (User as ClaimsPrincipal);
        List<Claim> claimsList = new List<Claim>();
        foreach (var claim in principal.Claims)
        {
            claimsList.Add(claim);
        }
        return Json<List<Claim>>(claimsList);
}

Not getting any build error. Any help is appreciated

Upvotes: 0

Views: 3880

Answers (4)

jolySoft
jolySoft

Reputation: 3020

You should have 2 config files:

RoutesConfig.cs and WebApiConfig.cs

RoutesConfig should look like this:

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

        routes.MapMvcAttributeRoutes();

        routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional });
    }
}

WebApiConfig.cs should look like this:

public static class WebApiConfig
{
    public static void Configure(HttpConfiguration config)
    {
        ConfigureRouting(config);
        ConfigureFormatters(config);
    }

    private static void ConfigureFormatters(HttpConfiguration config)
    {
        config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new NiceEnumConverter());
    }

    private static void ConfigureRouting(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional, @namespace = "api" });
    }
}

Within global.asax.cs you should have something like this:

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        // Register them in this order
        GlobalConfiguration.Configure(WebApiConfig.Configure); //registers WebApi routes
        RouteConfig.RegisterRoutes(RouteTable.Routes);  //register MVC routes
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }
}

Your controller does look a little strange why not let the default serialiser take care for things for you:

public IEnumerable<Claim> Get()
{
        var principal = (User as ClaimsPrincipal);
        List<Claim> claimsList = new List<Claim>();
        foreach (var claim in principal.Claims)
        {
            claimsList.Add(claim);
        }
        return claimsList;
}

EDIT: removed redundant code

Upvotes: 0

It&#39;s a trap
It&#39;s a trap

Reputation: 1353

Hy Guys.Thanks for all your help. I have figured out the solution. The answer is that in Global.asax.cs,

 GlobalConfiguration.Configure(WebApiConfig.Register) 

has to be called before

 RouteConfig.RegisterRoutes(RouteTable.Routes).

Upvotes: 2

cgt_mky
cgt_mky

Reputation: 196

Assuming the name of your controller is GraphController, I think the url you should be using is /api/graph/get.

If it's named something different, you'll need to adjust the url accordingly.

Also, there's a separate .cs file in MVC projects you should use to manage WebAPI routes - WebApiConfig.cs

Upvotes: 0

Mohammad Atiour Islam
Mohammad Atiour Islam

Reputation: 5708

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}",
        defaults: new { controller = "Default", action = "Index", id = UrlParameter.Optional }
    );
    }
}


public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultDataApi",
            routeTemplate: "Api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}


public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        FluentValidationModelValidatorProvider.Configure();
    }
}

Upvotes: 1

Related Questions