I'm working on building a MVC4 web app and want to set specific URL I would like to use in the start point of my web application.
So I changed some values in RouteConfig.cs like this below.
routes.MapRoute(
name: "Default",
url: "{action}.mon/{id}",
defaults: new { controller = "login", action = "index", id = UrlParameter.Optional }
);
you may notify this, but I put a suffix after action name, so that I could invoke a controller, displaying the URL like " index.mon "
if I manually put "index.mon" after host address in URL bar, then it works just okay.
But when the app gets started automatically, it throws 403.14 error. ( "automatically start" means here that I ran this app by putting F5 key to run a temporary IIS server. )
the login controller looks like this
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.OleDb;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Monarch815MVC.Controllers
{
public class loginController : Controller
{
//
// GET: /login/
public ActionResult index()
{
return View();
}
public ActionResult loginProcess(string id = "000000", string pass = "example", string scode = "co")
{
Dictionary<string, object> sessionData = null;
String SqlCommand = "USP_LOGIN";
DataSet UserInfo = dataController.ExecuteDataset(dataController.CONN_STRING, CommandType.StoredProcedure, SqlCommand, arParms);
if (UserInfo.Tables[0].Rows.Count > 0)
{
sessionData = new Dictionary<string, object>();
for (int i = 0; UserInfo.Tables[0].Rows[0].Table.Columns.Count > i; i++)
{
sessionData.Add(UserInfo.Tables[0].Rows[0].Table.Columns[i].Caption, UserInfo.Tables[0].Rows[0].ItemArray[i]);
}
}
return View();
}
}
}
( let's forget about the loginProcess, I took off a few codes. )
Do I have to do something on returning phase in index() or on Web.config? or, RouteConfig.cs?
I have to use the suffix ".mon" to invoke controllers with it.
I could think of solving this issue by only using a hack. You might want to create a dummy action which will be the default action and upon being hit will redirect the request to your index.mon
i tried following, Please check if this helps you. Thanks.
In the route config
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "DefaultY",
url: "{action}-mon/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "DefaultX2",
url: "{action}/{id}",
defaults: new { controller = "Home", action = "Startup", id = UrlParameter.Optional }
);
}
In controller
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Startup()
{
return RedirectToRoute("DefaultY", new {controller = "Home", action = "Index" });
}
}
For me i used index-mon. index.mon was not working (something which i'l explore later, perhaps it relates to static files), but above code demonstrates the approach.
Hope that helps.
Related
I'm having trouble getting ASP.net MVC to serve up the default controllers index view for the root site url http://mysite:8080/. All I get back is a 404 with The resource cannot be found. It works fine if I specify the full route path in the url : http://mysite:8080/Default/Index, however, I want the default route to apply even if the user doesn't specify the route path though. It seems that this should just work out of the gate. This is a fresh project from the VS2013 MVC 4 template.
I've tried both route mappings below and neither seems to work. How can this be achieved?
routes.MapRoute(
"Root",
"",
new { controller = "DefaultController", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "DefaultController", action = "Index", id = UrlParameter.Optional }
);
Here is a solution to this problem. It's disappointing that the default route's defaults do not apply for the root site url though.
routes.Add(new Route("", new SiteRootRouteHandler("~/Default/Index")));
public class SiteRootRouteHandler : IRouteHandler
{
private readonly string _redirectUrl;
public SiteRootRouteHandler(string redirectUrl)
{
_redirectUrl = redirectUrl;
}
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new SiteRootHandler(_redirectUrl);
}
}
public class SiteRootHandler: IHttpHandler
{
private readonly string _redirectUrl;
public SiteRootHandler(string redirectUrl)
{
_redirectUrl = redirectUrl;
}
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
context.Response.RedirectPermanent(_redirectUrl);
}
}
I was wondering how to setup routing in my MVC4 application where I can have a controller named TMZ and have it handle all of these routes:
/TMZ/About
/TMZ/Webinars
/TMZ/News
/TMZ/Conferment
/TMZ/CustomerCare
/TMZ/Marketing/Emails
/TMZ/Marketing/Brochures
/TMZ/Marketing/Print
/TMZ/Marketing/Press
/TMZ/Marketing/Presentations
/TMZ/Marketing/Graphics
/TMZ/Marketing/OCSRY
/TMZ/Marketing/Resources
/TMZ/Marketing/DesignStandards
/TMZ/Marketing/Videos
/TMZ/Marketing/PromoKits
/TMZ/Faculty/Forms
/TMZ/Faculty/Reports
/TMZ/CE/Guides
/TMZ/CE/Reports
/TMZ/Academy/Papers
/TMZ/Academy/Books
/TMZ/Academy/Promotions
/TMZ/ManualOfOperations
Showing Code:
Here is my RouteConfig.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace LicenseeArchive
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("TMZ",
"TMZ/{action}/{subaction}/{id}",
new { controller = "TMZ", action = "Index", subaction = UrlParameter.Optional, id = UrlParameter.Optional },
null,
new[] { "LicenseeArchive.Web.Controllers" });
routes.MapRoute("Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
null,
new[] { "LicenseeArchive.Web.Controllers" });
}
}
}
Here is my Global.asax.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
namespace LicenseeArchive
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
}
}
}
Here is my TMZController:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace LicenseeArchive.Controllers
{
public class TMZController : Controller
{
//
// GET: /TMZ/
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
return View();
}
public ActionResult Marketing(string subaction)
{
string _view = "Index";
switch (subaction)
{
case "Brochures":
_view = "Marketing/Brochures";
break;
}
return View(_view);
}
}
}
And here is my View folder structure:
Views
Account
Login.cshtml
Manage.cshtml
Register.cshtml
Home
About.cshtml
Contact.cshtml
Index.cshtml
Shared
_Footer.cshtml
_Head.cshtml
_HeaderBlock.cshtml
_Layout.cshtml
_LeftAside.cshtml
_LoginPartial.cshtml
_TopNav.cshtml
Error.cshtml
TMZ
Academy
Books.cshtml
Papers.cshtml
Promotions.cshtml
CE
Guides.cshtml
Reports.cshtml
Faculty
Forms.cshtml
Reports.cshtml
Marketing
Emails.cshtml
Brochures.cshtml
Print.cshtml
Press.cshtml
Presentations.cshtml
Graphics.cshtml
OCSRY.cshtml
Resources.cshtml
DesignStandards.cshtml
Videos.cshtml
PromoKits.cshtml
About.cshtml
Conferment.cshtml
CustomerCare.cshtml
News.cshtml
ManualOfOperations.cshtml
Webinars.cshtml
_ViewStart.cshtml
Web.Config
The simplest way would be modify the "default" route in Global.asax.cs
routes.MapRoute("Default",
"{controller}/{action}/{subaction}/{id}",
new {subaction= UrlParameter.Optional, id = UrlParameter.Optional});
This would mean you could use the same url format in other Controllers as well. Your TMZController would look something like:
public class TMZController : Controller
{
public ActionResult About()
{
return View();
}
public ActionResult Marketing(string subaction)
{
return View();
}
}
Because the subaction/id are both optional you can construct 2, 3 or 4-part urls and just pickup the extra parameters in your actions, then handle them as required within the body of the methods.
routes.MapRoute("TMZ",
"TMZ/{action}/{id}",
new {controller = "TMZ", action = "Index", id = UrlParameter.Optional},
null,
new[] {"YourNamespace.Web.Controllers"});
routes.MapRoute("Default",
"{controller}/{action}/{id}",
new {controller = "Home", action = "Index", id = UrlParameter.Optional},
null,
new[] {"YourNamespace.Web.Controllers"});
In this case i assumed that you've a Controller named TMZ and in that controller you've set all other actions including Marketing, Academy, Faculty, CE
But here is two things important to consider
This route should be before the default route "as I put it here"
The Actions in the TMZController should have an string id parameter to handle the request. this id would be passed something like "Resources" for the Marketing action or "Books" for Academy Action.
Hope this was clear.
I want to go to http://myserver and be able to get Help Pages as the default home page, so the first thing a guest to http://myserver should see is the Help Page.
I have a default route set up like this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Then I have my Help Page Area registration set up like this:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"HelpPage_Default",
"doc/{action}/{apiId}",
new { controller = "Help", action = "Index", apiId = UrlParameter.Optional });
HelpPageConfig.Register(GlobalConfiguration.Configuration);
}
When I change RouteConfig's controller to "Help" I get:
The view 'Index' or its master was not found or no view engine
supports the searched locations
When I change Help Page route to "{controller}/{action}/{apiId}" my AttributeRoutes stop working.
Is there some easy way to make ASP.NET Help Pages default home page?
I accomplished this with the following RouteConfig. I am also using ASP.Net Help Pages to auto-generate my documentation from the inline XML comments:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// By default route the user to the Help area if accessing the base URI.
routes.MapRoute(
"Help Area",
"",
new { controller = "Help", action = "Index" }
).DataTokens = new RouteValueDictionary(new { area = "HelpPage" });
}
}
I should also mention that I don't have any other routing in this class since I am using Attribute Routing on API methods individually.
For those who search where to add the route, with the current version of the WebApi and of the NuGet package you have to search for the file named "HelpPageAreaRegistration" in the Area folder added by NuGet.
Here is mine once it was coded to have the help page with WebApi has default web page.
public class HelpPageAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "HelpPage";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"HelpPage_Default",
"Help/{action}/{apiId}",
new { controller = "Help", action = "Index", apiId = UrlParameter.Optional });
context.MapRoute(
"Help Area",
"",
new { controller = "Help", action = "Index" }
);
HelpPageConfig.Register(GlobalConfiguration.Configuration);
}
}
i am trying to create a stackoverflow like url.
I the following example works fine. But if i remove the controller then it errors out.
http://localhost:12719/Thread/Thread/500/slug-url-text
Note the first Thread is the controller the second is the action.
How can i make the above URL look like the following excluding the controller name from the url?
http://localhost:12719/Thread/500/slug-url-text
My Routes
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("Default", // Route name
"{controller}/{action}/{id}/{ignoreThisBit}",
new
{
controller = "Home",
action = "Index",
id = "",
ignoreThisBit = ""
}); // Parameter defaults )
}
}
Thread Controller
public class ThreadController : Controller
{
//
// GET: /Thread/
public ActionResult Index()
{
string s = URLFriendly("slug-url-text");
string url = "Thread/" + 500 + "/" + s;
return RedirectPermanent(url);
}
public ActionResult Thread(int id, string slug)
{
return View("Index");
}
}
Placing the following route before the default route definition will directly call the 'Thread' action in 'Thread' controller with the 'id' and 'slug' parameter.
routes.MapRoute(
name: "Thread",
url: "Thread/{id}/{slug}",
defaults: new { controller = "Thread", action = "Thread", slug = UrlParameter.Optional },
constraints: new { id = #"\d+" }
);
Then if you really want it to be like stackoverflow, and assume someone enters the id part and not the slug part,
public ActionResult Thread(int id, string slug)
{
if(string.IsNullOrEmpty(slug)){
slug = //Get the slug value from db with the given id
return RedirectToRoute("Thread", new {id = id, slug = slug});
}
return View();
}
hope this helps.
In ASP.NET MVC, we have #Url.Action for actions. Is there something similar like #Url.Api which would route to /api/controller?
The ApiController has a property called Url which is of type System.Web.Http.Routing.UrlHelper which allows you to construct urls for api controllers.
Example:
public class ValuesController : ApiController
{
// GET /api/values
public IEnumerable<string> Get()
{
// returns /api/values/123
string url = Url.Route("DefaultApi", new { controller = "values", id = "123" });
return new string[] { "value1", "value2" };
}
// GET /api/values/5
public string Get(int id)
{
return "value";
}
...
}
This UrlHelper doesn't exist neither in your views nor in the standard controllers.
UPDATE:
And in order to do routing outside of an ApiController you could do the following:
public class HomeController : Controller
{
public ActionResult Index()
{
string url = Url.RouteUrl(
"DefaultApi",
new { httproute = "", controller = "values", id = "123" }
);
return View();
}
}
or inside a view:
<script type="text/javascript">
var url = '#Url.RouteUrl("DefaultApi", new { httproute = "", controller = "values", id = "123" })';
$.ajax({
url: url,
type: 'GET',
success: function(result) {
// ...
}
});
</script>
Notice the httproute = "" route token which is important.
Obviously this assumes that your Api route is called DefaultApi in your RegisterRoutes method in Global.asax:
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
It works with the simpler form of Url.Action thus you don't have to reference any Routing names:
Url.Action("ActionName", "ControllerName", new { httproute = "DefaultApi" })
You might want to add an area = "" if the URL is needed within an Area. (Api controllers are outside of Areas by default.) I'm using MVC 4.
Want to be able to generate links in a typesafe manner, without hardcoded strings (controller names)?
There's a nuget for that! (and it's written by Mark Seeman)
https://github.com/ploeh/Hyprlinkr
Works like this:
Routes, as usual:
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
Get an URL:
var linker = new RouteLinker(request);
var uri = linker.GetUri<FooController>(r => r.GetById(1337));
Result:
http://localhost/api/foo/1337
Here is the KISS method for answering the question:
If this is the code that you would use to create a MVC controller URL
#Url.Action("Edit", "MyController")
In order to get a URL for the API version of the controller (assuming you use the same controller name) you can use
#Url.Action("Edit", "api/MyController")
All the Url.Action method is doing is appending the root path of the application, with the controller name, followed by the action name (unless it is "Index" in which case it is not appended. if the route values object has an id property the value is also appended to the URL.