Multiple controller matching the request in attribute based routing asp.net MVC - c#

This is regarding to how to define routes in controller of asp.net mvc
1st controller
[AllowAnonymous]
[Route("contact/Login")]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
2nd controller
[Route("{CategoryURL}/{Keywords}")]
public ActionResult BrowseProducts(string CategoryURL, string Keywords)
{
}
I am getting below error If try to access URL abc.com/contact/Login
Multiple controller types were found that match the URL. This can
happen if attribute routes on multiple controllers match the requested
URL. The request has found the following matching controller types:
abc.Controllers.AccountController abc.Controllers.CoursesController
My question is, I want to validate {CategoryURL} input's and also want to access URL "abc.com/contact/Login"

Related

Why Should we assign a Http Attribute to every action in controller

I having a question should we assign a http attribute for each action?
Like for example Index Page that doesn't have any action just displaying html we still need to assign a http attribute? Why since there is no retrieving data.
And If I remove Http Attribute for ViewDetail and CreateRecord, the page is still working and no bug what the huge difference for adding and not adding http attribute
public ActionResult Index()
{
return View();
}
[HttpGet]
public ActionResult ViewDetail()
{
//.... Get Data Action
return Redirect(Url.Action("Edit","Home"));
}
[HttpPost]
public ActionResult CreateRecord()
{
//.... Create Action
return Redirect(Url.Action("Edit","Home"));
}
There may be some methods in your Controller class that are not HTTP Endpoints.

Route parameters and multiple controller types

I have a asp.net web api, using attributes for routing on the controllers. There are no route attriutes on the action level. The route for accessing a resource is:
[Route("{id}"]
public MyApiController: ApiController
{
public HttpResponseMessage Get(Guid id)
{
// ...
}
}
My problem is that when I want to create a search controller, I'd like the URL to be
[Route("search")]
But this results in an error: Multiple controller types were found that match the URL. Is it possible to make sure the exact matching route is selected before the generic one?
Technically, the phrase search could be a valid ID for the first controller, but as {id} is a guid, this will never be the case, thus I'd like to select the controller with the exact matching route.
You can use Route constraints to do the job. For example you could constraint your ID route to accept only valid GUID's.
Here is an ID controller that accepts only GUID strings in the URL:
[System.Web.Http.Route("{id:guid}")]
public class MyApiController: ApiController
{
public HttpResponseMessage Get(Guid id)
{
return new HttpResponseMessage(HttpStatusCode.OK);
}
}
The Search controller would match to an url like "/search". Here is the Search controller:
[System.Web.Http.Route("search")]
public class SearchController : ApiController
{
public HttpResponseMessage Get()
{
return new HttpResponseMessage(HttpStatusCode.OK);
}
}
Constraints will prevent matching conflicts in the router.

oauth redirecting in asp.net mvc4

I will try to implement redirect with oauth authorization in asp.net mvc4 project
controller
public ActionResult SomeName() {
if (!User.Identity.IsAuthenticated) {
return RedirectToAction("ExternalLogin", "Account", new { provider = "vkontakte" });
}
}
account
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ExternalLogin(string provider) {
return new ExternalLoginResult(provider, Url.Action("ExternalLoginCallback"));
}
error
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: /Account/ExternalLogin
Does anybody know what I should to do?
try this:
[HttpGet]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ExternalLogin(string provider) {
return new ExternalLoginResult(provider, Url.Action("ExternalLoginCallback"));
}
By using RedirectToAction you are making a GET request to the url of your action, you need to accept HttpGet at ExternalLogin action on your AccountController
RedirectToAction is 302 redirect request which is GET by nature. if you are supposed to utilize your action from VIEW as well, you can use both verbs :
[HttpGet, HttpPost]
at ExternalLogin action on your AccountController accept HttpGet as other member also said.

MVC4 Ignoring [HttpGet] and [HttpPost] attributes

I am attempting to make a simple test website to allow me to list, create, edit and delete customer objects using MVC4.
Inside my controller I have 2 create methods, a Get for when the form loads with the controls, and a Post that actually saves the data.
//
// GET: /Customer/Create
[HttpGet]
public ActionResult Create()
{
return View();
}
//
// POST: /Customer/Create
[HttpPost]
public ActionResult Create(Customer cust)
{
if (ModelState.IsValid)
{
_repository.Add(cust);
return RedirectToAction("GetAllCustomers");
}
return View(cust);
}
However when I run the project and attempt to access the create action I get an error that:
The current request for action 'Create' on controller type 'CustomerController' is ambiguous between the following action methods:
System.Web.Mvc.ActionResult Create() on type [Project].Controllers.CustomerController
System.Web.Mvc.ActionResult Create([Project].Models.Customer) on type [Project].Controllers.CustomerController
My I understand that it can't see the difference between my Get and Post methods, but I have added the attribues. What could be the cause of this and how can I make it work again?
MVC does not authorize you to have 2 action methods with the same name.
BUT you can have 2 action methods with the same URI when the http verb differs (GET, POST). Use the ActionName attribute to set the action name. Don't use the same methods names. You can use any name. A convention is to add the http verb as the method suffix.
[HttpPost]
[ActionName("Create")]
public ActionResult CreatePost(Customer cust)
{
if (ModelState.IsValid)
{
_repository.Add(cust);
return RedirectToAction("GetAllCustomers");
}
return View(cust);
}

Using the ASP.NET MVC Attribute Based Route Mapper

In my ASP.NET MVC application, I want to use this ASP.NET MVC Attribute Based Route Mapper, first announced here.
So far, I understand how to implement code that uses it, but I've run into a few questions that I think those who have used this attribute-based route mapper in the past will be able to answer.
How do I use it with ActionResults that are for HTTP POSTs? In other words, how does it work with form submissions and the like? Should I just put the URL of the GET method in, or should I use the GET method URL without any parameters (as in HTTP POST they aren't passed in through the URL)?
How do I use it with "URL querystring parameters"? Can the attribute be configured to map to a route such as /controller/action?id=value rather than /controller/action/{id}?
Thanks in advance.
How do I use it with ActionResults
that are for HTTP POSTs?
You decorate the action that you are posting to with the [HttpPost] attribute:
[Url("")]
public ActionResult Index() { return View(); }
[Url("")]
[HttpPost]
public ActionResult Index(string id) { return View(); }
If you decide to give the POST action a different name:
[Url("")]
public ActionResult Index() { return View(); }
[Url("foo")]
[HttpPost]
public ActionResult Index(string id) { return View(); }
You need to supply this name in your helper methods:
<% using (Html.BeginForm("foo", "home", new { id = "123" })) { %>
How do I use it with "URL querystring
parameters"?
Query string parameters are not part of the route definition. You can always obtain them in a controller action either as action parameter or from Request.Params.
As far as the id parameter is concerned it is configured in Application_Start, so if you want it to appear in the query string instead of being part of the route simply remove it from this route definition:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoutes();
routes.MapRoute(
"Default",
"{controller}/{action}",
new { controller = "Home", action = "Index" }
);
}

Categories

Resources