pass a url string as parameter to mvc controller - asp.net-mvc

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 )
{
...
}

Related

MVC 3 - ActionLink

I am using RegisterRoutes method in Global file to route user url to actual url.
routes.MapRoute("Blog",
"blog/dp/{id}",
new { controller ="Blog", action = "Details" });
As you might have guessed, Blog is the controller and Details is its action.
So the problem is that the following code does not generate my desire URL which has dp word in its url.
By the way, I don't want to change my Action Name.
#Html.ActionLink( "headline", "Details", "Blog", new { id="1200" }, null )
Thanks in advance ;)
You could use a RouteLink instead of using an ActionLink. In a RouteLink you can explicitly pass your route name:
#Html.RouteLink("headline", "Blog", new { controller = "Blog", action = "Details" })
More about RouteLink method can be found in the MSDN. Reordering routes can do the job but that's a rather fragile mechanism.
The ActionLink may be using a different route from what you are providing in the question. Do you have any routes declared before this one?
The routes are matched in the order that you provide them. So, for instance, if you had something like:
routes.MapRoute("Blog",
"blog/dp", // {id} is not provided in this one
new { controller ="Blog", action = "Details" });
declared before this route:
routes.MapRoute("Blog",
"blog/dp/{id}",
new { controller ="Blog", action = "Details" });
The first route would be matched first and you would see /blog/dp/?id=1200 instead of /blog/dp/1200.

asp.net.MVC How to produce RESTful url like this: /mycontroller/myaction/24

Could someone show me the syntax of an Html.ActionLink that will produce a hyperlink that looks like this:
<a h ref="/mycontroller/myaction/67">mylinktext</a>
thanks.
Terrence
It depends more on how you set up your routes. But if you only have the default route and myaction takes one parameter named id it can look like this:
<%=Html.ActionLink("mylinktext", "myaction", "mycontroller", new { id = 67 }, null) %>
Or, if you want and have mvc features or mvc2, it can look like this:
<%=Html.ActionLink<mycontroller>(x => x.myaction(67), "mylinktext")%>
To generate a link, use the HtmlHelper and the Action extension...
<%= Html.ActionLink ("mycontroller", "myaction", new { id = 67 }) %>

ASP.NET MVC Url.Action routing error

I've been using this some while now, but I can't seem to figure out, where could be mistake in this simple code:
<a href="<%= Url.Action("Page", new { page=(Model.PageIndex + 1) }) %>" >a</a>
With this routing table:
routes.MapRoute(
"Paging",
"Home/Page/{page}",
new { controller = "Home", action = "Index" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
And of course this method
public ActionResult Index(int? page)
I am getting instead of expected address http://localhost:58296/Home/Page/1 the one http://localhost:58296/Home/Page?page=1
When using
<%= Html.RouteLink("a", "Paging", new { page=(Model.PageIndex+1) }) %>
it works.. Please, where is my mistake? I want image link, so if there is a way to insert it into Html.RouteLink, I would appriciate that info too.
Thanks in advance.
There's a bunch of items to cover here for you to fully understand what's happening. Sorry, this will be a bit long.
routes.MapRoute(
"Paging",
"Home/Page/{page}",
new { controller = "Home", action = "Index" }
);
First, this is the route you want to hit. You do not include the action route parameter, '{action}', in the route path. The only action this route can possibly take is the value you have specified as the default action value "Index".
<a href="<%= Url.Action("Page", new { page=(Model.PageIndex + 1) }) %>" >a</a>
Second, in your link you are setting an action of Page. The route you are expecting does not accept action as a parameter and the only action it is aware of is Index. When Url.Action looks for possible routes in your route table, it will skip the route you want because that route does not accept an action of Page. The default route is valid though because you are implicitly supplying a controller, Home, explicitly supplying an action, Page, allowing the framework to supply a default for id, string.Empty, and any other parameters are tacked on as query parameters, page.
When you changed the Url.Action to "Index", the Url.Action method inspected the routes table and found the route with the action of Index specified for the Home controller with a parameter of page and everything is happier.
Hope that helps and isn't too confusing.
I don't know why, but
<%= Url.Action("Index", new { page=(Model.PageIndex + 1) }) %>
works and it displays and directs to /Home/Page/1 . If someone could explain it to me, I would be gratful.

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

asp.net mvc Html.ActionLink() keeping route value I don't want

I have the following ActionLink in my view
<%= Html.ActionLink("LinkText", "Action", "Controller"); %>
and it creates the following URL http://mywebsite.com/Controller/Action
Say I add an ID at the end like so: http://mywebsite.com/Controller/Action/53 and navigate to the page. On this page I have the markup I specified above. Now when I look at the URL it creates it looks like this:
http://mywebsite.com/Controller/Action/53 (notice the addition of the ID)
But I want it to remove the ID and look like it did originally, like this http://mywebsite.com/Controller/Action (notice no ID here)
Any ideas how I can fix this? I don't want to use hard coded URLs since my controller/actions may change.
The solution is to specify my own route values (the third parameter below)
<%= Html.ActionLink("LinkText", "Action", "Controller",
new { id=string.Empty }, null) %>
It sounds like you need to register a second "Action Only" route and use Html.RouteLink(). First register a route like this in you application start up:
routes.MapRoute("ActionOnly", "{controller}/{action}",
new { controller = "Home", action = "Index" } );
Then instead of ActionLink to create those links use:
Html.RouteLink("About","ActionOnly")
The problem is the built in methods take input from the URL you are currently on as well as what you supply. You could try this:
<%= Html.ActionLink("LinkText", "Action", "Controller", new { id = ""}) %>
That should manually wipe the id parameter.
Don't know why, but it didn't work for me (maybe because of Mvc2 RC). Created urlhelper method =>
public static string
WithoutRouteValues(this UrlHelper helper, ActionResult action,params string[] routeValues)
{
var rv = helper.RequestContext.RouteData.Values;
var ignoredValues = rv.Where(x=>routeValues.Any(z => z == x.Key)).ToList();
foreach (var ignoredValue in ignoredValues)
rv.Remove(ignoredValue.Key);
var res = helper.Action(action);
foreach (var ignoredValue in ignoredValues)
rv.Add(ignoredValue.Key, ignoredValue.Value);
return res;
}
If you either don't know what values need to be explicitly overridden or you just want to avoid the extra list of parameters you can use an extension method like the below.
View
The implementation details are in this blog post
I explicitly set the action name as "Action/". Seems a little like a hack but it's a quick fix.
#Html.ActionLink("Link Name", "Action/", "Controller")
Another way is to use ActionLink(HtmlHelper, String, String, RouteValueDictionary) overload, then there are no need to put null in the last parameter
<%= Html.ActionLink("Details", "Details", "Product", new RouteValueDictionary(new { id=item.ID })) %>
The overloads of Html.ActionLink are changed on the later versions of MVC. On MVC 5 and above. This is how to do this:
#Html.ActionLink("LinkText", "Action", "Controller", new { id = "" }, null)
Note I passed "" for id parameter and null for HTMLATTRIBUTES.
I needed my menu links to be dynamic. Rather than implement a lot of extra code and routing for every single page I simple dispensed with the HTML helper.
#item.MenuItemName

Resources