Request.Url.Scheme未按预期工作

4

我正在使用asp.net MVC。我的代码如下:

var url = Url.Action(
                   "ConfirmEmail", "Account",
                   new { userId = id, code = code },
                   protocol: Request.Url.Scheme);

在本地主机上,它返回正确的URL,即:https://localhost:44300/Account/ConfirmEmail?userId=bed34d05-2b7b-49b8-940e-0d89d4870d17&code=AQAA但是在实际网站上不符合预期。它返回的URL是:http://newtemp.apphb.com:16169/Account/ConfirmEmail?userId=7ba65316-0901-4c27-9371-588a5e945baa&code=AQAA 其中:16169部分是额外添加的,请问如何去掉这部分?以下是我的详细代码:
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;
        }

也许 Request.Url.Host 是你正在寻找的? - zgood
在本地主机上,它返回localhost://localhost/Account/ConfirmEmail?userId=abc&code=def,但不是。 - Irfan Y
它来自于Request.Url.Scheme。请看这个链接:https://dev59.com/RWMl5IYBdhLWcg3wP1HE - Mohit Verma
如何移除这个? - Irfan Y
1个回答

1

它来自哪里?

端口从当前请求中解析出来。不幸的是,Microsoft没有考虑到当在运行非默认端口的服务器上生成URL时会发生什么,它将只使用当前端口(无论协议是否与当前请求相同)。

如何删除这个?

您可以创建一个扩展方法告诉 UrlHelper 使用默认端口而不管传入请求的端口。

此示例基于默认端口(HTTP为80,HTTPS为443)创建了一个假的HTTP上下文,然后使用新的 UrlHelper 实例来解析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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接