writing route in mvc4 to eliminate query string - asp.net-mvc-4

I have a situation where I am redirecting to an action that accepts 3 parameters. This I am doing like -
RedirectToAction("ProductSpecific", routeValues: new { partId = m.partId, categoryId= m.categoryId, categoryName = m.categoryName});
However, when the page loads, it contains all these parameters as query string.
Parts/ProductSpecific?partId=38&categoryId=1&categoryName=Monitor
I tried writing a route, but that didn't work. Can someone please guide on how to write a route in this scenario?
Thanks

The second argument of RedirectToAction is routeValues, so these will be appended to the querystring. Creating an extra route will still require you passing the values in the querystring, but like this: parts/productspecific/{partId}/{categoryId}/{categoryname} which i dont think you want.
If you dont want the values in the querystring, have a look at the TempData object, which is similar to session but will live until the next request.
Something like this:
public ActionResult DoSomething()
{
TempData["partId"] = partId;
TempData["catId"] = catId;
TempData["catName"] = catName;
return RedirectToAction("ProductSpecific");
}
public ActionResult ProductSpecific()
{
var partId = TempData["partId"];
var catId = TempData["catId"];
var catName = TempData["catName"];
var model = service.LoadProduct(partId, catId, catName);
return View(model);
}
Update:
For a route:
routes.MapRoute(
name: "ProductRoute",
url: "{controller}/{action}/{partId}/{categoryId}/{categoryname}",
defults: new { controller = "product", action = "productspecific"}
);
Add that route in the route.config class in app_start before your default routesm, and change your product specific method signature to accept the partid, catid and category name parameters. You can also use this from phil hack to profile your routes: Route Debugger

Related

How to get #Url.Action value inside a controller

I am using ASP.net core
I can use an Html action inside a view
#Url.Action("GetOptions", "ControllerName", new { id="1"});
However I want to get a string value of it in the Controller.
e.g. something like
string Url= Url.Action("GetOptions", "ControllerName", new { id="1"}).ToString();
In previous versions of MVC you can reference the helper in the controller by
UrlHelper urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
Basically what I want to do is generate a URL string representation in my controller
In order for the route values to work correctly for me I had to use the static invocation of the url helpers
UrlHelperExtensions.Action(Url, "Details", "Resellers", new { id = 1 })
Edit: The shorthand way of writing this is:
this.Url.Action("Details", "Resellers", new { id = 1 })
Thanks #Learner.

how I can implement default product in each category in mvc4 using routing

how I can implement default product in each category in mvc4 using routing?
You'll want to set up your routes like this:
routes.MapRoute("Category Route",
"categories/{category}/{product}",
new {
Controller = "Categories",
Action = "ShowCategory",
Category = "Books",
Product = ""
});
Then, your controller action method could look like this:
public CategoriesController : Controller {
public ActionResult ShowCategory(String category, String product) {
// rest of code goes here
}
}
Then inside your action you can design your repository to check String.IsNullOrEmpty(product) and determine the default one based on a database flag or however you want to indicate that.

ActionLink with Attribute Routing in MVC 5

I'm having trouble with an ActionLink in MVC 5.
#Html.ActionLink("View Commissions", "/" + item.Id.ToString, "Commissions")
#Html.ActionLink("View Commissions", "Index", "Commissions", New With {Key .payRollId = item.Id}, Nothing)
These two ActionLinks should accomplish the same thing, but I would prefer to use the second one. Unfortunately, they produce different URLs. The first creates http://mysite/Commissions/3. The second creates http://mysite/Commissions?payRollId=3.
In my Commissions controller, I have the following code:
' GET: Commissions/5
<Route("Commissions/{payRollId:min(1)}")>
Async Function Index(ByVal payRollId As Integer?) As Task(Of ActionResult)
If IsNothing(payRollId) Then
Return New HttpStatusCodeResult(HttpStatusCode.BadRequest)
End If
Return View(Await ...query...).ToListAsync)
End Function
This successfully handles the first ActionLink's URL. The second one results in a 404 error. I don't have any other RouteAttributes or mapped routes for Commissions. According to this attribute routing article, the second ActionLink should create the pretty URL (no query string) that successfully handles the request.
What am I missing? How can I get the second ActionLink to generate the proper URL (Commissions/3) to match the RouteAttribute?
Edit
This should produced the desired route:
View Commissions
This assumes you've enabled attribute based routing something like this:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}
}
I have a partial solution. I played with the controller code and found that changing the RouteAttribute to <Route("Commissions/{payRollId:min(1)?}")> (note the ? at the end) allows it to handle the second URL.
I am still working on how to generate a pretty URL using the second ActionLink. I will update this answer if I work it out.

Passing a string (besides the model) into a partial view in MVC4

How can I send a string to a partial view?
What I would like is to send information about the model being viewed, to a partial view. Something like this:
#{Html.RenderPartial("_PhaseCreate", new Phase(), #Model.Id );}
Is this possible?
If you want to send some data that isn't in model or view, you should use something like the following:
1) instead of #Html.Partial(), use a #Html.Action("ActionName", "Controller", routeValues: new { id = Model.Id }) helper.
2) Add something like this to your controller:
public ActionResult GetMyView(int id)
{
ViewBag.Phase = new Phase();
ViewBag.Id = id;
// also whatever which doesn't in model ...
return View("_PhaseCreate");
}
And in your partial view, you can use those info just like you declare them:
<label>#ViewBag.Id</label>
You also can simply use the following if you just need to add data existing in model and the view:
#Html.Partial("_PhaseCreate",
new ViewDataDictionary(new { Phase = new Phase(), Id = Model.Id }))
and use them like this:
<label>#ViewData["Id"].ToString()</label>

asp.net mvc, generate url by custom route

i have created application, where url generates depends on database values.
i parse these urls without any problem and get controller and action from database in my route handler.
but when i try to generate url, i get troubles.
in my case, it seems like:
view
#Html.ActionLink("more", MVC.Blog.Post(item.Alias)) // i use T4MVC
MyRouteConstraint
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
if (routeDirection == RouteDirection.UrlGeneration)
{
var data = GetDataFromDbByControllerActionAndParameters(values);
if (data == null)
return false;
var valuesToRemove = new List<string>();
var path = GenerateUrlByData(data, valuesToRemove);
values.Remove("controller");
values.Remove("action");
valuesToRemove.ForEach(v => values.Remove(v)); // remove values that is already used in path
values.Add("all", path) // path = "blog/post/postalias"
return true;
}
// skipped code
}
route rule
routes.MapRoute("Locations", "{*all}",
constraints: new { all = new LocationConstraints() },
defaults: new { },
namespaces: new []{typeof(BaseController).Namespace}).RouteHandler = new LocationRouteHandler();
and as result i got url like this
localhost:8553/?Controller=Blog&Action=Post&alias=postalias
but expect like this
localhost:8553/blog/post/postalias
how can I generate url? where it should be? i think not in the constrant, but why it is invoked in this case?
In my MVC application the closest route that matches the one you have is the one below:
routes.MapRoute(
name: "MyRouteName",
url: "{SomeFolder}/{SomePageName}",
defaults: new { controller = "MyController", action = "Index" },
constraints: new { routeConstraint = new MyRouteConstraint() }
);
SomeFolder can be fixed or changed from the database while SomePageName will be changed to a different value from database. The url should be whatever URL you want to match with this route and the one that will be replaced by the value from the database. The defaults address the Controller and Action that will render the page in the end of the MVC cycle. The constraints will lead to your Match method described.
With this configuration I have URLs like www.project.com/SomeFolder/SomePageNameFromDatabase.