I have been at this for an hour now and I haven't got a clue what I am doing wrong.
I got the following ActionLink:
#Html.ActionLink("Remove", "RemoveActivity", "Dashboard", new { id = a.Id },htmlAttributes: null)
This targets the following Method in my DashboardController:
[HttpPost]
public ActionResult RemoveActivity(int id)
{
activityRepo.Delete(activityRepo.GetById(id));
return RedirectToAction("ActivityDetails");
}
For some reason this error gets returned:
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: /Dashboard/RemoveActivity/564
A table row with the Id of 564 does exist in the database. It worked a few hours ago.
Any help is appreciated. I am clueless!
EDIT:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace HaarlemFestival_Web
{
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 }
);
}
}
}
#Html.ActionLink() generates a <a> tag which makes a GET, not a POST. You need to include a <form> element and submit the value to your POST method
#using (Html.BeginForm("RemoveActivity", "Dashboard", new { id = a.Id }))
{
<input type="submit value="Remove" />
}
and you can style your submit button to look like a link if that is what you want visually
I also suggest you add the #Html.AntiForgeryToken() method in the <form> and add the [ValidateAntiForgeryToken] attribute to your method to prevent CSRF attacks.
You should also consider validating that the current user does have the permission to delete that record.
Note that since you method is changing data, it should be a POST, so do not be tempted to just remove the [HttpPost] attribte from your method so that the link works.
Because #Html.ActionLink will render an anchor tag, Clicking on which is always "GET" request. So if you want an HTTP-Post method you need to override its behavior using javascript like this:
#Html.ActionLink("Remove", "RemoveActivity", "Dashboard", new { id = a.Id ,#class="post_link"},htmlAttributes: null);
[HttpPost]
public String RemoveActivity(int id)
{
activityRepo.Delete(activityRepo.GetById(id));
return "Remove/ActivityDetails";
}
<script type="text/javascript">
$(function(){
$("a.post_link").click(function(e){
e.preventDefault();
$.post($(this).attr("href"),function(data){
//got your redirection link and do a redirection request at here
window.location = data;
});
});
});
</script>
You can try this , very simple way
In you view just place anchor tag: // make sure you have Id coming here
Remove
Jquery block:
<script type="text/javascript">
function RemoveActivity(index) {
var urlBase = '/Dashboard/RemoveActivity/';
$.ajax({
url: urlBase,
data: { id: index },
success: function (result) {
},
error: function (ex) {
}
});
}
</script>
keep your controller action as post method only. I hope this helps.
Related
I have seen lots of questions regarding this issue but none of those resolved my problem.
My problem: my redirect action method hits the method I am redirected to, but the view stays on the same page it never changes to the redirected one.
From my Index.chstml I am creating a partial view.
From that partial view using AJAX I am submitting a request to my controller. AJAX code is below
$.ajax({
method: 'POST',
url: "/Home/SubmitTest",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(arr),
success: function (response) {
}
});
My controller code is here. I am receiving data from AJAX method and performing some jobs. In the end, I am trying to redirect the user to another method.
[HttpPost]
public IActionResult SubmitTest([FromBody] List<TestSubmitViewModel> data)
{
// Rest of the code goes here
return RedirectToAction(nameof(PipelineList));
}
The method I am redirecting to is below. Both methods are in the same controller. After redirection, I am getting hit to this method. But my view still stays in the previous URL which is
https://localhost:44339/Home/Index
but it supposed to redirected to
https://localhost:44339/Home/PipelineList
Code:
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> PipelineList()
{
List<PipelineViewModel> itemList = new List<PipelineViewModel>();
/// my other code goes here
return View(itemList);
}
Note: my PipelineList() works fine when I am coming to this action method directly from UI. What am I doing wrong here and what can I do to redirect to the URL?
I am using .NET Core 5.
Here is my routing information from StartUp.cs:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action}/{id?}",
defaults: new { controller = "Home", action="SignIn"});
});
UPDATE
Thank you guys for pointing out the problem I was having.
Using AJAX was necessary for me to pass the selected values (which were from a table created by JS) from UI.
Finally, I made it work by changing my Controller and AJAX code.
Updated Controller:
[HttpPost]
public async Task<JsonResult> SubmitTest([FromBody]
List<TestSubmitViewModel> data)
{
try
{
// my codes goes here
return Json(new {StatusCode = statusCode });
}
catch (Exception)
{
return Json(new {StatusCode = 500 });
}
}
Updated AJAX:
$.ajax({
method: 'POST',
url: "/Home/SubmitTest",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(arr),
success: function (response) {
if (response.statusCode == 200) {
var url = "/GitLab/PipelineList";
window.location.href = url;
} else {
alert("error");
}
}
});
I know this might not be the best solution but for now, it did work. Thanks a lot to #Sergey and #Filipe
As #Sergey says, you used the wrong senior for ajax. Ajax is normally used when you want to update part of the page instead of refreshing the whole page to increase the customer experience and page load speed. If you want to redirect to another page and there is no other specific reason, there is no need to use ajax.
You could find the ajax server has returned the right 302 redirect to the client side and it redirect to the new page:
The right way is directly redirect to the new page like this:
<form asp-action="SubmitTest" asp-controller="Home" method="post">
#*Other input value you want to submit*#
<input type="submit" value="Click"/>
</form>
Result:
I want to be able to click on a blog link and open the blog showing the page of that specific blog. My route config accepts optional id parameters. I am doing this with AJAX as well so hoping to click on a blog link and return to BlogController. I have searched around but cannot find something that helps me..
Here is my code
CSHTML
#foreach (var blodID in blogCont)
{
<a href="??" id="blogHREF" blog-id="#blodID.blogID">
Text
</a>
}
AJAX
$(document).on("click", "#blogHREF", function () {
var retBlogID = $(this).attr("blog-id");
var blogData = {
blogID: retBlogID
}
$.ajax({
type: "GET",
url: "Blog/getBlog",
data: blogData
});
});
C#
public class BlogController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpGet]
public ActionResult getBlog(blogTable blogged)
{
return View(blogged.blogAuthor);
}
}
If you are simply navigating to a new page (such as your question suggests) I would simply use a html helper.
#Html.Action("getBlog", "Blog", new {blogged = blodID })
So this:
<a href="??" id="blogHREF" blog-id="#blodID.blogID">
Text
</a>
would be this:
<a href="#Html.Action("getBlog", "Blog", new {blogged = blodID })" id="// THIS HAS TO BE UNIQUE">
Text
</a>
This is assuming that blodID is a blogTable.
Remove the [HttpGet], we don't need it.
Also worth noting that the id on your <a> tag doesn't look to me to be a unique value. These have to be unique. No matter where you use Id's in HTML.
I'm attempting to wrap my head around .NET MVC5 routing.
I've got a form:
#using (Html.BeginForm("ProductsCheaperThan", "Home", FormMethod.Post))
{
<input type="text" name="comparisonPrice" />
<button type="submit">Search!</button>
}
And I've got a controller Home and an action ProductsCheaperThan which takes a parameter comparisonPrice
public ActionResult ProductsCheaperThan(decimal comparisonPrice)
{
ViewBag.FilterPrice = comparisonPrice;
var resultSet = new ProductService().GetProductsCheaperThan(comparisonPrice);
return View(resultSet);
}
This posts the value in the input (let's suppose that the value I'm posting is 20) back to my action, and correctly routes me to ~/Home/ProductsCheaperThan. The problem is, I'd like to be routed to ~/Home/ProductsCheaperThan/20
I'd like to do this so that if somebody bookmarks the page they don't end up getting an error when they revisit the page.
I thought that adding something like:
routes.MapRoute(
name: "ProductsCheaperThan",
url: "Home/ProductsCheaperThan/{comparisonPrice}",
defaults: new { controller = "Home", action = "ProductsCheaperThan", comparisonPrice = 20 }
);
might work, and I have one solution to my problem which changes the form to a GET
#using (Html.BeginForm("ProductsCheaperThan", "Home", FormMethod.Get))
and produces a URL of ~/Home/ProductsCheaperThan?comparisonPrice=20, but that uses a query string instead, and isn't exactly what I was aiming for.
Can anybody help me get my URL right?
You should add [HttpPost] attribute to your action
[HttpPost]
public ActionResult ProductsCheaperThan(decimal comparisonPrice)
{
ViewBag.FilterPrice = comparisonPrice;
var resultSet = new ProductService().GetProductsCheaperThan(comparisonPrice);
return View(resultSet);
}
One option is to use JQuery -
<div>
<input type="text" name="comparisonPrice" id="comparisonPrice" />
<button type="button" id="Search">Search!</button>
</div>
#section scripts{
<script>
$(function () {
$("#Search").click(function () {
window.location = "#Url.Action("PriceToCompare", "Home")" + "/" + $("#comparisonPrice").val();
});
});
</script>
}
Above script will result in - http://localhost:1655/PriceToCompare/Home/123
I think you can specify your route values using an overload:
#using (Html.BeginForm("Login", "Account", new { comparisonPrice= "20" }))
{
...
}
I have the following in my view:
#Html.DropDownList("ProductionOrder", null, htmlAttributes: new { #class = "form-control", #id = "ProductionOrder" })
<div class="col-lg-6" id="ProductionOrderDetails"></div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$(function () {
$("#ProductionOrder").change(function () {
var po = $("#ProductionOrder").val().toString();
//This alert is for debug purpose only
alert(po);
$.get('/wetWashRequests/GetDetails/' + po, function (data) {
$('#ProductionOrderDetails').html(data);
$('#ProductionOrderDetails').fadeIn('fast');
});
})
})
</script>
then I have the following in my controller:
public PartialViewResult GetDetails(string PONumber)
{
var details = db.vwProductionOrderLookups.Where(x => x.No_ == PONumber).SingleOrDefault();
return PartialView("_ProductionOrderDetails", details);
}
What I don't understand is why it doesn't pass the value to the controller or why, when I enter the URL manually in the browser, like so(http://localhost:51702/wetWashRequests/GetDetails/WO033960), it also doesn't assign it to the parameter and so returns no data.
What am I missing? I thought I was on the right track but...
You need to edit the route configuration to allow URL of type {controller}/{action}/{PONumber}. Otherwise, you can also send the PONumber via querystring, so that your URL looks like this:
http://localhost:51702/wetWashRequests/GetDetails?PONumber=WO033960
Use URL.Action() method
var url= "#Url.Action("wetWashRequests","GetDetails")"+"?PONumber="+po;
$.get(url,function(data)
{
});
I think this modification will work:
$.get('/wetWashRequests/GetDetails?PONumber=' + po,
please note #malkam's remark to always use: #Url.Action(controller,action)
var url= "#Url.Action("wetWashRequests","GetDetails")"+"?PONumber="+po;
To clarify:
In your app-start you'll probably have the default routing:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index",
id = UrlParameter.Optional }
);
This means you can have URL's like:
/wetWashRequests/GetDetails/999
but then the 999 is bound to a parameter is called id.
For all other variables you'll need the
/wetWashRequests/GetDetails?someParameter=999
syntax.
Alternatively, you can modify your routing.
I'm using ASP.NET MVC 4 C Sharp and I have 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: /ClerkBooking/ConfirmBooking/22
In my controller I have:
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = "Booking Clerk")]
public ActionResult ConfirmBooking(int id = 0)
{
if (ModelState.IsValid)
{
//Find the booking
Booking booking = db.Bookings.Find(id);
//Get RoomID of Preferred Room.
int roomId = Convert.ToInt32(db.Rooms.Find(booking.PreferredRoom));
//Set RoomID of Booking.
booking.RoomId = roomId;
//Save Changes.
db.SaveChanges();
}
return View("Index");
}
So im not sure why its not finding the method even though its in the correct place. Any help would be great! Thanks!
Your action link #Html.ActionLink("Confirm Booking", "ConfirmBooking", new {id = booking.BookingId}) is going to make a GET request, but you put an [HttpPost] attribute on the action.
You'll probably want to make the link a button inside of a form post instead of an action link.
Here's an example:
#using (Html.BeginForm("ConfirmBooking", "ClerkBooking", new { id = booking.BookingId }))
{
<input type="submit" value="Confirm Booking" />
}
Make sure your controller is called "ClerkBooking" and remove the [HttpPost] decoration from the method.
Are adding your AntiForgeryToken to your html file?
#using (Html.BeginForm("Manage", "Account")) {
#Html.AntiForgeryToken()
}
If not then probably asp.net mvc is blocking to reach your controller.
Also do not forget to check your Global.asax with the parameters:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "ClerkBooking", action = "ConfirmBooking", id = UrlParameter.Optional } // Parameter defaults
);
}
Otherwise you have to declare your id object from outside.
$.ajax("/ClerkBooking/ConfirmBooking/?id=22", {
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (result) {
//Do Something
}
}
}).fail(function () {
//Do Something
});