Calling Controller HttpGet method by actionLink - asp.net

I think I read almost all threads about actionLink and HttpGet but I don’t get the routing done.
In my startup class I have the default routing:
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}"
);
I call a website by the controller:
public class CollectionController : Controller
{
public async Task<IActionResult> Collection()
{
var viewModel = new CollectionViewModel();
…
return await Task.Run(() => View("~/Views/Sccm/Collection.cshtml", viewModel));
}
And in the View I will call another method in the controller to query more information:
#Html.ActionLink(linkText: item.DistinguishedName ?? "Not Found", actionName: "GetCollection", controllerName: "Collection",
routeValues: new { hostname = item.DistinguishedName }, htmlAttributes: null)
The method in the same controller looks like that but is never called (breaking point):
[HttpGet]
[ValidateAntiForgeryToken]
public async Task<IActionResult> GetCollection(string hostname)
{
Console.WriteLine("Hostname is: " + hostname);
return View();
}
I noticed that when I change routing in HttpGet I also get linked to another URL, but I never access the function. I assume I am missing some small detail. Any hint would be welcomed.
Thanks
Stephan
Maybe my problem is that the View is in another subfolder then die Controller name
Edit:
Damn it :(, I used the ValidateAntiForgeryToken in a getMethod

try this:
HttpGet("{hostname}")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> GetCollection(string hostname)
{
Console.WriteLine("Hostname is: " + hostname);
return View();
}

Related

How can I achieve a in-url routing in asp.net core?

I am trying to achieve a routing style such as:
mydomain.com/some-slug-text-a-123
The last digits is the Id of the particular resource and the 'a' before that will represent the resource. Resources might be a for Article, p for Product and so on. Obviously for each resource I have a separate controller and my challange starts here.
In this case, apart from using the Home controller and serving all the content depending on the resource provided, is there a routing configuration specific to this scenario?
I am sorry if this has been an opinion based question but don't know how else to ask.
You have multiple ways to achive that. I'll will give you two examples, but I suggest taking a look into Asp.Net Routing documentation
Option 1 (Multiple Convetional Routes)
Map new route conventions on Startup.cs (method Configure)
app.UseEndpoints(endpoints =>
{
// Map articles (a)
endpoints.MapControllerRoute(name: "a",
pattern: "{*slug}-a-{*id}",
defaults: new { controller = "Blog", action = "Article" });
// Map products (p)
endpoints.MapControllerRoute(name: "p",
pattern: "{*slug}-p-{*id}",
defaults: new { controller = "Store", action = "Product" });
// Default routing
endpoints.MapControllerRoute(name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
Create a controller and action that receive the parameters setted on your route convetion:
public class BlogController : Controller
{
[HttpGet]
public ActionResult Article(string slug, int id)
{
// Your code here
}
}
Option 2 (Attribute routing)
Map new route conventions on Startup.cs (method Configure)
app.UseEndpoints(endpoints =>
{
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Add the attribute [Route("")] to your controller and/or action. I put the attribute just on action to simplify the example
public class BlogController : Controller
{
[Route("/{slug}-a-{id}")]
public ActionResult Article(string slug, int id)
{
// Your code here
}
}
public class StoreController : Controller
{
[Route("/{slug}-p-{id:int}")] // ":int means that the route will only accept an valid integer on this route; otherwiase will return NotFound
public ActionResult Product(string slug, int id)
{
// Your code here
}
}

Mvc customize routes

I just want to customize routes in asp.net mvc ,
This is a blog website and I want to access controller methods using
wwww.sitename.com/blog/{blogtitle}
www.sitename.com/blog/{action}
Blog Controller
public class BlogController : Controller
{
public ActionResult Index(string title)
{
return View();
}
[Route("post-blog")]
[HttpPost]
public ActionResult Post(Blog blog,HttpPostedFileBase blogimage)
{
//some coe
}
[Route("post-blog")]
public ActionResult Post()
{
if (Request.Cookies["userInfo"]==null)
{
return Redirect("/login");
}
return View();
}
}
Here is route Config
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//routes.Canonicalize().Www();
routes.Canonicalize().Lowercase();
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "freelogomaker", id = UrlParameter.Optional }
);
}
But I am unable to hit action name "Index" using www.site.com/blog/titlename
But I can access "post-blog" using www.site.com/blog/post-blog
Please help me I am beginner in asp.net mvc routing.
Add your parameter to the route attribute within {} brackets to indicate that it should be read from the URL, and not from something else (such as POST body, dependency injections, etc)
[Route("{title}")]
public ActionResult Index(string title)
{
return View();
}
I also like to add the RoutePrefix attribute to the controller to make it a bit clearer.
[RoutePrefix("blog")]
public class BlogController : Controller

ASP.NET MVC 5 not seeing "{id}" route in controller

I've created a new ASP.NET MVC 5 project in Visual Studio 2015 Update 3, and everything is pretty standard. I have this controller:
public class UsersController : BaseController
{
[HttpGet]
public async Task<ActionResult> Newest()
{
var newestUsers = await Database.Users.OrderByDescending(u => u.ID).Take(100).ToListAsync();
return View(newestUsers);
}
[HttpGet]
[Route("{id}")]
public async Task<ActionResult> GetUser(long id)
{
var user = await Database.Users.FindAsync(id);
return View(user);
}
}
My BaseController derives from regular MVC Controller and it contains some common properties for my app. Nothing special.
When I go to /users/newest the appropriate page loads, but when I go to /users/1 I immediately get a 404 not found error. I've tried changing the route to ~/{id} but no avail. My route configuration is the standard, auto-generated one, I haven't touched it:
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 }
);
}
}
Why am not hitting the GetUser action?
UPDATE: For some reason, it started not working again. I didn't do anything. It was working after I've added routes.MapMvcAttributeRoutes();, it's still there but I started getting 404 again.
Okay I have no idea how it went away (or why it wasn't there) but I was missing the routes.MapMvcAttributeRoutes(); method in route configuration. Adding that method fixed the issue.
UPDATE: I've also needed to add RoutePrefix to get the routes working, and I have to explicitly add the correct route for any actions that have arguments. It's a pity that MVC can't map them by themselves.
Get ride of your additional Id routing above getuser - this isn't needed.
Your route is incorrect - it should be users/getuser/1

Asp.Net routing to action with parameters

I have a routing config file with a following routing settings
routes.MapRoute(
name: "Login",
url: "Account/login/{username}/{password}",
defaults: new { controller = "Account", action = "Login"}
);
and I have a Login action in an Account Controller
[HttpPost]
public ActionResult Login(string username, string password)
{
// do some
}
[HttpGet]
public ActionResult Login()
{
//do some
}
I just want to call first action, with parameters not the second
Can you help me to fix this problem?
The first one is POST and second one is GET. So the HTTP verb which you use for calling will decide what gets called.

Multiple actions within a controller

Currently I have a controller which is named (Manage). I want it to have links such as
Manage/Users/{userid}/{manageType}
Manage/Pages/{pageid}/{manageType}
Where the action manageType can be (Settings, Username, Description).
What is the best way to structure this in my Manage Controller so I can have all these attributes? Is it possible for there to be multiple actions functions that was within other actions? For example
ManageController
-> viewResult Users(int userID)
-> viewResult Pages(int pageID)
-> viewResult Type(string typeID)
Where the Users and Pages will point to the type after it gets the ID's from the link.
"Is it possible for there to be multiple actions functions that was within other actions?"
How would that work? Action methods are just regular .NET methods - actions within actions don't really make sense.
If you want it all in one controller, you will have to have something like this:
public ActionResult UserSettings(int userid) { /*...*/ }
public ActionResult UserName(int userid) { /*...*/ }
public ActionResult UserDescription(int userid) { /*...*/ }
public ActionResult PageSettings(int userid) { /*...*/ }
public ActionResult PageName(int userid) { /*...*/ }
public ActionResult PageDescription(int userid) { /*...*/ }
You could wire up routing like this:
routes.MapRoute(
name: "Default",
url: "Manage/Users/{userid}/Settings",
defaults: new { controller = "Manage", action = "UserSettings" },
constraints = new { userid = #"\d+" }
);
etc.

Resources