I ask a similar question here I think this is a really easy one (of course not for me). I have a extension method for Html helper and I need to get current view's url with HtmlHelper. Does anyone have any idea about it?
Based on your comment and the original thread you linked to I think you want to use a Url helper to get the URL for the form action, but I could have misunderstood what you wanted:
In a View:
#Url.Action(null) returns the current controller/action
#Url.Action("Action") returns a custom action with current controller
#Url.Action("Action","Controller") returns a custom controller and action
In a HTML Helper:
public static MvcHtmlString MySpecialHelper(this HtmlHelper htmlHelper)
{
UrlHelper urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext,htmlHelper.RouteCollection);
string url = urlHelper.Action("Controller","Action");
//To get the action based on the current Action/Controller use:
url = urlHelper.Action(htmlHelper.ViewData["action"] as string);
//or
url = urlHelper.Action(null);
return new MvcHtmlString(url);
}
if you want to get information about the route information , like the controller or action method that are called
you can access the RouteData dictionary from the ViewContext Object
will be like this
#ViewContext.RouteData.Values["Controller"]
with the RouteData Dictionary you can get all the info needed about the controller , action and extra parameters' name , depending on what you want
If you just want the requested url then you can just get it via the Request.Url object. This returns a Uri, but if you want the raw url then Request.RawUrl.
Necromancing
public static MvcHtmlString MyHelper(this HtmlHelper htmlHelper)
{
var url = htmlHelper.ViewContext.HttpContext.Request.Url;
//more code
}
The OP asked about "extension method for Html helper" - so yeah, this is it.
You could use the Request.RawUrl property or Request.Url.ToString() or Request.Url.AbsoluteUri.
You can use a Html Helper passing the object page as reference, like this:
#helper GoHome(WebViewPage page)
{
}
An in the View just use:
#Links.GoHome(this)
Related
I was hoping to write a method/property in my BaseController class that would enable any action to get the current URL. If I call localhost/Keyword/Edit/1 I can use Request.Url to get the url. However, if there is a partial view in my Edit view, I need to use Request.UrlReferrer to get localhost/Keyword/Edit/1. If I use Request.Url while in the action for the partial view, I would end up with localhost/Keyword/PartialView.
Is there a built in way to always get the Url that would be in the browser address bar regardless of whether I'm in a View or Partial View?
Create a custom HtmlHelper.Your HtmlHelper's ViewContext property will have just about everything you need about the particular request: HttpContext, RequestContext, RouteData, TempData, ViewData, etc.
To get the current path of the request, try helper.ViewContext.HttpContext.Request.Path
You can check the RouteData and obtain the (partial) action and controller, among other route values:
public static string TestHelper(this HtmlHelper helper)
{
var controller = helper.ViewContext.RouteData.Values["controller"].ToString();
var action = helper.ViewContext.RouteData.Values["action"].ToString();
return controller + "/" + action;
}
If called in your Index view , it would return "Home/Index".
If called in your Partial view , it would return "Home/Partial".
Hope that helps.
Can I access to current AntiForgeryToken that generated in view to HtmlHelper extention method?
Something like this:
public static string AntiForgeryTokenValue(this HtmlHelper helper)
{
}
You can get current anti forgery token value from incoming request... like below
MVC keeps this value in hidden form field with name __RequestVerificationToken...
HttpContext.Current.Request.Headers["__RequestVerificationToken"]
You can also get in client side like below :-
$('input[name="__RequestVerificationToken"]').val()
(But why do you need its value in HtmlHelper while rendering view)
Is it possible to detect a route value in a view?
Such as /pages/create/1 and I want to check to see if 1 is there?
Basically, I want to render a different partial view based on this value though I'm fairly sure this is probably not the best way to go about what I'm trying to achieve.
On a side note, instead of doing the above is it possible for me to be able to change what partial views are rendered in a view based on a value from within my controller?
ViewContext.RouteData.Values["whatever"]
You can inspect a RouteData object through ViewPage.ViewContext.RouteData. Then check for values using something like
string areaname = routeData.Values["area"] as string;
string controllername = routeData.Values["controller"] as string;
string actionname = routeData.Values["action"] as string;
string id = routeData.Values["id"] as string;
If you find that you want to inspect these values in the controller instead, you can access them using ControllerBase.ControllerContext.RouteData. Something similar applies for action filters etc.
Other answers are correct, but thought i'd address your last sentence:
On a side note, instead of doing the above is it possible for me to be able to change what partial views are rendered in a view based on a value from within my controller?
Well partial view's are rendered in the View itself (unless calling from JavaScript and binding directly to DOM) with the following code:
<%: Html.RenderPartial("SomePartial") %>
So to prevent "code soup" (if statements) in your view, you use a HTML helper which calls through to RenderPartial after inspecting the ViewContext:
public static string RenderCustomPartial(this HtmlHelper helper, RouteData rd)
{
string partialName;
if (rd.Values["SomeParam"] == 1)
partialName = "PartialOneName";
else
partialName = "PartialTwoName";
return helper.RenderPartial(partialName);
}
And then in the View:
<%: Html.RenderCustomPartial(ViewContext.RouteData) %>
You could make some mods to the above - like access the route data directly in the extension, pass through the model to bind in the partial, etc - but you get the idea.
Alternatively you could do the above IF statement in your controller, and stuff the partial view name in the ViewData, then use that in the regular RenderPartial call in your View.
Whatever floats your boat. :)
I have a route added by the code
routes.MapRoute("MyRoute", "TheUrl", new { controller = "MyController", action = "MyAction" });
I can then do a reverse lookup with the arguments like UrlHelper.Action("MyAction", "MyController"), and it will return a nice url like ~/TheUrl
However, for this route I want the generated URL to be ~/TheUrl?p=2354, with the parameter being some versioning parameter. Is there a way of doing this by mapping the route with some customized route handler or something? The versioning parameter will be non-standard and require some custom code to execute every time the Url is looked up.
I think a UrlHelper extension method would be most ideal and simple here specially.
public string MyRoute(this UrlHelper url)
{
string versionNumber = GetVersionNumber(); // or w/e is required to get it
return Url.Action("MyAction", "MyController") + "?p=" + versionNumber;
}
This would make calling that route much easier in html
<%= Url.MyRoute() %>
I have an action method, and depending on what is passed to it, I want to redirect to another action in another controller. The action and controller names are determined at run time.
If I return RedirectToAction(), it will force a redirect and change the URL in the browser. What I would like is something like TransferToAction() that can transfer processing of the current request to another action, without doing a redirect. I seem to remember a method behaving like this in earlier previews, but I can't seem to find it in the RC of ASP.NET MVC.
Do you know how I would do this?
UPDATE
I added the following route:
routes.MapRoute(
"PageRouter",
"{site}/{*url}",
new { controller = "PageRouter",
action = "RoutePage", site = "", url = "" }
);
And the PageRouter controller action RoutePage:
public ActionResult RoutePage(string site, string url)
{
var controller = new HomeController {ControllerContext = ControllerContext};
controller.RouteData.Values["controller"] = "Home";
controller.RouteData.Values["action"] = "Index";
return controller.Index(site, url);
}
I had to set the controller and action in RouteData for the Home Index view to be rendered. Otherwise, it would look for an Index view in PageRouterController.
I still need to figure out how to create a controller and its action knowing only their names. e.g. I'd like to be able to just call something like this:
public ActionResult RoutePage(string site, string url)
{
return InvokeAction("Home", "Index");
}
What should go in InvokeAction() ? Do I need to pass it any context?
You should be able to just call the other method directly and, assuming that it returns a ViewResult, it will render that view in response to the request and the url will not change. Note, you'll be responsible for making sure that all of the data that the other method needs is available to it. For example if your other method requires some form parameters that weren't provided, you may need to construct a suitable FormCollection and set the ValueProvider of the controller to a ValueProvider based on your FormCollection. Likewise with any arguments required by the method.