UrlParameter.Optional not working in Razor - asp.net-mvc

I am using below code in layout for links:
But it's not working, here is my route Config
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 }
);
}
This is my NewProduct Controller:
public ActionResult NewProduct(int id = -1)
{
NewProductModel m = new NewProductModel();
return View(m);
}
What is problem in my UrlParameter.optional

When you using #Url.Action helper you should pass the actual value to parameter like this:
#Url.Action("NewProduct", "Administrator", new { id = 1 })
UrlParameter.Optional should be used only in RouteConfig as you see in your code.

in NewProduct controller :
public ActionResult NewProduct(int id = -1)
{
NewProductModel m = new NewProductModel();
m.Id = id;
return View(m);
}
and for Link

Related

How to make short url for display of post content in asp.net mvc

I want to display of post content with like below url.
http://domainname.com/name-of-post
Please help me to solved this problem with route config.
This is my codes :
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{param}/{paramAction}",
defaults: new { controller = "Home", action = "Index", param = UrlParameter.Optional, paramAction = UrlParameter.Optional }
);
routes.MapRoute(
name: "ShortUrl",
url: "{PostName}",
defaults: new { controller = "ShortUrl", action = "Post", PostName = UrlParameter.Optional }
);
}
public ActionResult shortaddress(string _postName = "post-name")
{
return RedirectToRoute("ShortUrl", new { postName = _postName });
}
[Route(Name = "ShortUrl")]
public ActionResult Post(string postName)
{
if (string.IsNullOrEmpty(postName))
return RedirectToAction("Index", "Home");
var postData = postsInfo.getPost(postName);
return View(postData);
}

Change url asp.net mvc 5

routes.MapRoute(
name: "MyRoute",
url: "{Product}/{name}-{id}",
defaults: new { controller = "Home", action = "Product", name = UrlParameter.Optional , id = UrlParameter.Optional }
);
my routemap and i want my url in product action be like = http://localhost:13804/Wares/Product/name-id
but now is like =
http://localhost:13804/Wares/Product/4?name=name
When defining a route pattern the token { and } are used to indicate a parameter of the action method. Since you do not have a parameter called Product in your action method, there is no point in having {Product} in the route template.
Since your want url like yourSiteName/Ware/Product/name-id where name and id are dynamic parameter values, you should add the static part (/Ware/Product/) to the route template.
This should work.
routes.MapRoute(
name: "MyRoute",
url: "Ware/Product/{name}-{id}",
defaults: new { controller = "Ware", action = "Product",
name = UrlParameter.Optional, id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Assuming your Product action method accepts these two params
public class WareController : Controller
{
public ActionResult Product(string name, int id)
{
return Content("received name : " + name +",id:"+ id);
}
}
You can generate the urls with the above pattern using the Html.ActionLink helper now
#Html.ActionLink("test", "Product", "Ware", new { id = 55, name = "some" }, null)
I know its late but you can use built-in Attribute Routing in MVC5. Hope it helps someone else. You don't need to use
routes.MapRoute(
name: "MyRoute",
url: "{Product}/{name}-{id}",
defaults: new { controller = "Home", action = "Product", name = UrlParameter.Optional , id = UrlParameter.Optional }
);
Instead you can use the method below.
First enable attribute routing in RouteConfig.cs
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
}
Then in WaresController
[Route("Wares/Product/{name}/{id}")]
public ActionResult Product(string name,int id)
{
return View();
}
Then to navigate write code like this in View.cshtml file
Navigate
After following above steps your URL will look like
http://localhost:13804/Wares/Product/productname/5

How to display only name in url instead of id in mvc.net using routing

I am getting url like http://localhost:49671/TestRoutes/Display?f=hi&i=2
I want it like http://localhost:49671/TestRoutes/Display/hi
I call it from Index method.
[HttpPost]
public ActionResult Index(int? e )
{
// return View("Display", new { f = "hi", i = 2 });
return RedirectToAction("Display", new { f = "hi", i = 2 });
}
Index view
#model Try.Models.TestRoutes
#using (Html.BeginForm())
{
Model.e = 5 ;
<input type="submit" value="Create" class="btn btn-default" />
}
Display Action method
// [Route("TestRoutes/{s}")]
public ActionResult Display(string s, int i)
{
return View();
}
Route config file
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Professional", // Route name
"{controller}/{action}/{id}/{name}", // URL with parameters
new { controller = "TestRoutes", action = "Display", s = UrlParameter.Optional, i = UrlParameter.Optional
});
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional
});
You need to change your route definition to
routes.MapRoute(
name: "Professional",
url: "TestRoutes/Display/{s}/{i}",
default: new { controller = "TestRoutes", action = "Display", i = UrlParameter.Optional }
);
so that the names of the placeholders match the names of the parameters in your method. Note also that only the last parameter can be marked as UrlParameter.Optional (otherwise the RoutingEngine cannot match up the segments and the values will be added as query string parameters, not route values)
Then you need to change the controller method to match the route/method parameters
[HttpPost]
public ActionResult Index(int? e )
{
return RedirectToAction("Display", new { s = "hi", i = 2 }); // s not f
}
change your route as
routes.MapRoute(
"Professional", // Route name
"{controller}/{action}/{name}", // URL with parameters
new
{
controller = "TestRoutes",
action = "Display"
} // Parameter defaults
);
and your action as
public ActionResult Display(string name)
{
//action goes here
}
Remove the maproute code:
routes.MapRoute(
"Professional", // Route name
"{controller}/{action}/{id}/{name}", // URL with parameters
new { controller = "TestRoutes", action = "Display", s = UrlParameter.Optional, i = UrlParameter.Optional
});
Use attribute routing code:
[Route("TestRoutes/{s}/{i?}")]
public ActionResult Display(string s, int? i)
{
return View();
}
You can also try using Attribute Routing. You can control your routes easier with attribute routing.
Firstly change your RouteConfig.cs like that:
public class RouteConfig
{
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 }
//);
}
}
After that change your controller files like that:
namespace YourProjectName.Controllers
{
[RoutePrefix("Home")]
[Route("{action}/{id=0}")]
public class HomeController : Controller
{
[Route("Index")]
public ActionResult Index()
{
return View();
}
[Route("ChangeAddress/{addressID}")]
public ActionResult ChangeAddress(int addressID)
{
//your codes to change address
}
}
You can also learn more about Attribute Routing in this post:
https://blogs.msdn.microsoft.com/webdev/2013/10/17/attribute-routing-in-asp-net-mvc-5/
Another way to solve this problem is to put the proper route before the default route, as follows:
routes.MapRoute(name: "MyRouteName", url: "Id", defaults: new { controller= "Home", action = "Index",id= Id });
Default route:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{Id}",
defaults: new { controller = "Home", action = "Index",id= Id }
);

asp mvc 5 Attribute routing not firing

I'm trying to use the attribute routing in a new project, but I can't get it to work.
Here is what I have so far :
[RoutePrefix("Product")]
public class ProductController : Controller
{
[Route("{id}/{title}", Name = "Product Details")]
public ActionResult Index(int id = 0, string title = "")
{
Product p = Product.Get(id);
return View(p);
}
}
And here is my RouteConfig.cs :
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//routes.MapRoute(
// "Product Details",
// "Product/{id}/{title}",
// new { controller = "Product", action = "Index", id = UrlParameter.Optional, title = UrlParameter.Optional }
//);
routes.MapRoute(
name: "DefaultIndex",
url: "{controller}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
If I remove the Routing attributes and uncomment the first route in my RouteConfig.cs it works fine, but I'd like to stick with route attributes.
Any idea why it's not working correctly ?
The URL I want to use is : http://www.mydomain.com/Product/12345/ProductName
EDIT, here is my Application_Start()
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleMobileConfig.RegisterBundles(BundleTable.Bundles);
}
Looks like its treating the {id} as an action.
Try this:
[Route("{id:int}/{title}", Name = "Product Details")]
Or this
[Route("Product/{id}/{title}", Name = "Product Details")]

Routing to controller with a required, non-empty Guid parameter

I would like to map http://localhost/Guid-goes-here to ResellerController and fire Index action of that controller only when Guid-goes-here is not the empty Guid.
My routing table looks like this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Reseller",
"{id}",
new { controller = "Reseller", action = "Index", id = Guid.Empty }
// We can mark parameters as UrlParameter.Optional, but how to make it required?
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
The action on the ResellerController looks like this:
public ActionResult Index(Guid id)
{
// do some stuff with non-empty guid here
}
Once the application has started, navigating to http://localhost routes me to the ResellerController with the empty Guid as the argument to the Index action's id parameter.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Reseller",
"{id}",
new { controller = "Reseller", action = "Index", id = UrlParameter.Optional },
new { id = #"^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
or if you want a more robust constraint than some cryptic regex:
public class GuidConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
var value = values[parameterName] as string;
Guid guid;
if (!string.IsNullOrEmpty(value) && Guid.TryParse(value, out guid))
{
return true;
}
return false;
}
}
and then:
routes.MapRoute(
"Reseller",
"{id}",
new { controller = "Reseller", action = "Index", id = UrlParameter.Optional },
new { id = new GuidConstraint() }
);
You need to include a constraint in the routing definition. Have a look on this post: http://blogs.microsoft.co.il/blogs/bursteg/archive/2009/01/11/asp-net-mvc-route-constraints.aspx

Resources