I'm having a problem where the action in my controller called GiftCards is over-writing the actual URL/View page name.
public IActionResult SomeStupidName()
{
return ("Checkout");
}
my url turns into
www.mywebsite.com/GiftCards/SomeStupidName
while I want it to be
www.mywebsite.com/GiftCards/Checkout
Some further detail would be that this is execute with an form-submit where the form has an
asp-action="SomeStupidName"
You have to understand that www.mywebsite.com/GiftCards/SomeStupidName means SomeStupidName is an action of controller GiftCards so www.mywebsite.com/GiftCards/Checkout means Checkout is an action of controller GiftCards but in your code you are returning View from GiftCards action not redirecting to other action. Lets suppose I have action name Checkout.
public IActionResult Checkout()
{
return View("Checkout");
}
It will return the view Checkout when I enter www.mywebsite.com/GiftCards/Checkout so now I can redirect to action from any other action like:
public IActionResult SomeStupidName()
{
return RedirectToAction("Checkout");
}
You can use "Attribute Routing" in Asp.Net Core. Return the proper view in your controller.Try this code !!
[Route("GiftCards/Checkout")]
public IActionResult SomeStupidName()
{
return View("Checkout");
}
Attribute routing is set of attributes to map actions directly to route templates. We can mention rewrite url inside the "()" in "[Route("")]" Attribute.
More details about attribute routing in Asp.net core : click here
Related
In my ASP.Net (.net 4.7 + MVC5) web application I have an action Search() which leads to the an error after authorising the user. The error is as follows:
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: /Search
Version Information: Microsoft .NET Framework Version:4.0.30319;
ASP.NET Version:4.7.2106.0
The action is implemented as follows:
[Authorize]
[Route("Search")]
[HttpPost]
public ActionResult Search(SearchViewModels passedQuery)
{
//Action working code here
return View("~/Views/Home/Search.cshtml", passedQuery);
}
Form submission code as follows:
#using (Html.BeginForm("Search", "Home"))
{
<div class="form-group">
#Html.TextBoxFor(m => m.Content, new { #class = "form-control" })<br />
<button type="submit" class="btn btn-danger">SEARCH</button>
</div>
}
If I take the [HttpPost] out from the action then during debugging mode the application works perfectly even after authorising the user (No error thrown). But without using the [HttpPost] the code does nothing on the production server.
Can someone help with:
Why the error message is shown when [HttpPost] is used with
[Authroize]?
When and why to use [HttpPost]? (I have referred to few posts and
documents regarding the usage of HttpPost and HttpGet but still I
am finding it liitle hard to grasp the concept of their
appropriate usage [1], [2])
I am very new to ASP.Net and MVC development and any help is really appreciated. Thank you.
This line which returns a view makes no sense:
return View("~/Views/Home/Search.cshtml", passedQuery);
In proper usage, just use view name instead of its complete virtual path with extension and ensure that the Search method belongs to HomeController:
[Authorize]
public class HomeController : Controller
{
[HttpPost]
public ActionResult Search(SearchViewModels passedQuery)
{
return View("Search", passedQuery); // or just return View(passedQuery)
}
}
Note that AuthorizeAttribute requires authorized users who meet the specified requirements to access the method, so it's no use to set it on POST methods while submitting the form which already loaded. You need to specify AuthorizeAttribute on controller class when users requesting page they're wanted to view based from authentication roles, and set AllowAnonymousAttribute on methods which you're allow anonymous users to get through.
Hence, your Search action pair should constructed like this example:
[Authorize]
public class HomeController : Controller
{
// other stuff
[Route("Search")]
[HttpGet] // getting search page request
[AllowAnonymous] // allow anonymous users to load search page
public ActionResult Search()
{
return View();
}
[HttpPost] // posting content using inserted values on form
[AllowAnonymous] // allow anonymous users to load search page
public ActionResult Search(SearchViewModels passedQuery)
{
return View("Search", passedQuery); // or just return View(passedQuery)
}
// other stuff
}
I am creating a asp.net mvc 4 application
public class AspNetController : Controller
{
//
// GET: /AspNet/
public ActionResult Index()
{
return View();
}
public ActionResult Introduction()
{
return View();
}
}
as Shown Above There is AspNet Controller and Introduction Action Method
Default Url for Introduction Action Method is
localhost:55134/aspnet/introduction
But I Want Url Like
localhost:55134/aspnet/introduction-To-AspNet
Same for
/localhost:55134/aspnet/NetFrameWork To
/localhost:55134/aspnet/What-is-.Net-Framework
How to do that
You should be able to use the ActionName attribute to decorate your routes.
[ActionName("Introduction-To-AspNet")]
public ActionResult Introduction()
{
return View();
}
You really want to use AttributeRouting, either via a 3rd party package or natively if you can.
Technically this concept comes under Routing in ASP.NET MVC.
For this you need to do an entry for route in App_Start->RouteConfig.cs file under RegisterRoutes(RouteCollection routes)
For Example:
routes.MapRoute(
"customRouteName",
"aspnet/introduction-To-AspNet",
new { controller = "AspNet", action = "Introduction" });
here aspnet/introduction-To-AspNet will append after your base url i.e. localhost:55134/
The quick and dirty answer is to add a route to your ~/AppStart/RouteConfig.cs file and it will be taken care of:
routes.MapRoute(
name: "CustomRoute",
url: "Aspnet/Introduction-To-AspNet",
defaults: new { controller = "Home", action = "AspNet", id = UrlParameter.Optional }
);
However, I'm assuming this is for some type of blog? I would reccomend that you have an action method called view, and then use your name as a parameter for the article. That way, you don't have to go in and edit the code every time you add a new article or other content:
public class ArticlesController : Controller
{
public ActionResult ViewArticle(string? title)
{
ViewBag.Article = title;
return View();
}
}
that way, your URL would be www.yoursite.com/Articles/ViewArticle/Introduction-To-AspNet. In general, you don't want to add tons of specific routes to your route config if you can avoid it. That being said, if this is a legacy system, the route table may be the only way.
EDIT
Ok, so what you can do is pass the string into the ViewBag and use a case statement to determine which partial view to show (I think this just might be your ideal solution):
<!--cshtml view-->
#switch(ViewBag.Article)
{
case 'Introduction-To-AspNet':
#Html.Partial('pathToPartialView.cshtml')
break;
case 'Some-Other-Article'
#Html.Partial('pathToAnotherPartialView.cshtml')
break;
...
...
default:
#Html.Partial('invalidArticleName.cshtml')
break;
}
The controller will pass the article name through the ViewBagand then you can use the case statement to figure out which article to render... and of course, the real secret sauce you've been looking for: #Html.Partial('URL') - this will take your partial and render it right were you put that in the page. You can also pass objects to that just as an FYI.
In addition, make sure that you have a default action on the switch statement that will show some sort of 404 page that indicates that the name in the URL was invalid. You ALWAYS want to have this anytime you're taking user input from the URL because people monkey with URLs all the time (and more innocently, copy+paste them wrong/incompletely all the time)
I'm beginning to use WebApi and I'm having an issue with a URL being incorrectly generated
I have an ApiController like this:
public class EntriesController : ApiController
{
public HttpResponseMessage Post(Entry entry)
{
...
}
}
And I was trying to create a standard controller (i.e. not webapi) in the same project to test this api (I already tested the api with fiddler and everything is ok there).
I assumed I could use the standard HTML helpers like this:
#using (Html.BeginForm("Post", "Entries"))
However this generates the following markup:
<form action="/Entries/Post" method="post">
and I expected it to generate
<form action="/api/Entries" method="post">
What is the correct way to generate the API url from a view?
I am using the default api and controller routes.
Thanks
#using (Html.BeginForm("Post", "Entries"))
You can not put WebAPI controller and method in MVC BeginForm like above. You need to pass MVC Controller and action to the BeginForm.
You can create a WebAPI EntriesController instance in your MVC controller, then use this instance to call the WebAPI method. See below:
//MVC Controller
public class EntriesController : Controller
{
[HttpGet]
public ActionResult Entries()
{
return View();
}
[HttpPost]
public ActionResult Entries(SomeModels model)
{
if (ModelState.IsValid)
{
var api = new EntriesController(); // Create WebAPI instance Here
api.Post(model.entry);
return RedirectToAction("Index", "Home");
}
return View();
}
}
This is technically possible by doing:
#using (Html.BeginForm("Post", "api/Entries"))
Don't forget, the "Post" value in the .BeginForm() extension method doesn't mean anything to an out-of-box Web Api route setup. Only the url and HTTP action matter (and any additional values on the URL for method overloading)
You would need to use BeginRouteForm as link generation to Web API routes always depends on the route name. Also make sure to supply the route value called httproute as below.
#using (Html.BeginRouteForm("DefaultApi", new { controller="Entries", httproute="true" }))
I am working on an MVC application and I have an index view where I pass model from controller to index view. The index action has no parameters. Now On view I have a jquery calendar. I want to change all the data on view when a date is selected. do I need to use different action method for this as current action method doesn't have parameter. or I can use same ? Please suggest
Sounds like you need a DateTime parameter on that index view. You can then handle the case where it is null in the action:
public ActionResult Index(DateTime dateTime)
{
if (dateTime == null)
//Do default view
else
//Use date for view
}
Use a client-side event handler on the calendar, and call a different action on the controller via jQuery.ajax()
http://api.jquery.com/jQuery.ajax/
You can create the same Action method to handle both:
[HttpGet]
public ActionResult DoThis() { }
[HttpPost]
public ActionResult DoThis(FormCollection data) { }
It can be the same action, but it has to be a different action handler to handle the post to the server, where the post is from a form or a JQuery call.
I am working on a very simple application, using MVC2 Preview 1.
I have a controller named ContentController. My problem is that /Content/Index works correctly, but /Content/ returns a 404. I am running the application on the Studio Development Server.
Tested with RouteDebugger but /Content/ returns a 404, and does not display any debugging information.
I have not changed the routing code:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
This is my controller:
public class ContentController : Controller
{
IRepository _repo = new SimpleRepository("db", SimpleRepositoryOptions.RunMigrations);
public ActionResult Index()
{
var content = _repo.GetPaged<Content>(0, 20);
return View(content);
}
It's a shot in the dark, but do you have a directory named /Content/ as well?
/Content is a controller, which is basically just a collection of actions. ASP.NET MVC needs to know WHICH action you want to run, so by leaving out the action asp.net mvc doesn't know what action to return and gives a 404.
You can tell it a default either by adding a route:
eg:
routes.MapRoute("ContentDefault", "Content", new {controller = "Content", action = "Index"});
The attributes are defined as follows:
'ContentDefault`: Name of the Route (must be unique in your routing table)
Content: The URL segment (try changing this to 'Content/Much/Longer/URL' and then go to http://localhost/Content/Much/Longer/URL to see how this works)
new {controller=.., action=...}: which controller/action combo to run for this route.
You could also override HandleUnknownAction in your controller:
protected override void HandleUnknownAction(string actionName)
{
return RedirectToAction("index");
}
Oh and incidentally, an extra piece of advice about routing.... if you add something to the route in braces { } these will be passed to the action as an attribute.
e.g. /Content/Much/Longer/Url/{page}
so the URL http://localhost/Content/Much/Longer/Url/999
will pass the 999 into your action, as the page attribute
public ActionResult Index(int Page) { }
I love MVC - never going back to WebForms - this is how web development should be!