I am developing a MVC 3 application for a corporate intranet site and I am having some issues with the URL helper sometimes not producing correct URLs. The application is being accessed through an access manager application that is controlled by our IT department which basically provides a standardized URL so that the user does not need to know any information about the server. For example, to access the application directly on the server, I would visit:
http://philsserver/App
Through the access manager, I would use the URL provided by the IT department:
http://secureintranet/PHILSAPP/App/
I am using the MVC URL helper in several places in my application - the issue is that sometimes the "PHILSAPP" part is left out - when I use it within an "<a>
" link, it works, but when I use it in elsewhere, it does not.
For example, the code:
<a href="@Url.Action("Index", "FormsAndTemplates")">
correctly creates the link as:
<a href="/PHILSAPP/App/FormsAndTemplates">
.
The following code:
@Html.TextBox("lastName", ViewBag.LastName as string, new { @class = "input-mini", @autocomplete = Url.Action("QuickSearch", "Employee") })
produces:
<input autocomplete="/App/Employee/QuickSearch" class="input-mini" id="lastName" name="lastName" type="text" value="" />
Notice that this URL does not contain the "PHILSAPP" part. This also happens if I use the URL helper in javascript or just about anywhere other than an "<a>
" tag. Does anyone have any idea why this would be happening? As far as I can tell, both calls to Url.Action are pretty much the same so I cannot figure out why this is happening. I apologize if this question has already been answered but I was not able to find any information about someone having a similar problem. Thanks in advance for any assistance.
Update:
As requested, my routes are below:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
Update 2: The access manager being used is Tivoli Identity Manager if that gives anyone any clues.
As nemesv pointed out above, the answer was that the Url.Action
method was always generating the URL as /App/... but the access manager application would recognize certain tags (such as <a href="/App/...">
, <form action="/App/...">
, etc.) and would add the /PHILSAPP to the beginning. The solution I am exploring is to write some extension methods for the UrlHelper
and HtmlHelper
to generate absolute URLs rather than relative URLs where the host name including the /PHILSAPP will be specified in the web.config file. If anyone still has any other suggestions to solve this I would be happy to hear them but otherwise I am satisfied with using this as a work-around.
Some boilerplate code to start with:
namespace MvcApplicationNameSpace
{
/// <summary>
/// Extension methods to the UrlHelper class for generating absolute URLs using
/// Web.config settings
/// </summary>
public static class UrlHelperExtensions
{
private static string BaseUrl
{
get
{
return System.Configuration.ConfigurationManager.AppSettings["BaseUrl"];
}
}
/// <summary>
/// Generates a string for the absolute URL to an action method
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static string AbsoluteAction(this UrlHelper url)
{
return BaseUrl + url.Action();
}
/// <summary>
/// Generates a string for the absolute URL to an action method with the
/// specified name
/// </summary>
/// <param name="url"></param>
/// <param name="actionName"></param>
/// <returns></returns>
public static string AbsoluteAction(this UrlHelper url, string actionName)
{
return BaseUrl + url.Action(actionName);
}
/// <summary>
/// Generates a string for the absolute URL to an action method with the
/// specified name and route values
/// </summary>
/// <param name="url"></param>
/// <param name="actionName"></param>
/// <param name="routeValues"></param>
/// <returns></returns>
public static string AbsoluteAction(this UrlHelper url, string actionName, object routeValues)
{
return BaseUrl + url.Action(actionName, routeValues);
}
/// <summary>
/// Generates a string for the absolute URL to an action method with the
/// specified name and route values
/// </summary>
/// <param name="url"></param>
/// <param name="actionName"></param>
/// <param name="routeValues"></param>
/// <returns></returns>
public static string AbsoluteAction(this UrlHelper url, string actionName, RouteValueDictionary routeValues)
{
return BaseUrl + url.Action(actionName, routeValues);
}
/// <summary>
/// Generates a string for the absolute URL to an action method and
/// controller
/// </summary>
/// <param name="url"></param>
/// <param name="actionName"></param>
/// <param name="controllerName"></param>
/// <returns></returns>
public static string AbsoluteAction(this UrlHelper url, string actionName, string controllerName)
{
return BaseUrl + url.Action(actionName, controllerName);
}
/// <summary>
/// Generates a string for the absolute URL to an action method and
/// controller, including route values
/// </summary>
/// <param name="url"></param>
/// <param name="actionName"></param>
/// <param name="controllerName"></param>
/// <param name="routeValues"></param>
/// <returns></returns>
public static string AbsoluteAction(this UrlHelper url, string actionName, string controllerName, object routeValues)
{
return BaseUrl + url.Action(actionName, controllerName, routeValues);
}
/// <summary>
/// Generates a string for the absolute URL to an action method and
/// controller, including route values
/// </summary>
/// <param name="url"></param>
/// <param name="actionName"></param>
/// <param name="controllerName"></param>
/// <param name="routeValues"></param>
/// <returns></returns>
public static string AbsoluteAction(this UrlHelper url, string actionName, string controllerName, RouteValueDictionary routeValues)
{
return BaseUrl + url.Action(actionName, controllerName, routeValues);
}
}
}
We exactly had the same problem behind our secure entry server.
For REST calls, we wanted to generate urls on the server side to make them available in java script. But they didn't include the sub-path added by the secure entry server.
So we came up with a workaround like that (rendered in layout page):
<a id="urlBase" href="/" style="display: none;"></a>
<script type="text/javascript">
baseUrl = document.getElementById('urlBase').getAttribute('href');
</script>
href="/"
has been substitued by the entry server by href="/path/"
, and we could easily concatenate baseUrl
with our relative paths when accessing REST services.
Hope it helps in your case too.