Thymeleaf - How to add url to relative url - thymeleaf

I have a form page into:
GET /admin/form
Instead of send to full relative path like:
th:action="#{/admin/form}"
i would like to send to:
th:action="#{**** I dont know how to set '/admin' from thymeleaf **** /form}"
In other words i want to get the path (/admin) programmatically. How can i do it and add '/form'?

If you want to get param from controller dynamically, just set a method like this:
#RequestMapping(value = "form", method = RequestMethod.GET)
public String messages(Model model) {
model.addAttribute("param", "admin");
return "form/";
}
And then in html you can get it like this:
<form th:action="#{/${param}/form}">
You can include parameters statically in the form of path variables like this :
<form th:action="#{/{param}/form(param='admin')}">
So if we formulize the path :
<form th:action="#{/staticpath/{dynamicpath}(dynamicpath=${type})}">

Related

generate url with Url.Action helper from attribute routing controller with prefix

i have definned a Map route like this:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=User}/{action=Student}/{id?}");
});
and i have an API Action with Attribute routing like this:
[Route("api/User")]
public class UserApiController : Controller
{
....
[HttpGet]
[Route("Teacher")]
public async Task<IEnumerable<UserApiVM>> GetTeachers()
{
....
}
}
Which i can access browsing to a direct url like "http://api/User/Teacher".
Now i whant to generate that url using the #URL.Action helper or any other helper, but i can't figure out how. I tried with
#Url.Action("Teacher","UserApi")
but it couldn't find the controller.
BTW, the controller is Controllers are in a folder called "Controllers", and the API controllers in a folder called "API" inside the "Controllers" folder.
Thanks!
For generating api/User/Teacher, you need to specify GetTeachers as controller name instead of Teacher.
#Url.Action("GetTeachers", "UserApi")
If you want to generate URL by specifying Teacher, you could try to set route name like below:
[HttpGet]
[Route("Teacher",Name = "Teacher")]
public async Task<IEnumerable<string>> GetTeachers()
{
return null;
}
And generate URL by:
#Url.RouteUrl("Teacher")

Ambiguous route ordering

I have two ambiguous routes, both within the same MVC area:
Default
{controller}/{action}/{id}
controller = "Home"
action = "Index"
id = Optional
SettingsRoute
Settings/{controller}/{action}
action = "Index"
I want MVC to use the Default route by default, which it does when the routes are in the order specified above. So this...
Controller: WelcomeController
Action: Login
using( Html.BeginForm() ) { }
...results in this HTML
<form action="/Welcome/Login" method="post"></form>
So far, so good.
However when I have an anchor that looks like this:
Application settings
...it gets captured by the Default route as Controller = Settings, Action = AppSettings instead of by the SettingsRoute route.
When I reorder the routes so SettingsRoute appears before Default then my Html.BeginForm() calls look like this: <form action="Settings/Welcome/Login"> which isn't what I want at all.
Is there any solution to this?
You Can mention <%:Html.ActionLink("Create Item-->this is the page you wanted to redirec ","Index","Item--> folder of the page") %>
You can Navigate from one page to another.

How to avoid default URL encoding in ASP.NET MVC Html Helpers like RouteLink

I want my url like this:
"http://domain.com/tag/高兴"
My route mapping:
routes.MapRoute("Tag", "tag/{name}", new { controller = "Tag", action="Index" });
But Html.RouteLink will encode the parameters as default. If I use Html.RouteLink in my View, the generated html is:
高兴
Is there any way to avoid this?
Changed my example.
This works in my case
<%= HttpUtility.UrlDecode(Html.RouteLink("Test", new { id = "高兴" }).ToString())%>
Make sure to change from <%: to <%=

Why doesn't this form call my controller action in ASP.NET MVC?

I'm attempting to make a TinyURL clone in ASP.NET MVC as a learning project.
Right now, all I want is to be able to submit new URLs to my /Home/Create action via a form.
I have my LINQ expression all setup, I have my routing setup, and I have my view setup but something is wrong with my setup.
Routing:
routes.MapRoute(
"Default", // Route name
"", // URL with parameters
new { controller = "Home", action = "Index" } // Parameter defaults
);
routes.MapRoute(
"Redirect",
"{hash}",
new { controller = "Home", action = "RequestLink", hash = "" }
);
These routes allow me to be able to go to my website, www.tinyurlclone.com/ and if nothing is passed ti will simply go to my Home/Index() action. However, if you put anything after the slash, it will consider that a Link Hash and attempt to retrieve the hash.
My HomeController is as follows:
[HandleError]
public class HomeController : Controller
{
TinyGetRepository repo = new TinyGetRepository();
public ActionResult Index()
{
return View();
}
public ActionResult Create(String url)
{
String hash = repo.addLink(url);
ViewData["LinkHash"] = hash;
return View();
}
public ActionResult RequestLink(String hash)
{
String url = repo.getLink(hash);
return Redirect(url);
}
}
My repo class has all my LINQ expressions in it for dealing with the database and I don't really need to include them because it isn't relevant to this question.
Finally, my basic Home/Index() view (used for submitting urls) is as follows:
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Index</title>
</head>
<body>
<div>
<center>
<span style="font-size: 14pt">TinyGet <em>(beta)</em></span><br />
<span style="font-family: Tahoma">Reduce your long links to smaller ones to keep them more memorable....<br />
</span>
<% using(Html.BeginForm("Create", "Home")) %>
<% { %>
<%= Html.TextBox("url") %>
<input type="submit" name="submitButton" value="Shorten Link!" />
<% } %>
</center>
</div>
</body>
</html>
However, my form simply isn't firing any methods when I click submit.
Furthermore, if I view the source of my generated HTML I can see that it didn't make my Form's action correctly, it reads:
<form action="" method="post"><input id="url" name="url" type="text" value="" />
<input type="submit" name="submitButton" value="Shorten Link!" />
</form>
Why is the HTML helper putting "" as the action when it ~should~ be putting /Home/Create? Why isn't my /Home/Create action method being called? Even if I don't use the Html helpers and specify the <form> tag manually it throws errors.
What is wrong here?
Source for project: here
The problem is that you don't have a route that matches the route values (controller = Home, action = Create).
You have two routes, one is the empty string (no parameters), which matches Controller = "Home", Action = "Index". The other is your hash route, which matches Controller = "Home", Action = "RequestLink". So, when ASP.Net Routing goes to build a URL from the route values you're providing, it can't find one (since none of them have the "{controller}" and "{action}" parameters).
The simplest solution, in this case, is to create a direct route to the "Create" action, so that you can still use your "hash" route. Put this at the top of your RegisterRoutes method. NOTE: Order does matter! ASP.Net Routing checks each route, in the order added, until it finds a match.
routes.MapRoute(
"Create", // Route name
"Create", // URL with parameters
new { controller = "Home", action = "Create" } // Parameter defaults
);
Since you have that "hash" route, you can't really use the default "{controller}/{action}/{id}" technique, since the "hash" value would be consider a valid Controller name. So, if someone requested: http://www.mysite.com/fjhas82, MVC would look for a Controller called "fjhas82" and complain that it couldn't find it. Unfortunately, this means you have to manually add new routes for each new Controller Action (like I showed above), which is a pain.
The best solution (in my opinion) is to use Regex Constraints: If your hashes have a very well-defined format (say: 5 letters followed by 2 numbers, or "_" followed by any alpha-numeric characters, etc.), or if you're willing to impose such a format, you can use the Regex constraints supported by ASP.Net Routing. Then, you'd only need these two routes
routes.MapRoute(
"Redirect",
"{hash}",
new { controller = "Home", action = "RequestLink" },
new { hash = #"[a-zA-Z]{5}[0-9]{2}" } // Regex Constraints
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index" } // Parameter defaults
);
Under these routes, if MVC sees a controller name like: "Home", it will check the first route, find that it doesn't match the regular expression, and move to the next one. NOTE: My Regular Expression syntax may be a bit rusty, so I'd use something like http://regexpal.com/ to test a Regex first, to make sure it works with your hashes and controller names.
Hope that helps, I know I wrote a lot, but MVC is so flexible, you can do things in so many different ways!
I had a similar issue from what I've learned is the routing takes the last route
So its using your hash route instead so thus its putting ""
Basically you could get rid of that hash route and just have this
routes.MapRoute( "Default", // Route name "{controller}/{action}/{hash}", // URL with parameters new { controller = "Home", action = "Index", hash="" } // Parameter defaults );
It would accomplish the same thing, and when the hash isn't provided it wouldn't matter

pass a url string as parameter to mvc controller

I need to pass a full website url to my controller action, like this:
http://myweb/controller/action/http://blabla.com/dir2
how to create a new route for passing this parameter to action?
routes.MapRoute("Name", "{controller}/{action}/{*url}");
Additional Info:
ASP.NET MVC In-Depth: The Life of an ASP.NET MVC Request
Pass it as a parameter.
<%= Html.ActionLink( "Link",
"MyAction",
"MyController",
new { url = "http://blah.com/blah" },
null ) %>
Should produce a link that looks like:
<a href='/MyController/MyAction?url=http://blah.com/blah'>Link</a>
Your action would look like:
public ActionResult MyAction( string url )
{
...
}

Resources