I have MVC Web Api project. Based on this project I created REST Api controller:
public class ViewConfigFileController : ApiController
{
public string Get()
{
string result = string.Empty;
try
{
result = File.ReadAllText(System.Web.Hosting.HostingEnvironment.MapPath("~/Config/configData.xml"));
}
catch (Exception)
{
result = "Error read XML file!";
}
return result;
}
}
I want create manual route:
routes.MapRoute(
name: "ViewConfigFile",
url: "ViewConfigFile/Get/{id}",
defaults: new { controller = "ViewConfigFile", action = "Get", id = UrlParameter.Optional }
);
After start application I see error: Application doesn't found.
So, How can I fix it?
Thanks in advance.
You need "{controller}" and "{action}" placeholder in your route config.
Try change your route config to following one.
routes.MapRoute(
name: "ViewConfigFile",
url: "{controller}/{action}/{id}",
defaults: new { controller = "ViewConfigFile", action = "Get", id = UrlParameter.Optional }
);
Related
I currently have the following url implemented:
https://example.com/controller/challenge/{params}
and would like to create a second url that accepts a different set of parameters: https://example.com/controller/v2/challenge/{params}.
I cannot seem to get the "v2" to be hardcoded into the url path. Rather, the only way I can make it work at the moment is using https://example.com/controller/challengev2/{params}
In my configuration file:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "controller", action = "Challenge", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "ChallengeV2",
url: "{controller}/{action}/{id}",
defaults: new { controller = "controller", action = "Challengev2", id = UrlParameter.Optional }
);
My controller is set up like:
public async Task<ActionResult> Challenge(string resumePath, string refid, string client_id)
{
}
[ActionName("Challengev2)]
public async Task<ActionResult> Challenge(string refid)
{
}
I have tried modifying the url when defining the route to:
routes.MapRoute(
name: "ChallengeV2",
url: "controller/v2/Challenge/{id}",
defaults: new { controller = "controller", action = "Challengev2", id = UrlParameter.Optional }
);
But this seems to throw a 404 error. Is there a step that I am missing to create that endpoint?
Switch the order you define your routes. The order plays an extremely important role.
routes.MapRoute(
name: "ChallengeV2",
url: "controller/v2/Challenge/{id}",
defaults: new { controller = "controller", action = "Challengev2" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "controller", action = "Challenge", id = UrlParameter.Optional }
);
To create a v2 route prefix, I would recommend you to use route attribute instead of route map.
Using route attribute, your code would be like this:
public class ChallengeController
{
[Route("/challenge/{resumePath}/{refid}/{client_id}")]
public async Task<ActionResult> Challenge(string resumePath, string refid, string client_id)
{
// ...
}
[Route("/v2/challenge/{refid}")]
public async Task<ActionResult> Challenge(string refid)
{
// ...
}
}
I want create route config multiple Url. ex: "fr-ca/user/login" and "en-ca/user/login" and its working, but if click submit and proccess data by controller and return RedirectToAction(MVC.User.Dashboard); always return "fr-ca/user/dashboard";
Although I use Url "en-ca/", and always return all link MVC.anything in first is "fr-ca/"
Because in position route config, "fr-ca" is first.
Maybe somebody can help me to solve this, thank u.
routes.MapRoute(
name: "fr-Default",
url: "fr-ca/{controller}/{action}/{id}",
defaults: new { controller = MVC.Content.Name, action = MVC.Content.ActionNames.Show, id = UrlParameter.Optional, siteId = Site.FR.Id },
namespaces: new string[] { "Jay.Cms.Web.Controllers" }
);
routes.MapRoute(
name: "en-Default",
url: "en-ca/{controller}/{action}/{id}",
defaults: new { controller = MVC.Content.Name, action = MVC.Content.ActionNames.Show, id = UrlParameter.Optional, siteId = Site.EN.Id },
namespaces: new string[] { "Jay.Cms.Web.Controllers" }
);
You can write to action attribute in controller
'[Route("fr-ca/{controller}/{action}/{id}")]
[Route("en-ca/{controller}/{action}/{id}")]
public ActionResult Home()
{
return View();
}'
I'm using ASP.NET MVC 4 with C#. I'm using areas and it's named like "Admin"
Here is my route config;
public static class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(name: "PageBySlug",
url: "{slug}",
defaults: new {controller = "Home", action = "RenderPage"},
constraints: new {slug = ".+"});
routes.MapRoute(name: "Default",
url: "{controller}/{action}/{id}",
defaults: new {controller = "Home", action = "Index", id = UrlParameter.Optional},
namespaces: new[] { "Web.Frontend.Controllers.Controllers" });
}
}
I generated frontend page links like; "products/apple-iphone"
So I want to call them like this.
But the error is: The code can't get the controller / action method.
I used frontend page links like;
#Html.ActionLink(linkItem.Title, "RenderPage", routeValues: new {controller = "Home", slug = linkItem.PageSlug})
#Html.RouteLink(linkItem.Title, routeName: "PageBySlug", routeValues: new { controller = "Home", action = "RenderPage", slug = linkItem.PageSlug })
#linkItem.Title
#linkItem.Title
They are rendering url links like; http://localhost:1231/products/apple-iphone
It's like what I want. But when I click any link, asp.net mvc gives me this error:
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: /products/apple-iphone
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.6.1069.1
Here is my controller;
namespace Web.Frontend.Controllers
{
public class HomeController : BaseFrontendController
{
public ActionResult Index()
{
return View();
}
public ActionResult RenderPage(string slug)
{
return View();
}
}
}
So how can I catch every link request like this combined slug and turn my coded view ?
The problem is, When you request products/iphone, the routing engine don't know whether you meant the slug "products/iphone" or the controller "products" and action method "iphone".
You can write a custom route constraint to take care of this. This constraint will check whether the slug part of the urls is a valid controller or not, if yes,the controller action will be executed.
public class SlugConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName,
RouteValueDictionary values, RouteDirection routeDirection)
{
var asm = Assembly.GetExecutingAssembly();
//Get all the controller names
var controllerTypes = (from t in asm.GetExportedTypes()
where typeof(IController).IsAssignableFrom(t)
select t.Name.Replace("Controller", ""));
var slug = values["slug"];
if (slug != null)
{
if (controllerTypes.Any(x => x.Equals(slug.ToString(),
StringComparison.OrdinalIgnoreCase)))
{
return false;
}
else
{
var c = slug.ToString().Split('/');
if (c.Any())
{
var firstPart = c[0];
if (controllerTypes.Any(x => x.Equals(firstPart,
StringComparison.OrdinalIgnoreCase)))
{
return false;
}
}
}
return true;
}
return false;
}
}
Now use this route constraint when you register your custom route definition for the slug. make sure you use {*slug} in the route pattern. The * indicates it is anything(Ex : "a/b/c")(Variable number of url segments- more like a catch all)
routes.MapRoute(name: "PageBySlug",
url: "{*slug}",
defaults: new { controller = "Home", action = "RenderPage" },
constraints: new { slug = new SlugConstraint() }
, namespaces: new string[] { "Web.Frontend.Controllers.Controllers" });
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
, new string[] { "Web.Frontend.Controllers.Controllers" });
you can provide only this type of link
#linkItem.Title
Because Routetable find your route using Route name provided by you. so controller name and action name is not necessary.
I am having trouble implementing the routing in MVC 5. While debugging the expected url(e.g. http://localhost/Download/Blog/1cf15fe6033a489a998556fedeab20a2/Test/1cd15fe6033a489a998556fedeab20a2) causes the correct method on the Download controller to be called however the did and fid are always null. What am I doing wrong? I also tried removing the Download route and defining the routes in the controller with the following attributes:
[RoutePrefix("Download")] //on the controller
[Route("{action}/{did:guid}/Test/{fid:guid}")] //on the Blog Action
Here is what I have in my RouteConfig.cs:
routes.MapRoute(
name: "Download",
url: "Download",
defaults: new { controller = "Download", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new {
controller = "Home",
action = "Index",
id = UrlParameter.Optional
}
);
here is my controller:
[Route("{action}/{did}/Test/{fid}")]
public class DownloadController : Controller
{
public ActionResult Index()
{
return Redirect(HandleBadResponse(webResponse));
}
[Route("{action}/{did}/Test/{fid}")]//nope
public ActionResult Blog(HttpRequestMessage request,string did,string fid)
{
string server = Request.ServerVariables["SERVER_NAME"];
string pathStr = #"\\mypath\1cf15fe6033a489a998556fedeab20a2.xls";
byte[] fileBytes = System.IO.File.ReadAllBytes(pathStr);
string fileName = "test.txt";
return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}
I got the expected result by adding the following to my RouteConfig.cs I placed this route at the top of my RegisterRoutes method, I think you should go from most detailed route to the least detailed route:
routes.MapRoute(
name: "DownloadBlogAttachment",
url: "Download/Blog/{did}/fid/{fid}",
defaults: new { controller = "Download", action = "Blog"}
);
I removed the Route attributes in my controller as well.
New to MVC and the API template, familiar with C#.
Plain new WebAPI project with a simple controller. Url path like /api/Clients/1, is there a way to sort of nest controllers? Or execute a function in the same controller by following a url path like this: /api/Clients/1/Sysinfo/typeOf?
I have a model Client which contains properties which are sysinfo items. /api/Clients/1 returns all the properties of an object Client with the Id of 1. I want only specific items returned with /api/Clients/1/Sysinfo/RAM for example.
#Joachim Rosskopf
I have tried that approach. It result in a 404. /clients/1/ works. /clients/1/sysinfo does not work.
Using the following routes:
routes.MapRoute(
name: "Sysinfo",
url: "Clients/{id}/Sysinfo/{type}",
defaults: new { controller = "Sysinfo", type = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Created a new controller SysinfoController:
public class SysinfoController : ApiController
{
public Sysinfo GetAllSysinfoItems()
{
return new Sysinfo { Id = 1, RAM = "1GB" };
}
public IHttpActionResult GetSysinfoByType(int id)
{
return Ok();
}
}
You have to adjust your routing configuration and add special entries for the child routes. It is important to add the most specific route first:
routes.MapHttpRoute(
name: "SysInfoApi",
routeTemplate: "api/Clients/{id}/Sysinfo/{param}",
defaults: new { controller = "SysInfo", param = RouteParameter.Optional }
);
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
In the Above example there is a specific route for a SysInfo controller, which handles the nested resource. As well as the default route.
The SysInfo controller with actions for GET-requests could look the following
public class SysInfoController : ApiController
{
// GET api/client/{id}/sysinfo/
public string Get(int id)
{
return "value";
}
// GET api/client/{id}/sysinfo/{param}
public string Get(int id, string param)
{
return "value";
}
}
I don't know of a method to handle hierarchical ressources in WebApi automatically.