I can't to call action method in the controller from view - c#

I want to call the "Delete Person" method from the "Home" controller on the link provided by the "Index" view, but get the error: "could not find this resource": HTTP 404, URL: /Home/DeletePerson/1. I tried #Html.ActionLink, but it doesn't work either. Where is my mistake?
The project has .NET Framework 4.7.2, Entity Framework 6.2.0, MVC 5.
This project has HomeController:
public class HomeController : Controller
{
...
public ViewResult Index()
{
...
return View("Index");
}
[HttpGet]
public ActionResult DelelePerson(int id)
{
...
return View(person);
}
[HttpPost]
public ActionResult DeletePersonConfirmed(int id)
{
...
return RedirectToAction("Index");
}
}
My Index.cshtml includes
<td><p>Del</p></td>

First, use Html.ActionLink to create the correct link They are aware of your specific routing configuration. Second, your link should probably look like "/Home/DeletePerson?id=#b.id", but that depends on your routing configuration which you haven't posted.

Related

How to override Controller's name in asp.net mvc core?

In my MVC controller, i have two action methods which are rendering View, other 6 Action Methods are either HttpGet or HttpPost. I want to do the below
for ActionMethods rendering View it will be "controller/action". But for the GET/POST, i want it to be api/whatevernameilike.
Is it acheivable in asp.net mvc core?
TIA
Worth trying as well if the previous methods aren't working:
[HttpGet("/api/whatevernameilike")]
Attribute Routing in ASP.NET Web API 2 has an example for this:
Use a tilde (~) on the method attribute to override the route prefix:
[RoutePrefix("api/books")]
public class BooksController : ApiController
{
// GET /api/authors/1/books
[Route("~/api/authors/{authorId:int}/books")]
public IEnumerable<Book> GetByAuthor(int authorId) { ... }
// ...
}
Routing to controller actions in ASP.NET Core shows the following:
[Route("[controller]/[action]")]
public class HomeController : Controller
{
[Route("~/")]
[Route("/Home")]
[Route("~/Home/Index")]
public IActionResult Index()
{
return ControllerContext.MyDisplayRouteInfo();
}
public IActionResult About()
{
return ControllerContext.MyDisplayRouteInfo();
}
}
In the preceding code, the Index method templates must prepend / or ~/ to the route templates. Route templates applied to an action that begin with / or ~/ don't get combined with route templates applied to the controller.
You can use route attribute on top of your controller
ex:
[Route("Api/Yourchosenname")]
public async Task<IActionResult> Action()
{
return Ok();
}

Multiple controller types were found that match the URL in mvc app

I have a weird bug using attribute routing with the following two controllers:
[Route("{action=Index}")]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
[RoutePrefix("search")]
[Route("{action=Index}")]
public class SearchController : Controller
{
public ActionResult Index(string searchTerm)
{
return View();
}
}
And in the route config:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
As you can see, the second controller should have a prefix of search
However if I go to dev.local/search?searchterm=test
I get the error
The request has found the following matching controller types:
Marshalls.WebComponents.Web.Controllers.SearchController
Marshalls.WebComponents.Web.Controllers.HomeController
If I remove the [Route("{action=Index}")] from the homecontroller, it will work fine, but then I cannot get to the homepage using http://dev.local/
This hasn't happened before and usually works ok so I'm wondering if anyone can spot anything obvious I have messed up
Add RoutePrefix for HomeController and move Route from controller to methods/actions.
Empty string in Route and RoutePrefix attributes means that this controller or action is default.
http://dev.local/ => HomeController and Index action
http://dev.local/search?searchTerm=123 => SearchController and Index action
Please keep in mind that only one controller can have empty RoutePrefix and only one action in controller can have empty Route
[RoutePrefix("")]
public class HomeController : Controller
{
[Route("")]
public ActionResult Index()
{
return View();
}
}
[RoutePrefix("search")]
public class SearchController : Controller
{
[Route("")]
public ActionResult Index(string searchTerm)
{
return View();
}
}

How can I generate specific Url

How to generate some URL like http://mysite/some-id using below method?
Note: I do not want to use controller name and action name in url. because the main site used this structure and my boss does not want to change it.
public class StoryController : Controller
{
public ActionResult Index(string id)
{
if(id =="some-id"){
}
return View();
}
}
I don't know what version of MVC you are using, but if you are on the newest version or .NET Core, if you used routing attributes, you'd achieve this by:
[Route("")]
public class StoryController : Controller
{
[Route("{id}")]
public ActionResult Index(string id)
{
if(id =="some-id"){
}
return View();
}
}
Having a single parameter that is a string on your index-like route will definitely pose problems later with the routing engine though, when you try to add more controllers and views

Asp.net MVC - Area Attribute Routing is not working

I have code like below
[RouteArea("Client")]
public Class LoginController : Controller {
[Route("register")]
public ActionResult SignUp() {
return View();
}
}
Attribute routing unfortunately is not working in the areas :/, if I will remove "register" route for signup, it will work just for for client/signup, but with route "register" it is not working.
I have added [RouteArea()], tried with [RoutePrefix] but nothing is working correctly "Route Area" just enabled to use it with views (before that Razor couldn't find the view).
What am I doing wrong ?
Ok I HAVE FOUND THE SOLUTION.
1 Remove Area registration class from your area
2 Use this convention :
[RouteArea("Client")]
[RoutePrefix("login")]
[Route("{action}")]
public class LoginController : Controller
{
[Route("")]
// GET: Client/Login
public ActionResult Index()
{
return View();
}
[Route("register")]
// GET: client/login/register
public ActionResult SignUp()
{
return View();
}
}
Now you can use any route you want, with any prefix :)

GET and POST methods with the same Action name in the same Controller [duplicate]

This question already has answers here:
MVC [HttpPost/HttpGet] for Action
(4 answers)
Closed 2 years ago.
Why is this incorrect?
{
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
Some Code--Some Code---Some Code
return View();
}
[HttpPost]
public ActionResult Index()
{
Some Code--Some Code---Some Code
return View();
}
}
How can I have a controlller thas answer one thing when is "getted" and one when is "posted"?
Since you cannot have two methods with the same name and signature you have to use the ActionName attribute:
[HttpGet]
public ActionResult Index()
{
// your code
return View();
}
[HttpPost]
[ActionName("Index")]
public ActionResult IndexPost()
{
// your code
return View();
}
Also see "How a Method Becomes An Action"
While ASP.NET MVC will allow you to have two actions with the same name, .NET won't allow you to have two methods with the same signature - i.e. the same name and parameters.
You will need to name the methods differently use the ActionName attribute to tell ASP.NET MVC that they're actually the same action.
That said, if you're talking about a GET and a POST, this problem will likely go away, as the POST action will take more parameters than the GET and therefore be distinguishable.
So, you need either:
[HttpGet]
public ActionResult ActionName() {...}
[HttpPost, ActionName("ActionName")]
public ActionResult ActionNamePost() {...}
Or,
[HttpGet]
public ActionResult ActionName() {...}
[HttpPost]
public ActionResult ActionName(string aParameter) {...}
I like to accept a form post for my POST actions, even if I don't need it. For me it just feels like the right thing to do as you're supposedly posting something.
public class HomeController : Controller
{
public ActionResult Index()
{
//Code...
return View();
}
[HttpPost]
public ActionResult Index(FormCollection form)
{
//Code...
return View();
}
}
To answer your specific question, you cannot have two methods with the same name and the same arguments in a single class; using the HttpGet and HttpPost attributes doesn't distinguish the methods.
To address this, I'd typically include the view model for the form you're posting:
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
Some Code--Some Code---Some Code
return View();
}
[HttpPost]
public ActionResult Index(formViewModel model)
{
do work on model --
return View();
}
}
You received the good answer to this question, but I want to add my two cents. You could use one method and process requests according to request type:
public ActionResult Index()
{
if("GET"==this.HttpContext.Request.RequestType)
{
Some Code--Some Code---Some Code for GET
}
else if("POST"==this.HttpContext.Request.RequestType)
{
Some Code--Some Code---Some Code for POST
}
else
{
//exception
}
return View();
}
Can not multi action same name and same parameter
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(int id)
{
return View();
}
althought int id is not used
You can't have multiple actions with the same name. You could add a parameter to one method and that would be valid. For example:
public ActionResult Index(int i)
{
Some Code--Some Code---Some Code
return View();
}
There are a few ways to do to have actions that differ only by request verb. My favorite and, I think, the easiest to implement is to use the AttributeRouting package. Once installed simply add an attribute to your method as follows:
[GET("Resources")]
public ActionResult Index()
{
return View();
}
[POST("Resources")]
public ActionResult Create()
{
return RedirectToAction("Index");
}
In the above example the methods have different names but the action name in both cases is "Resources". The only difference is the request verb.
The package can be installed using NuGet like this:
PM> Install-Package AttributeRouting
If you don't want the dependency on the AttributeRouting packages you could do this by writing a custom action selector attribute.
Today I was checking some resources about the same question and I got an example very interesting.
It is possible to call the same method by GET and POST protocol, but you need to overload the parameters like that:
#using (Ajax.BeginForm("Index", "MyController", ajaxOptions, new { #id = "form-consulta" }))
{
//code
}
The action:
[ActionName("Index")]
public async Task<ActionResult> IndexAsync(MyModel model)
{
//code
}
By default a method without explicit protocol is GET, but in that case there is a declared parameter which allows the method works like a POST.
When GET is executed the parameter does not matter, but when POST is executed the parameter is required on your request.

Categories