I've added Web Api controller to MVC 5 application but all the time I get Error 404 - The resource cannot be found. I've added GlobalConfiguration.Configure(WebApiConfig.Register) to Application_Start()
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
GlobalConfiguration.Configure(WebApiConfig.Register);
}
and I have route registred
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
WebApi routing started to work after I've changed the position of Register api method to be above of register routes:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
If this may help somebody.
In my case the problem was that i deleted default controllers and in RouteConfig.cs file Home controller was still being referenced.
Related
I have a Spring boot 1.5 + Angular5 application utilizing Websockets via SockJS, and was recently forced to upgrade to Spring boot 2.2.
Following the upgrade, my websocket is being closed after either a random period of time, or when a write to the websocket happens. When using Spring Boot 1.5, everything works perfectly.
Below is the configuration in Spring, using spring-boot-starter-websocket version: '2.2.4.RELEASE'
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfiguration extends AbstractWebSocketMessageBrokerConfigurer {
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/api/socket")
.setAllowedOrigins("*")
.withSockJS();
}
#Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app")
.enableSimpleBroker("/nightly");
}
}
I've also added the following security rules:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/api/socket/**")
.cors().and()
.headers().frameOptions().disable().and()
.csrf().disable()
.authorizeRequests()
.anyRequest().permitAll();
}
Client code:
initWebSocket() {
const ws = new SockJS('/api/socket');
this.stompClient = Stomp.over(ws);
const that = this;
this.stompClient.connect({}, () => {
that.stompClient.subscribe('/nightly', (message) => {
this._rootStore.dispatch(new UpdateNightlyAction(message));
});
});
}
When the connection is lost, the client logs the following:
POST https://<url>/api/socket/231/i0rsgjlx/xhr?t=1600673163228 404
Whoops! Lost connection to https://<url>/api/socket
I went through different scenarios of Websockets not working in Spring Boot 2 and nothing seemed to help. In 1.5 it works just fine. What am I missing here?
beacuse of springboot2.0^ is not allow cors param allowedOrigins = "*" , you can overwrite AllowedOriginPatterns equals "*"
boot1.5 ->
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
StompWebSocketEndpointRegistration registration = registry.addEndpoint("/webSocket");
registration.setAllowedOrigins("*");
registration.withSockJS();
}
boot2.0^->
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
StompWebSocketEndpointRegistration registration = registry.addEndpoint("/webSocket");
// boot2.0^ AllowedOrigins = * is not allown
registration.setAllowedOriginPatterns("*");
registration.withSockJS();
}
I had a same error with yours, even search for a long time ,but there is no
answers,so i check the debug log find this problem,i fixed it with this method,it works!
I use swagger2. I configured it to redirect to swagger-ui.html when the use access the root path.
#Bean
public WebMvcConfigurer index() {
return new WebMvcConfigurer() {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addRedirectViewController("/", "/swagger-ui.html");
}
};
}
As I configured in application.yml the context-path as /api, now the when user tries to access /api he is redirected to /api/swagger-ui.html.
But I don't want to display swagger-ui.html at all and leave only /api. Is there a way to achieve that?
you can use below java script on the landing html page
<script>
history.replaceState('data to be passed', 'Title of the page', "/api/");
</script>
I have problem with Spring Security.. I've made a admin role for access to users section and if someone else than Admin want to go there I am redictering to 403 page and it works, but css, plugins and bootstrap are not visible from this context..
Error in browser console if not administrator wants to go there:
(403 page is displaying without bootstrap and css..)
http://prntscr.com/h497qo
Error if administrator wants to go there (no mapping)..
(users page is displaying without bootstrap and css..)
http://prntscr.com/h49b7g
Spring security config:
#Override
protected void configure(final HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/bootstrap/**", "/dist/**", "/plugins/**").permitAll().antMatchers("/admin/**").hasAuthority("ADMIN")
.anyRequest().authenticated().and().formLogin().loginPage("/login").permitAll().and().rememberMe()
.tokenValiditySeconds(60 * 60 * 24 * 31).rememberMeParameter("remember-me").key("uniqueAndSecret").and()
.logout().deleteCookies("JSESSIONID").logoutUrl("/logout").logoutSuccessUrl("/login").permitAll().and().exceptionHandling().accessDeniedPage("/error")
.and().csrf().disable();
}
Any suggestions?
Try something like this :
#Override
public void configure( WebSecurity web ) throws Exception {
web.ignoring().antMatchers( "/bootstrap/**", "/dist/**", "/plugins/**");
}
in you security configuration.
EDIT : ResourceHandler
Add explicitly your static resources :
#Configuration
public class WebViewConfig extends WebMvcConfigurerAdapter {
#Override
protected void addResourceHandlers( ResourceHandlerRegistry registry ) {
registry.addResourceHandler( "/bootstrap/**", "/dist/**", "/plugins/**" ).addResourceLocations( "classpath:static/bootstrap/", "classpath:static/dist/", "classpath:static/plugins/" );
}
}
Note that I suppose you have those folders (dist, bootstrap, plugins) in your classpath under static folder.
try this to fix problem 'no mapping found for':
#Configuration
#EnableWebMvc
public class WebAppConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
I'm using MVC 6 and I have implemented Identity 3.0 for authentication.
I'm trying to prevent the user from clicking on the browser back button after logout. The closest working solution I came across seems to be not working in MVC 6.
Could someone help?
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NoCacheAttribute : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
filterContext.HttpContext.Response.Cache.SetNoStore();
base.OnResultExecuting(filterContext);
}
}
You can use it.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NoCacheAttribute : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
filterContext.HttpContext.Response.Headers.Add("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
filterContext.HttpContext.Response.Headers.Add("Pragma", "no-cache"); // HTTP 1.0.
filterContext.HttpContext.Response.Headers.Add("Expires", "-1"); // Proxies.
base.OnResultExecuting(filterContext);
}
}
WebApi's were working fine, then I added a few odata controllers, now my webapi's return not found. I assume its in the routing somewhere but I don't see it. returns 404 not found. how do I fix my webapi's to return data gain.
Global Config
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
Web API Config
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}/{action}",
defaults: new { id = RouteParameter.Optional }
);
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<pp_tsr_accounts_tab_Result>("pp_tsr_accounts_tab_Result");
config.Routes.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());
config.EnableSystemDiagnosticsTracing();
}
Call
http://localhost:xxx/api/pp_tsr_offer_calc_Result/Getpp_tsr_offer_calc_Result?id=0801314923
well I win the idiot award.
routeTemplate: "api/{controller}/{action}/{id}",
not
routeTemplate: "api/{controller}/{id}/{action}",