I'm writing an ASP.NET MVC 4 app (I can't use any framework versions newer than 4.0 for this project) with React SPA client.
I have a problem serving static resources like js files and stylesheets. In he heat of a fight I came with something like this:
routes.MapRoute(
name: "Static1",
url: "{filename}.{extension}",
defaults: new { controller = "Home", action = "Static1" }
);
routes.MapRoute(
name: "Static2",
url: "{url}/{filename}.{extension}",
defaults: new { controller = "Home", action = "Static2" }
);
routes.MapRoute(
name: "Static3",
url: "{url1}/{url2}/{filename}.{extension}",
defaults: new { controller = "Home", action = "Static3" }
);
routes.MapRoute(
name: "Empty",
url: "",
defaults: new { controller = "Home", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{*path}",
defaults: new { controller = "Home", action = "Index" }
);
and
public ActionResult Index()
{
return new FilePathResult("~/client/index.html", "text/html");
}
public ActionResult Static1(string filename, string extension)
{
return Redirect(Url.Content($"~/client/{filename}.{extension}"));
}
public ActionResult Static2(string url, string filename, string extension)
{
return Redirect(Url.Content($"~/client/{url}/{filename}.{extension}"));
}
public ActionResult Static3(string url1, string url2, string filename, string extension)
{
return Redirect(Url.Content($"~/client/{url1}/{url2}/{filename}.{extension}"));
}
The problem is that webpack often generates files with multiple dots in their name (ex. main.4395d64a.js) and thus even this already not pretty solution fails. I would rather not create multiple routes for different dot numbers.
Is there a better way?
Related
I have an asp.net web site that won't seem to resolve to Default.aspx when initially loading. When I debug on my local machine it loads Default no problem. Unless I try to navigate to "localhost:#####/". Then it gives a 404 error. When I deploy it to a staging server, give it a virtual path "mywebapp", and load it from "mydomain.com/mywebapp" it gives a 404 as well. I have set Default.aspx to the top of the list for Default Document in IIS. If I navigate to "mydomain.com/mywebapp/default" the site loads just fine. Any suggestions? I would paste code but it is a large website and I quite honestly am not sure what I'm looking for anymore.
EDIT:
In my site I am also using DataTables for display and edit of data. In the ajax calls I was previously able to call the controller by using urls such as:
api/MyController/idvalue
but since uncovering this I had to go back and preface the urls to get them to work:
mywebapp/api/MyController/idvalue
Controller:
public class MyController : ApiController
{
[Route("api/MyContoller/{idvalue}")]
[HttpGet]
[HttpPost]
public IHttpActionResult MyControllerMethod(intidvalue)
{
}
}
WebApiConfig:
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 }
);
}
}
RouteConfig:
public static class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
var settings = new FriendlyUrlSettings();
settings.AutoRedirectMode = RedirectMode.Permanent;
routes.EnableFriendlyUrls(settings);
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//routes.MapRoute(
// name: "Default",
// url: "{controller}/{action}/{id}",
// defaults: new { action = "Index", id = UrlParameter.Optional }
// );
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
Found the solution. In my RouteConfig.cs if I comment out the line:
controller = "Home",
it works just fine.
public static class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
var settings = new FriendlyUrlSettings();
settings.AutoRedirectMode = RedirectMode.Permanent;
routes.EnableFriendlyUrls(settings);
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//routes.MapRoute(
// name: "Default",
// url: "{controller}/{action}/{id}",
// defaults: new { action = "Index", id = UrlParameter.Optional }
// );
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new
{
//controller = "Home",
action = "Index",
id = UrlParameter.Optional
}
);
}
}
However, I'm not completely sure why this is. So if anyone is able to explain it to me that would be great!
my Model is
public class Organization
{
public int ID { get; set; }
public string Url { get; set; }
}
and this is my routeConfig
routes.MapRoute(
"Url",
"{controller}/{action}/{Url}",
new { controller = "Organization", action = "PageContent", Url = "" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Is there a way to fix the routing so that both Url and ID would work?
for example ...Organization/details/{ID} and ...Organization/details/{Url} would both work
As both the routes seems same you can combine both and define one and in the action (or onActionExecuting) you can decide the behavior based ID or URL
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{Segment}",
defaults: new { controller = "Home", action = "Index", Segment = UrlParameter.Optional }
);
Or you can map the route with ID only and take URL as querystring.
So I built a new ASP.NET MVC4 application, some really simple stuff. I added an Area for administration purposes. Everything works fine when I debug on Visual Studio's IIS Express.
The problem comes when I deploy this application on a Windows Server 2012's IIS, most of the time, when I try to acces my Area I get a 404 error. The weired thing is sometimes, after redeploying the application (but not changing anything), the area will work for a certain amount of time (until the application pool gets recycled maybe ?)
Anyway this is really weired and I'd need a hand on this. Here's what I've done :
Here is my RouteConfig for the base application :
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "NewsFilter",
url: "Articles/{tagName}",
defaults: new { controller = "Home", action = "Index", tagName = UrlParameter.Optional },
namespaces: new[] { "myapp.Controllers" }
);
routes.MapRoute(
"ViewArticle",
"Article/{articleId}/{articleTitle}",
new { controller = "Article", action = "Index", articleTitle = UrlParameter.Optional },
new { articleId = #"\d+" },
namespaces: new[] { "myapp.Controllers" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "myapp.Controllers" }
);
}
}
Now here's my AdminAreaRegistration for the Admin area
public class AdminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Admin";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
name: "Admin_default",
url: "Admin/Home/{action}/{id}",
defaults: new { controller="Home", action = "Index", id = UrlParameter.Optional },
namespaces: new []{ "myapp.Areas.Admin.Controllers" }
);
context.MapRoute(
name: "Admin_news",
url: "Admin/News/{action}/{id}",
defaults: new { controller="News", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "myapp.Areas.Admin.Controllers" }
);
context.MapRoute(
name: "Admin_Tags",
url: "Admin/Tags/{action}/{id}",
defaults: new { controller = "Tags", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "myapp.Areas.Admin.Controllers" }
);
}
}
Now here id the Application_Start method from Global.asax
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas(); //This registers the admin Area
WebApiConfig.Register(GlobalConfiguration.Configuration); //I did not delete WebApiConfig even though I'm not using it
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes); //And here are my "normal" routes
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
All the controllers from my Admin area are in the namespace myapp.Areas.Admin.Controllers. The main app controllers are in the namespace myapp.Controllers.
On IIS, the app pool for the application is running in .net 4.0 Integrated mode.
Any idea why the area is working in debug mode, working sometimes on IIS and returning 404 most of the time ?
I have 2 areas in my project:
Areas | Admin
Areas | FrontEnd
What I would like is when I visit the site, the default route should load Controllers / Views / Models from the FrontEnd area. It's normal to have Url/Admin for an admin panel but I would rather not have to force Url/FrontEnd (or some other variation). Basically I don't want to use the Controller / Model / View folders on the root level.
I'm not sure how to change the code to allow this or even it's an advisable method. Could someone provide some guidance please?
What I have:
routes.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new {
area = "Admin",
controller = "Home",
action = "Index",
id = UrlParameter.Optional
},
namespaces: new[] { "WebsiteEngine.Areas.Admin.Controllers" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new {
area = "FrontEnd",
controller = "Home",
action = "Index",
id = UrlParameter.Optional
},
namespaces: new[] { "WebsiteEngine.Areas.FrontEnd.Controllers" }
);
However this produces an error:
The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Home/Index.aspx
~/Views/Home/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Views/Home/Index.cshtml
~/Views/Home/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml
I do have views available in the areas and this doesn't look like it's looking there.
I believe you can just do something like this:
// Areas/Admin/AdminAreaRegistration.cs
public class AdminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get { return "Admin"; }
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
name: "Admin_Default",
url: "Admin/{controller}/{action}/{id}",
defaults: new
{
area = "Admin",
controller = "Home",
action = "Index",
id = UrlParameter.Optional
});
}
}
// Areas/Admin/FrontEndAreaRegistration.cs
public class FrontEndAreaRegistration : AreaRegistration
{
public override string AreaName
{
get { return "FrontEnd"; }
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
name: "FrontEnd_Default",
url: "{controller}/{action}/{id}",
defaults: new
{
area = "FrontEnd",
controller = "Home",
action = "Index",
id = UrlParameter.Optional
});
}
}
// Global.asax.cs
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
...
}
Now, in your RouteConfig class, you probably have a Default route set up. Bear in mind that as long as you call AreaRegistration.RegisterAllAreas before you call RouteConfig.RegisterRoutes, the routes that you set up in the areas may override the routes you set up in RouteConfig. (Routes are evaluated in the order they appear in the Routes collection, and .MapRoute pushes new routes to the end)
I have a front page and a CMS area with the following routes:
Default Front Page route
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new string[] { "SiteFactory.Site.Controllers" }
Administration route
context.MapRoute(
"Administration_default",
"administration/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
I would like to route from my ContentController (inside the administration area) to the front page HomeController, like this:
[HttpPost]
[ValidateInput(false)]
public ActionResult Save(string content, string contentId, string pageId)
{
if (ModelState.IsValid)
{
//TODO: save content.
}
return RedirectToRoute("Default");
}
How can i do this?
just return RidirectToAction("Index", "Home");