Displaying Another View in ASP.Net Web API Client - c#

New to the world of Web API and I can't seem to get any custom view to display. I've done the basics, made a method in my controller that seems to be linked corrected where I'm calling it. I'm more familiar with MVC so I'm wondering am I missing something basic here? The view always returns an error can't be accessed for me.
The ActionResult, in the generated HomeController:
[HttpGet]
public ActionResult SpotDetails()
{
ViewBag.Title = "Spot Details";
return View();
}
The link to call it in the menu:
<ul class="nav navbar-nav">
<li>#Html.ActionLink("SHOR //", "Index", "Home", new {area = ""}, null)</li>
<li>#Html.ActionLink("Index", "Index", "Home", new {area = ""}, null)</li>
<li>#Html.ActionLink("Spot Profile", "SpotDetails", "Home", new {area = ""}, null)</li>
<li>#Html.ActionLink("API", "Index", "Help", new {area = ""}, null)</li>
</ul>
I should say the links to the index and the api help pages work perfectly.
This is my RouteConfig in case it's at fault, I haven't touched it at all:
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 }
);
}
And finally my WebApiConfig:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.Formatters.Remove(config.Formatters.XmlFormatter);
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling =
Newtonsoft.Json.ReferenceLoopHandling.Ignore;
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
Edit - the error message when the link is clicked:
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: /Home/SpotDetails

Most likely this is an issue with your startup configuration. Routes must be registered in order from most specific to least specific. You have accounted for that within your RouteConfig.RegisterRoutes and WebApiConfig.Register methods. However, you must also call WebApiConfig.Register before RouteConfig.RegisterRoutes or your Default route will take precedence over any of the Web API routes.
WebApiConfig.Register(GlobalConfiguration.Configuration);
RouteConfig.RegisterRoutes(RouteTable.Routes);

Related

Is it possible to host Asp.net MVC web App locally [duplicate]

In asp.net MVC the "homepage" (ie the route that displays when hitting www.foo.com) is set to Home/Index .
Where is this value stored?
How can I change the "homepage"?
Is there anything more elegant than using RedirectToRoute() in the Index action of the home controller?
I tried grepping for Home/Index in my project and couldn't find a reference, nor could I see anything in IIS (6). I looked at the default.aspx page in the root, but that didn't seem to do anything relevent.
Thanks
Look at the Default.aspx/Default.aspx.cs and the Global.asax.cs
You can set up a default route:
routes.MapRoute(
"Default", // Route name
"", // URL with parameters
new { controller = "Home", action = "Index"} // Parameter defaults
);
Just change the Controller/Action names to your desired default. That should be the last route in the Routing Table.
ASP.NET Core
Routing is configured in the Configure method of the Startup class. To set the "homepage" simply add the following. This will cause users to be routed to the controller and action defined in the MapRoute method when/if they navigate to your site’s base URL, i.e., yoursite.com will route users to yoursite.com/foo/index:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=FooController}/{action=Index}/{id?}");
});
Pre-ASP.NET Core
Use the RegisterRoutes method located in either App_Start/RouteConfig.cs (MVC 3 and 4) or Global.asax.cs (MVC 1 and 2) as shown below. This will cause users to be routed to the controller and action defined in the MapRoute method if they navigate to your site’s base URL, i.e., yoursite.com will route the user to yoursite.com/foo/index:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Here I have created a custom "Default" route that will route users to the "YourAction" method within the "FooController" controller.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "FooController", action = "Index", id = UrlParameter.Optional }
);
}
Step 1: Click on Global.asax File in your Solution.
Step 2: Then Go to Definition of
RouteConfig.RegisterRoutes(RouteTable.Routes);
Step 3: Change Controller Name and View Name
public class RouteConfig
{
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 }
);
}
}
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Your Controller", action = "Your Action", id = UrlParameter.Optional }
);
}
}
Attribute Routing in MVC 5
Before MVC 5 you could map URLs to specific actions and controllers by calling routes.MapRoute(...) in the RouteConfig.cs file. This is where the url for the homepage is stored (Home/Index). However if you modify the default route as shown below,
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
keep in mind that this will affect the URLs of other actions and controllers. For example, if you had a controller class named ExampleController and an action method inside of it called DoSomething, then the expected default url ExampleController/DoSomething will no longer work because the default route was changed.
A workaround for this is to not mess with the default route and create new routes in the RouteConfig.cs file for other actions and controllers like so,
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Example",
url: "hey/now",
defaults: new { controller = "Example", action = "DoSomething", id = UrlParameter.Optional }
);
Now the DoSomething action of the ExampleController class will be mapped to the url hey/now. But this can get tedious to do for every time you want to define routes for different actions. So in MVC 5 you can now add attributes to match urls to actions like so,
public class HomeController : Controller
{
// url is now 'index/' instead of 'home/index'
[Route("index")]
public ActionResult Index()
{
return View();
}
// url is now 'create/new' instead of 'home/create'
[Route("create/new")]
public ActionResult Create()
{
return View();
}
}
check RegisterRoutes method in global.asax.cs - it's the default place for route configuration...
I tried the answer but it didn't worked for me. This is what i ended up doing:
Create a new controller DefaultController. In index action, i wrote one line redirect:
return Redirect("~/Default.aspx")
In RouteConfig.cs, change controller="Default" for the route.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Default", action = "Index", id = UrlParameter.Optional }
);
If you don't want to change the router, just go to the HomeController
and change MyNewViewHere in the index like this:
public ActionResult Index()
{
return View("MyNewViewHere");
}

Change MVC Routes

I have hosted a ASP.NET MVC website on IIS 7.5. The problem is that the site name and controller name are same, due to this I have to enter the controller name twice.
I am not allowed to change the name of the site or controller. My current URL for eg.
local/home/home/action
but I have shared as
localhost/home/action
now I need to configure the application so that the application routes properly for
localhost/home/action
If you are using MVC5 you can use the Route attribute. Like so:
[Route(“yourroot”)]
public ActionResult Index() { … }
More information can be found here Attribute Routing in ASP.NET MVC 5
Hope this helps
Try to add a new route to RouteConfig.cs before others routes like:
routes.MapRoute(
name: "DefaultHome",
url: "{action}/{id}",
defaults: new { controller = "Home", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
...

ASP.NET MVC 4 Parameters Separated by Forward Slashes "/" not passing args properly

I am trying to follow a convention used by many sites that pass in arguments with multiple forward slashes, as opposed to using the GET model.
That is, I am looking to consume a URL like:
http://www.foo.bar/controller/action?arg1=a&arg2=b&arg3=c
In this fashion:
http://www.foo.bar/controller/action/a/b/c
I currently have this (mostly) working, using the following:
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 }
);
routes.MapRoute(
name: "Sandbox",
url: "Sandbox/{action}/{*args}",
defaults: new { controller = "Sandbox", action = "Index", args = UrlParameter.Optional }
);
}
However, if I pass in something like
http://www.foo.bar/Sandbox/Index/a
or
http://www.foo.bar/Sandbox/Index/a/
The Controller and action are appropriately called:
public ActionResult Index(string args)
{
return View();
}
but args is null.
However, if I pass in something like:
http://www.foo.bar.com/Sandbox/Index/a/b
Then args is "a/b", as desired.
I have been scouring SO and the rest of the web, but can't seem to find the solution.
Is there something obvious I am missing to correct this behavior?
Am I looking for the wrong terminology?
Note: I was able to repro this issue with a brand new ASP.NET application using Windows Authentication. All that was done:
Create ASP.NET application in VS 2015
Choose MVC
Click on Change Authentication
Select Windows Authentication
Add the above Map Route to RouteConfig.cs
Create SandboxController.cs and add the args parameter to Index
Create the Index.cshtml view
Repro the problem using http://localhost:55383/Sandbox/Index/a
Repro the expected behavior using http://localhost:55383/Sandbox/Index/a/b
Any help is very appreciated. Thank you!
Similar question, but doesn't help me: URLs with slash in parameter?
Never mind... Here is the problem...
The MapRoute is calling the default route, first.
To fix it, I just swapped the Default map route with the Sandbox route.
I hope this helps someone.
Working Solution:
public class RouteConfig {
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Sandbox",
url: "Sandbox/{action}/{*args}",
defaults: new { controller = "Sandbox", action = "Index", args = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}

Get URL for Route Prefix in ASP.NET WEB API in Razor view

I have a Web API 2 API Controller
[RoutePrefix("things")]
public class ThingsController : APIController
{
[Route("{thingId}", Name="Things.Get")]
public Thing Get(string thingId)
{
//snip...
}
}
And all is well... except I'd like to pass the URL for that route into some JS so that it can construct URLs to request Things
So in the razor view I've tried
myJavascriptObject.thingUrl = '#Url.Action("Get", "Things", new {area=""})';
but I get a blank string
I've tried giving the controller route an explicit name and using
#Url.RouteUrl("Things.Get", new {areas="", thingId="foo"}") b
ut that's an empty string too.
Am I being silly? Should this work?
Update after more trying of things.
On an MVC controller (Where I need to know the API Controller route)
var something = Url.Action("Get", "Things", new {area = ""});
var somethingWithId = Url.Action("Get", "Things", new { area = "", siteId = "fakeId" });
var somethingElse = Url.RouteUrl(new {Action = "Get", Controller = "Things", Area = ""});
var somethingElseWithId = Url.RouteUrl(new { Action = "Get", Controller = "Things", Area = "", siteId = "fakeId" });
These are all null.
If I remove the area="" condition then I get a route but with the Area name in it and the route doesn't have the area name in it.
?!
TL;DR - if something is weird spike it in a fresh environment
Leaving an answer here in the very remote case it helps someone else.
As somebody pointed out to me that this worked for them I created a new MVC & API project and looked at the default routing.
Ours looked like this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "home",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new [] { "Another.Project.Controllers" }
);
}
WAT?
I replaced it with the default route config:
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 }
);
}
Everything else still works and I can get the route I want.
We definitely aren't using the other namespace in this project and I'm guessing that namespaces was introduced either when this solution was part of another one (which it did use to be) or by the refactoring that moved it.
And so I've reached the natural conclusion of any really annoying bug: "How did this ever work?!"

MVC 4 URL routing to absorb old legacy urls and forward to new domain

My domain used to point to a wordpress site where I had set up specific pages using the following format:
www.mydomain.com/product/awesome-thing
www.mydomain.com/product/another-thing
Recently I transferred my domain and now it points to an MVC version of my site. The links mentioned above are no longer valid, however the wordpress site still exists with a different domain. I'm trying to get my mvc site to absorb the previous links and forward them to
http://mydomain.wordpress.com/product/awesome-thing
http://mydomain.wordpress.com/product/another-thing
what I have right now is the following in the RouteConfig.cs
routes.MapRoute(
name: "product",
url: "product/{id}",
defaults: new { controller = "product", action = "redirect", id = UrlParameter.Optional });
and in my product controller I have the following
public void redirect(string id)
{
if (id == "awesome-thing")
{
Response.Redirect("http://mydomain.wordpress.com/product/awesome-thing ");
}
if (id == "another-thing")
{
Response.Redirect("http://mydomain.wordpress.com/product/another-thing");
}
Response.Redirect(" http://mydomain.wordpress.com/");
}
However my routing in RouteConfig.cs is not linking up correctly with my controller. I keep getting "404 The resource cannot be found" error.
I managed to solve this issue by reordering my map routes. I also changed the code in the controller and the maproute a bit, the following code ended up working.
routes.MapRoute(
name: "productAwesome",
url: "product/awesome-thing",
defaults: new { controller = "product", action = "redirectAwsome" });
routes.MapRoute(
name: "productAnother",
url: "product/another-thing",
defaults: new { controller = "product", action = "redirectAnother" });
//it's important to have the overriding routes before the default definition.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
then in the product controller I added the following:
public class productController : Controller
{
public void redirectAwsome()
{
Response.Redirect("http://mydomain.wordpress.com/product/awesome-thing ");
}
public void redirectAnother()
{
Response.Redirect("http://mydomain.wordpress.com/product/another-thing");
}
}

Categories