Web API routing in Sitecore 8.2 - asp.net-web-api

I migrated a sitecore 7.2 application to sitecore 8.2 using the express migration tool. After the migration Web API routing stopped working. I'm using below given method to map the routing
[UsedImplicitly]
public class ConfigRegister
{
/// <summary>
/// Startup method to bind all configurations for site core pipeline.
/// </summary>
/// <param name="args"></param>
public virtual void Process(PipelineArgs args)
{ RouteConfig.RegisterRoutes(RouteTable.Routes);
}
}
Then registering it using following code snippet
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "ControllersApi",
routeTemplate: "WebApi/CustomerPortal/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
I'm getting error A route named 'MS_attributerouteWebApi' is already in the route collection. Route names must be unique.
Parameter name: name.
But when I comment the line
config.MapHttpAttributeRoutes();
I'm getting error
{"Message":"An error has occurred.","ExceptionMessage":"The object has not yet been initialized. Ensure that HttpConfiguration.EnsureInitialized() is called in the application's startup code after all other initialization code.","ExceptionType":"System.InvalidOperationException","StackTrace":" at System.Web.Http.Routing.RouteCollectionRoute.get_SubRoutes()\r\n at System.Web.Http.Routing.RouteCollectionRoute.GetRouteData(String virtualPathRoot, HttpRequestMessage request)\r\n at System.Web.Http.WebHost.Routing.HttpWebRoute.GetRouteData(HttpContextBase httpContext)"}
Your help to solve this issue is highly appreciated

I assume you have this under the initialize pipeline, correct?
This is what we've done before and works on 8.2:
public void Process(PipelineArgs args)
{
HttpConfiguration httpConfig = GlobalConfiguration.Configuration;
httpConfig.Routes.MapHttpSessionRoute("WebApiRoute", "webapi/{controller}/{action}/{id}", true, new { id = RouteParameter.Optional });
}
If the above doesn't work,try this (per Habitat):
public void Process(PipelineArgs args)
{
RouteTable.Routes.MapHttpRoute("Feature.Demo.Api", "api/demo/{action}", new
{
controller = "Demo"
});
}

Related

Web API error - Server Error in '/api' Application

After publishing Web API to IIS, which is a child of an AngularJs IIS site, I can reach 'https://localhost/api' and see all endpoints; but when I try to reach some specific endpoint with a GET request, I get an error
Server Error in '/' Application
public class WebApiApplication : 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);
}
}
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
[RoutePrefix("api/branches")]
public class BranchesController : ApiBaseController
{
[HttpGet]
[Route("getBranches")]
public async Task<JsonResult<List<BranchDto>>> GetActiveBranches()
{
var branches = new List<BranchDto>();
var models = await WarehouseUnitOfWork.BranchRepository.GetActiveBranches();
if (models != null && models.Count > 0)
{
branches.AddRange(AutoMapper.Mapper.Map<List<Branch>, List<BranchDto>>(models));
}
return Json(branches, new JsonSerializerSettings
{
ContractResolver = new WarehouseCustomContractResolver()
});
}
}
Any ideas how to solve this?
The solution for my case was to deploy the Frontend into the main IIS site, and inside it create an application called v1 for the Backend.
Then within my angularJS I defined the Production app to make the http requests to /v1/api instead of /api.

Web api call works locally but not on Azure

I have same issue as per following questions and tried answer but never resolve issue
Web api interface works locally but not on Azure
Web API interface works locally but gets 404 after deployed to Azure Website
and many more similar type of...
When i tried to call api it says 404 Not Found
my WebApi.config file
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "versionApi",
routeTemplate: "api/{version}/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
API Controller
[Authorize]
[RequiresSSL]
[RoutePrefix("api/v2/Configuration")]
public class ConfigurationAPIv2Controller : ApiController
{
[Dependency]
public IConfigurationServicev2 configurationService { get; set; }
[Dependency]
public IAccountService accountService { get; set; }
#region testapi
[Route("getstring")]
[HttpGet]
public IHttpActionResult getstring()
{
return Ok("Success");
}
[Route("putstring")]
[HttpPut]
public IHttpActionResult putstring()
{
return Ok("Success");
}
#endregion
And Folder Structure is like :
i got follwowing issue for both get and Put method
404 error might caused by route issue. Since you are using route attribute for your Web API. Please make sure GlobalConfiguration.Configure(WebApiConfig.Register); is above other code.
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
And config.MapHttpAttributeRoutes(); code is above other routes configuration.
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "versionApi",
routeTemplate: "api/{version}/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
In addition, try to delete following code in your Controller to test whether it is related to the dependent injection module.
[Dependency]
public IConfigurationServicev2 configurationService { get; set; }
[Dependency]
public IAccountService accountService { get; set; }
If it also can't work for you. You could get the detail error message from web server after setting IncludeErrorDetailPolicy property in WebApiConfig class.
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
Visual Studio does not add a default.html page to wwwroot and IIS does.
Just add default.html page to wwwroot in your project, then re-deploy to Azure.

Web Api with Sitecore 8.1

I've been trying to get Web Api to work with Sitecore 8.1.
I installed this package: https://www.nuget.org/packages/Krusen.Sitecore.WebApi.Custom/ and I modified the ConfigureWebApi to the following:
public class ConfigureWebApi
{
public void Process(PipelineArgs args)
{
GlobalConfiguration.Configure(config => config.Routes.MapHttpRoute("API Default", "api/{controller}/{id}",
new { id = RouteParameter.Optional }));
GlobalConfiguration.Configure(config => config.MapHttpAttributeRoutes());
GlobalConfiguration.Configure(ReplaceControllerSelector);
}
private static void ReplaceControllerSelector(HttpConfiguration config)
{
config.Services.Replace(typeof (IHttpControllerSelector),
new CustomHttpControllerSelector(config, new NamespaceQualifiedUniqueNameGenerator()));
}
}
However, whenever I use post requests, I get the following error:
{"Message":"The requested resource does not support http method
'POST'."}. Get requests work.
This is the implementation of the controller:
[RoutePrefix("api/authentication")]
public class AuthenticationController : ApiController
{
[Route("email")]
[HttpPost]
public bool Login([FromBody] string email)
{
return true;
}
}
I figured out what the error was. When my controller was called AuthenticationController it gave the following error:
The requested document was not found
If I called it something else, the web api worked as a charm e.g.
public TestController : ApiController {
//Code goes here
}

Adding Web API 2 manually - getting 404

I've returned to a solution that was put on hold and when I originally created it, I didn't tick Web API. I've added it manually but when I call my URL i'm recieving a 404. I suspect I am missing some configuration but I'm not sure.
My web api controller
[RoutePrefix("search")]
public class SearchController : BaseWebApiController
{
private readonly IAmtProxy _amtProxy;
public SearchController(IAmtProxy amtProxy)
{
this._amtProxy = amtProxy;
}
[HttpGet]
[Route("supportticket/{id}")]
public HttpResponseMessage GetSupportTicket(int id)
{
try
{
var result = _amtProxy.GetSupportTicketById(id);
return GetResponse(result);
}
catch (Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e.Message);
}
}
[HttpGet]
[Route("supportticket")]
public HttpResponseMessage GetAllSupportTickets()
{
try
{
var result = _amtProxy.GetAllSupportTickets();
return GetResponse(result);
}
catch (Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e.Message);
}
}
}
Example of url that returns 404
http://localhost:60541/search/supporticket/1
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: /search/supporticket/1
Application_start in global.asax.cs has this code:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
Bootstrapper.Initialise();
}
I also have my WebApiConfig
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional});
}
}
Finally with nuget I got web api 2 and it installed successfully.
Does anyone know what I could be missing?
Your config looks fine.
It appears that you have misspelled the url:
http://localhost:60541/search/supporticket/1
It should be:
http://localhost:60541/search/supportticket/1
According to your implementation:
[Route("supportticket/{id}")]

web api - message handler attribute routing

Does anyone know whether message handler can work simultaneously with attribute routing in Web API 2.x? I got a custom message handler to work using conventional routing, then after adding attribute routing, it stops working. I am not sure whether it's not supported or if I had misconfigured something. Any help is greatly appreciated.
1) before attribute routing
--- WebApiConfig.cs code snippet (simplified)----
config.Routes.MapHttpRoute(
name:"DefaultApi",
routeTemplate: "api/{controller}",
defaults: null,
constraints: null,
handler: my-message-handler-object
);
--- MyController.cs code snippet (simplified)----
public class MyController : ApiController
{
[HttpGet]
public IHttpActionResult CheckInServices(...)
{
...
}
}
2) after attribute routing
--- WebApiConfig.cs code snippet (simplified)----
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name:"DefaultApi",
routeTemplate:"api/vendor",
defaults: new { controller = "Users" },
constraints: null,
handler: my-message-handler-object
);
}
--- MyController.cs code snippet (simplified)----
[RoutePrefix("api/vendor/{vendorID:long}/service")]
public class MyController : ApiController
{
[HttpPost]
[Route("{serviceID:long}")]
public IHttpActionResult CheckInServices(...)
{
...
}
}
Thanks,
Cody
Global message handlers will work - just set it up on start up.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MessageHandlers.Add(new YourAuthenticationHandler());
}
}
I'm unsure if per route Message Handlers work with Attribute Routing.

Resources