mvc routing to incorrect url on http post - c#

The default url of the application is
http://servername/Root/ITProjects
There is a menu item with 'Team' on the default page which should redirect to another controller with index which will display a dropdownlist at the following url
http://servername/Root/ITProjects/Team
It's working fine so far.
However when the user selects an item in the dropdownlist, it should go to the url below
http://servername/Root/ITProjects/Team/Index?Id=7
But it's directing to
http://servername/Team/Index?Id=7
and throwing the 404 error. It is missing the folder path 'Root/ITProjects' after the servername. It's working fine on localhost where there is no folder path but failing on deployment to test or prod servers
[AuthorizeAD(Groups = "APP_xxxx_Users")]
public class TeamController : Controller
{
public int pageSize = 5;
private IProjectService _projectService;
public TeamController(IProjectService projectService)
{
this._projectService = projectService;
}
public ActionResult Index(int? Id, int? page)
{
int pageNumber = (page ?? 1);
var viewModel = new TeamViewModel();
if (Id != null)
{
viewModel.SelectedMember = (int)Id;
viewModel.Tasks = this._projectService.GetTasksByStaff(viewModel.SelectedMember).ToPagedList(pageNumber, pageSize);
}
return View(viewModel);
}
[HttpPost, ActionName("Index")]
public ActionResult IndexPost(int Id, int? page)
{
int pageNumber = (page ?? 1);
var viewModel = new TeamViewModel();
viewModel.SelectedMember = Id;
if (ModelState.IsValid)
{
viewModel.Tasks = this._projectService.GetTasksByStaff(viewModel.SelectedMember).ToPagedList(pageNumber, pageSize);
}
return View(viewModel);
}
}
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 }
);
}
As part of Index view when dropdownlist item is selected
#Html.DropDownListFor(m => m.SelectedMember, new SelectList(Model.StaffList, "UniqueId", "Initials", Model.SelectedMember), new { #class = "btn btn-default btn-color", onchange = #"form.action='/Team/Index?Id=' +this.value;form.submit();" })

Your MVC application is in a sub-directory of another application, so IIS considers the root of the parent application instead of the root of your MVC application.
In IIS, you need to convert the virtual directory to an Application: choose your virtual directory and "Convert to Application." If you are unable to do that, then you need to modify your routes in routes.config to take the virtual directory into account:
routes.MapRoute(
"Default", // Route name
"Root/ITProjects/{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

your default route for controllers looks like this :
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
You can add /Root/ITProjects/ before the URL to change the default controller path

Related

C# Custom Map Routes / View Paths / Link Generation

Issue/Try 1:
I have a custom route map:
routes.MapRoute(
name: "User Profile",
url: "User/{userId}/{controller}/{action}/{id}",
defaults: new { Areas = "User", controller = "Kpi", action = "Index", id = UrlParameter.Optional }
);
If i manually navigate to the URL /User/f339e768-fe92-4322-93ca-083c3d89328c/Kpi/View/1 the page loads with a View Error: The view 'View' or its master was not found or no view engine supports the searched locations.
Issue/Try 2:
Stopped using the custom route and set up my controller as instead:
[RouteArea("User")]
[RoutePrefix("{userId}/Kpi")]
public class KpiController : BaseUserController
{
[Route("View/{id}")]
public async Task<ActionResult> View(string userId, int? id = null)
{
[...]
}
}
This now works i can navigate to the URL and the View displays fine.
Issue for both:
Although I can navigate manually to both and they load I can't seem to generate the URL correctly using ActionLink:
#Html.ActionLink(kpi.GetFormattedId(), "View", "Kpi", new { Area = "User", userId = Model.Id, id = kpi.Id }, null)
It generates: /User/Kpi/View/1?userId=f339e768-fe92-4322-93ca-083c3d89328c instead of /User/f339e768-fe92-4322-93ca-083c3d89328c/Kpi/View/1
URL Mapping
After some time i have found the solution for the custom mapping i was adding in the main RouteConfig.cs and not in the Area Registration. Moving the MapRoute to the Area works correctly and without the RouteArea, RoutePrefix and Route attributes in the Controller.
Area Registration
public class UserAreaRegistration : AreaRegistration
{
public override string AreaName => "User";
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
name: "User",
url: "User/{userId}/{controller}/{action}/{id}",
defaults: new { action = "Index", id = UrlParameter.Optional }
);
context.MapRoute(
"User_default",
"User/{controller}/{action}/{id}",
new {action = "Index", id = UrlParameter.Optional}
);
}
}
Links
Instead of using ActionLink i am now using RouteLink.
#Html.RouteLink("KPIs", "User", new { Controller = "Kpi", Action = "Index", userId = Model.Id })

Controller Redirect not executing method

Following all suggested remedies, still my method is not getting called.
The method being called is in the same controller. TEST can be called either by itself through a link on a separate page, or when a user selects a saved "TEST" view that they wish to load again. In this case, the below LoadUserSelectedTransaction is called.
I've tried specifying the controller to use with no luck, hard coding requestType, [HTTPPOST] attribute, removing FormMethod.Post from the view
View is as follows:
using (Html.BeginForm("LoadUserSelectedTransaction", "TransactionList", FormMethod.Post))
Controller is as follows
public class TransactionListController : Controller
{
public static bool userLoaded = false;
public static string userFriendlyName;
public static string transaction;
public static string requestType;
//[HttpPost]
public ActionResult LoadUserSelectedTransaction(FormCollection formdata)
{
userLoaded = true;
userFriendlyName = formdata["UserLoadedTransaction"];
var model = new MyTransactionsDBHandle();
transaction = model.ReturnUserLoadedTransaction(userFriendlyName, User.Identity.Name);
var myTransaction = new MyTransactionsModel();
requestType = myTransaction.ReturnRequestType(transaction);
if (requestType == "")
{
requestType = formdata["CurrentTransactionPage"];
}
// need to check for duplicate transactions types, such as CC_SALE also being a POS Surcharge transaction
// CC_SALE has EMV, ship to, bill to etc, POS Surcharge does not
// CC_VOID with and without card - With card will have NGT_TRACKDATA tag
// DB_SALE with and without cashback - Cashback will have NGT_DC_CASH_BACK_AMOUNT tag
if (requestType == "DB_SALE")
{
if (transaction.Contains("NGT_DC_CASH_BACK_AMOUNT"))
return RedirectToAction("DB_Sale_With_Cash_Back");
return RedirectToAction("DB_Sale_No_Cash_Back");
}
else if (requestType == "CC_SALE")
{
if (transaction.Contains("NGT_EMV_DATA"))
return RedirectToAction(requestType);
return RedirectToAction("CC_POS_Surcharge");
}
else if (requestType == "CC_VOID")
{
if (transaction.Contains("NGT_TRACKDATA"))
return RedirectToAction(requestType);
return RedirectToAction("CC_Void_No_Card");
}
else
return RedirectToAction(requestType);
}
}
Method being called:
public ActionResult TEST(FormCollection formdata)
{
ViewModel model = new ViewModel();
if (userLoaded) // static in same controller
{
userLoaded = false;
if (requestType == "My Transactions")
{
var currentTransactionPage = formdata["CurrentTransactionPage"];
return RedirectToAction(currentTransactionPage);
}
model.myTransactions.ParseUserTransactionString(transaction, model);
}
return View(model);
}
Any suggestions are greatly appreciated, thanks in advance!
RouteConfig.cs
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 = "User", action = "Login", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "ClientTablePages",
url: "{controller}/{action}/{pageNumber}",
defaults: new { controller = "Client", action = "Index", page = UrlParameter.Optional }
);
routes.MapRoute(
name: "DivisionTablePages",
url: "{controller}/{action}/{pageNumber}",
defaults: new { controller = "Division", action = "Index", page = UrlParameter.Optional }
);
routes.MapRoute(
name: "MerchantTablePages",
url: "{controller}/{action}/{pageNumber}",
defaults: new { controller = "Merchant", action = "Index", page = UrlParameter.Optional }
);
routes.MapRoute(
name: "TerminalTablePages",
url: "{controller}/{action}/{pageNumber}",
defaults: new { controller = "Terminal", action = "Index", page = UrlParameter.Optional }
);
routes.MapRoute(
name: "ResetPassword",
url: "{controller}/{action}/{id}",
defaults: new { Controller = "User", action = "UserResetPassword", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "MyTransactions",
url: "{controller}/{action}/{pageNumber}",
defaults: new { Controller = "MyTransactions", action = "MyProfile", page = UrlParameter.Optional }
);
}
}
RedirectToAction returns a 302 redirect to the browser which is always a GET request.
In comparison Server.TransferRequest(url, true) performs a server redirect preserving the postBack values using a POST request.
P.S. Browser won't be aware of this redirect hence the browser url will not reflect the new address

I want to put dash in URL in .net MVC.How to do it?

I am working with MVC5 where I am unable to put dashes in the URL. What I want is to put a dash between the words.Kindly view my working code.
My Route Config is:
routes.Add(
new Route("{MyApple}/{page}",
new RouteValueDictionary(
new { controller = "MyApple", action = "Index", page = "" }),
new HyphenatedRouteHandler())
);
And My controller is :
public ActionResult Index(string page)
{
if (System.IO.File.Exists(Server.MapPath("/Views/MyApple/" + page + ".cshtml")))
{
string userId = "";
if (Session["AppId"] != null)
userId = Session["AppId"].ToString();
Session["ReturnUrl"] = Url.Action("EmptyTemplate");
IBaseViewModel model = new BaseViewModel();
return View(page, model);
}
}
This is my controller where the parameters go to page.
Example: devpage = aspdotnet then it will render the view = aspdotnet.html
Please help with this edited content.
I want to dash to the URL with lowercases.
Example: Suppose I have perfectsolution.html page then i
localhost/case-study/perfect-solution
(Don't mind my English).Help will be appreciated. Thanks
Note: in the index page, I` am using "perfect solution" to pass to the view but I want in URL, perfect-solution.
I want this type URL /case-studies/san-Diego-veg-festival ,
casestudies is controller and san-diego-veg-festival is parameter.
As per your comments , I made a guess that you are trying to pass parameter value in CaseStudies controller's Index method.
Two types of Routing to choose from, you can choose anyone as required:
1. Convention-based Routing
In Your RouteConfig.cs file make these changes:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "CaseStudiesRoute",
url: "case-studies/{devPage}",
defaults: new { controller = "CaseStudies", action = "Index", devPage = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Controller:
public class CaseStudiesController : Controller
{
public ActionResult Index(string devPage)
{
return View();
}
}
Now using your browser give a GET request to URL , /case-studies/san-Diego-veg-festival , It should work with Convention-based Routing.
2. Attribute Routing
In Your RouteConfig.cs enable Attribute Routing , by adding routes.MapMvcAttributeRoutes(); , Now RouteConfig.cs looks like:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Controller:
public class CaseStudiesController : Controller
{
[Route("case-studies/{devPage?}")]
public ActionResult Index(string devPage)
{
return View();
}
}
Now using your browser give a GET request to URL , /case-studies/san-Diego-veg-festival , It should work with attribute routing.
References
1.
2.
Try using Routing Attribute functionality
[Route("study/perfect-solution")]
eg:
[Route("study/perfect-solution")]
public ActionResult PerfectSolution()
{
// code here
}
If you want to pass parameters it need to be specified
Eg:
[Route("study/perfect-solution/{parameter}")]
public ActionResult PerfectSolution(string parameter)
{
// code here
}

Change nopcommerce default action

How to change nopcommerce default action?
I create new action in HomeController, and want to be default page.
I change:
routes.MapRoute(
"",
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new[] { "Nop.Web.Controllers" }
);
To:
routes.MapRoute(
"",
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "NewAction", id = UrlParameter.Optional },
new[] { "Nop.Web.Controllers" }
);
But nothing has changed.
When you navigate to /Home/Index, MVC parses route as follows:
Controller: Home
Action: Index
Id:
If you navigate to /Home:
Controller: Home
Action: NewAction (from route's default action)
Id:
You can make it always activate NewAction like this:
routes.MapRoute(
"",
"{controller}/{id}", // URL with parameters
new { controller = "Home", action = "NewAction", id = UrlParameter.Optional },
new[] { "Nop.Web.Controllers" }
);
You can try like this.
//your default action
public ActionResult Index()
{
return RedirectToAction("NewAction"); //Like Response.Redirect() in Asp.Net WebForm
}
//your new action
public ActionResult NewAction()
{
//some code here
return view();
}

Mvc route not being matched

I have the following routes defined in Global.asax.cs:
void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// catalog
routes.MapRoute("thumbs", "Thumbnail/{extn}/{image}/{width}/{height}", new
{
controller = "Image",
action = "FetchThumbnail",
extn = "gif",
image = MediaManager.DefaultImageGuid,
width = 250,
height = 200
});
routes.MapRoute("rfqlist", "Rfqs/", new { controller = "RfqList", action = "Index" });
routes.MapRoute("TappDefault", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
I cant step through and see them being registered. I have a controller:
public class RfqListController : TappController
public ActionResult Index(string rfqTitle, int? page)
If I call
> https://localhost:44300/rfqlist
it fires but if I call:
> https://localhost:44300/rfqs
it 404s. I cant see for looking what Im doing wrong. This is normally so easy.
do you have a rfqs controller?
https://localhost:44300/rfqs matches your default route ("TappDefault") which points to the Index action of rfqs controller

Categories