Controller Method Using Custom Parameter Name - c#

I am having a problem when I use custom parameter name instead of id in my method in asp.net MVC controller.
My working method is:
// POST: Admin/Pages/ReorderPages
[HttpPost]
public void ReorderPages(int[] id)
{
using (Db db = new Db())
{
//Set Initial count
int count = 1;
//Declare PageDTO
PageDTO dto;
//Set sorting for each page
foreach (var pageId in id)
{
dto = db.Pages.Find(pageId);
dto.Sorting = count;
db.SaveChanges();
count++;
}
}
}
my ajax call is:
$("table#pages tbody").sortable({
items: "tr:not(.home)",
placeholder: "ui-state-highlight",
update: function () {
var pageids = $("table#pages tbody").sortable("serialize");
var url = "/Admin/Pages/ReorderPages";
$.post(url, pageids, function (data) {
});
}
});
Now, when I use different param instead of id, I get null value in param. I added new route also like below: But still, the problem is same.
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name:"CustomRoute",
url:"{controller}/{action}/{ids}",
defaults:new { controller = "Pages", action = "ReorderPages" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
I spent pretty much time in research but couldn't find the exact solution.

Why don't you use
var pageids = $("table#pages tbody").sortable("serialize");
$.ajax({
url: "/Admin/Pages/ReorderPages",
data: { id: pageids }
})
.done(function(response) {
alert("works");
});
.fail(function(response){
alert("failed because of..");
}
Look into Ajax calls and promises. It works really nice and this way no need to play around with routing. If this still not passing through the ids then you debug through your code, but in that case your problem is with the var pageids = var pageids = $("table#pages tbody").sortable("serialize"); line
If you really want to stick with your way of doing it. Use this
$.post(url, { newParameter : pageids }, function (data)
After this you can rename your parameter inside the ActionMethod
public void ReorderPages(int[] newParameter)

Related

how to implement url rewriting similar to SO

I need to implement SO like functionality on my asp.net MVC site.
For example when user go to https://stackoverflow.com/questions/xxxxxxxx
after loading the subject line is concatenated with the url and url becomes like this https://stackoverflow.com/questions/xxxxxxxx/rails-sql-search-through-has-one-relationship
Above "/rails-sql-search-through-has-one-relationship " part is added to the url.
In webforms it's simple, I could just use url rewriting. But not sure how to accomplish this in MVC
The following line is from Global.asax file
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Account", action = "LogOn", id = UrlParameter.Optional } // Parameter defaults
);
the string that I need to concatenate is in my database so it fetches from there. How can I accomplish this?
This is called a slug route. One way to achieve this is to define a route with an optional slug parameter, and in the controller method check if the parameter has been provided
routes.MapRoute(
name: "Question",
url: "Question/{id}/{slug}",
defaults: new { controller = "Question", action = "Details", slug = UrlParameter.Optional }
);
Then in QuestionController (assumes an id will always be provided)
public ActionResult Details (int id, string slug)
{
if (string.IsNullOrEmpty(slug))
{
// Look up the slug in the database based on the id, but for testing
slug = "this-is-a-slug";
return RedirectToAction("Details", new { id = id, slug = slug });
}
var model = db.Questions.Find(id);
return View(model);
}
You are looking for a custom route. If you look closely, SO doesn't care about the text part of the URL. So:
http://stackoverflow.com/questions/xxxxxxxx/rails-sql-search-through-has-one-relationship
AND
http://stackoverflow.com/questions/xxxxxxxx/
Will both work. You can easily do that with something like:
routes.MapRoute(
"Question",
"questions/{id}/{title}",
new { controller = "Question", action = "Details" });
The trick is add the "slug" at the end when you create links:
#Html.RouteLink(
"Read more.",
"Question",
new { id = question.Id, title = Slugger.ToUrl(question.Title) })

Routing ASP NET with two parameters not working

I have read here : Routing with Multiple Parameters using ASP.NET MVC. But still not worked in my case.
I have EmitenController which there a function like this:
public async Task<ActionResult> Financial(string q = null, int page = 1)
At first load, the URL that produced by this function: Emiten/Financial?q=&page=1.
The next page of course Emiten/Financial?q=&page=2.
If I give the query that URL become: Emiten/Financial?q=query&page=1 and go on.
For the routes, I have tried
routes.MapRoute(
name: "Financial",
url: "{controller}/{action}/{q}/{page}",
defaults: new { controller = "Emiten", action = "Financial", q = "", page = 1 }
);
But, when I try go to page 3 the URL still Emiten/Financial?q=&page=2 and how about the URL if I give q empty value?
Thanks in advance.
I can't seem to reproduce your issue. Are you sure you mapped your Financial route before your Default one?
Here is my RegisterRoutes method:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Financial",
"{controller}/{action}/{q}/{page}",
new { controller = "Emiten", action = "Financial", q = string.Empty, page = 1 }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Here is the Controller:
public class EmitenController : Controller
{
public async Task<ActionResult> Financial(string q, int page)
{
return View();
}
}
(I know the async is useless in this case, but you can't await a ViewResult)
And here is the View:
q = #Request.QueryString["q"]<br/>
page = #Request.QueryString["page"]
#Html.ActionLink("Page 2", "Financial", "Emiten", new { q = "test", page = 2 }, null)
<br/>
Page 3
Everything works as expected
If the route is for a specific action method, then you should specify the action method directly in the URL settings
routes.MapRoute(
name: "Financial",
url: "Emiten/Financial/{q}/{page}", // <---- Right here
defaults: new
{
controller = "Emiten",
action = "Financial",
q = string.Empty, // string.Empty is the same as ""
page = 1,
}
);
In your action method, you don't need to specify the default values since you already did that in your route config.
public async Task<ActionResult> Financial(string q, int page)
Let me know how it works for you
UPDATE:
Generating a link relative to a route
#Html.RouteLink(
linkText: "Next Page",
routeName: "Financial",
routeValues: new { controller = "Emiten", action = "Financial", q = ViewBag.SearchKey, page = nextPage})
Related Link: What's the difference between RouteLink and ActionLink in ASP.NET MVC?

Passing value from View to Controller, what am I missing?

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.

Server Error in '/' Application. Resource Cannot Be Found. ASP.NET MVC

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
});

Match Route Only if specific Parameter

I am trying to create a route that only matches if a specific parameter is used in the URL.
For example:
routes.MapRoute(
name: "BannerAds",
url: "Go/{Web}",
defaults: new { controller = "CommunicationsAlias", action = "BannerAds", web = UrlParameter.Optional }
);
I want the URL to match for http://www.domain.com/Go/Web?=111222
But not for http://www.domain.com/Go/Advertising
How do I change my route to function this way?
You would need to make that part of the url static in your route then:
routes.MapRoute(
name: "BannerAds",
url: "Go/Web",
defaults: new { controller = "CommunicationsAlias", action = "BannerAds" }
);
And then place that route above a your more general one:
routes.MapRoute(
name: "BannerAds",
url: "Go/{Web}",
defaults: new { controller = "CommunicationsAlias", action = "BannerAds", web = UrlParameter.Optional }
);
like this
routes.MapRoute(
name: "BannerAds",
url: "Go/Web",
defaults: new { controller = "CommunicationsAlias", action = "BannerAds", web = UrlParameter.Optional }
);
if you actually only want to catch
http://www.domain.com/Go/Web?x=111222
then write the controller to check for query strings
edit
?=111222 isn't a proper query string - I don't really get why you want to catch that - usually there is key value pair , like ?key=111222 or ?x=111222 when writing like that you can check for the value of x or key and if it equals 111222 , then do something
You should be able to just do this:
routes.MapRoute(name: "BannerAds",
url: "Go/Web",
defaults: new { controller = "CommunicationsAlias", action = "BannerAds", web = UrlParameter.Optional });
And manually parse the query string in the controller like this:
public ActionResult BannerAds()
{
string idStr = Request.QueryString.ToString().Trim('='); // strip of leading '='
int id;
if (!int.TryParse(idStr, out id))
{
return HttpNotFound();
}
...
}

Categories

Resources