Reputation: 1310
I am using asp.net MVC. My code is:
var url = Url.Action(
"ConfirmEmail", "Account",
new { userId = id, code = code },
protocol: Request.Url.Scheme);
On localhost it is returning right url i.e,
https://localhost:44300/Account/ConfirmEmail?userId=bed34d05-2b7b-49b8-940e-0d89d4870d17&code=AQAA
But on live website its not working as expected. The url it returns is:
http://newtemp.apphb.com:16169/Account/ConfirmEmail?userId=7ba65316-0901-4c27-9371-588a5e945baa&code=AQAA
the portion :16169
is addational. Where it came from and how to remove this?
My detailed code is:
public async Task<bool> SendMailtoConfirmEmailAddress(string id,string name,string email)
{
var user = await db.AspNetUsers.FindAsync(id);
if (user.EmailConfirmed)
{
return false;
}
try
{
var provider = new DpapiDataProtectionProvider("http://newtemp.apphb.com/");
UserManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser, string>(provider.Create("UserToken"))
as IUserTokenProvider<ApplicationUser, string>;
var code = await UserManager.GenerateEmailConfirmationTokenAsync(id);
var callbackUrl = Url.Action(
"ConfirmEmail", "Account",
new { userId = id, code = code },
protocol: Request.Url.Scheme);
ElectronicsController.sendEmail(email, "Welcome to dealkar.pk - Confirm Email address", "Hello " + name + "!<br/>Confirm your email address by clicking <a href=\"" + callbackUrl + "\">here</a> OR " + callbackUrl);
}
catch (Exception e)
{
string s = e.ToString();
}
return true;
}
Upvotes: 4
Views: 4954
Reputation: 56879
Where it came from?
The port is resolved from the current request. Unfortunately, Microsoft didn't account for when a URL is generated on a server that is running a non-default port and it will just use the current one (whether or not the protocol is the same as the current request).
how to remove this?
You can create an extension method to tell the UrlHelper
to use the default port regardless of the port of the incoming request.
This example creates a fake HTTP Context based on the default port (80 for HTTP, 443 for HTTPS), then uses a new instance of UrlHelper
to resolve the URL.
using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
public static class UrlHelperExtensions
{
public static string Action(this UrlHelper helper, string actionName, string controllerName, object routeValues, string protocol, bool defaultPort)
{
return Action(helper, actionName, controllerName, routeValues, protocol, null, defaultPort);
}
public static string Action(this UrlHelper helper, string actionName, string controllerName, object routeValues, string protocol, string hostName, bool defaultPort)
{
if (!defaultPort)
{
return helper.Action(actionName, controllerName, new RouteValueDictionary(routeValues), protocol, hostName);
}
string port = "80";
if (protocol.Equals("https", StringComparison.OrdinalIgnoreCase))
{
port = "443";
}
Uri requestUrl = helper.RequestContext.HttpContext.Request.Url;
string defaultPortRequestUrl = Regex.Replace(requestUrl.ToString(), @"(?<=:)\d+?(?=/)", port);
Uri url = new Uri(new Uri(defaultPortRequestUrl, UriKind.Absolute), requestUrl.PathAndQuery);
var requestContext = GetRequestContext(url);
var urlHelper = new UrlHelper(requestContext, helper.RouteCollection);
var values = new RouteValueDictionary(routeValues);
values.Add("controller", controllerName);
values.Add("action", actionName);
return urlHelper.RouteUrl(null, values, protocol, hostName);
}
private static RequestContext GetRequestContext(Uri uri)
{
// Create a TextWriter with null stream as a backing stream
// which doesn't consume resources
using (var writer = new StreamWriter(Stream.Null))
{
var request = new HttpRequest(
filename: string.Empty,
url: uri.ToString(),
queryString: string.IsNullOrEmpty(uri.Query) ? string.Empty : uri.Query.Substring(1));
var response = new HttpResponse(writer);
var httpContext = new HttpContext(request, response);
var httpContextBase = new HttpContextWrapper(httpContext);
return new RequestContext(httpContextBase, new RouteData());
}
}
}
var url = Url.Action("ConfirmEmail", "Account",
new { userId = 123, code = 456 },
protocol: Request.Url.Scheme,
defaultPort: true);
Upvotes: 1