查看序列化时链接中断

SWa*_*SWa 6 c# asp.net-mvc asp.net-mvc-5

我有以下作为填充局部视图的视图模型的一部分:

public string DownloadLink
{
    get
    {
        UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
        switch (this.Type)
        {
            case (int)DocumentTypes.WasteNote: { 

                return url.Action("PaperWork", "Jobs", new { JobId = this.DOCJobId }, HttpContext.Current.Request.IsSecureConnection ? "https" : "http" ); 
            }
            case (int)DocumentTypes.Contract:
            case (int)DocumentTypes.DestructionCert:
            case (int)DocumentTypes.Quote:
            default: { return url.Action("Download", "Documents", new { DocId = this.DocumentLinkId }, HttpContext.Current.Request.IsSecureConnection ? "https" : "http"); }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

因此在视图中调用:

@model  IEnumerable<Document>
@using CustomerDashboard.ViewModels;
@using CustomerDashboard.Utilities;
@{ Layout = null; }
    @foreach (Document doc in Model)
    {
        <li>
            <a href="@doc.DownloadLink" class="documentDownload">
                <div class="col-sm-12 col-md-5 li-row li-row-icon">
                    <div class="pull-left">
                        <img height="40" src="/Content/img/file-icons/@doc.Icon" />
                    </div>
                    ...
             </a>
        </li>
    }
Run Code Online (Sandbox Code Playgroud)

虽然这是直接在另一个View中呈现的,但生成的链接很好,但是,我正在序列化部分并返回为JSON:

public string RenderRazorViewToString(string viewName, object model)
    {
        //https://gist.github.com/timiles/2828976 
        ViewData.Model = model;
        using (var sw = new StringWriter())
        {
            var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext,
                                                                     viewName);
            var viewContext = new ViewContext(ControllerContext, viewResult.View,
                                         ViewData, TempData, sw);
            viewResult.View.Render(viewContext, sw);
            viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
            return sw.GetStringBuilder().ToString();
        }
    }
Run Code Online (Sandbox Code Playgroud)

然后从控制器返回Json:

        return Json(new { 
            totalCount = (int)Session["DocumentTotalCount"], 
            markup = RenderRazorViewToString("_DocumentListAjax", docs) 
        },JsonRequestBehavior.AllowGet);
Run Code Online (Sandbox Code Playgroud)

但要清楚,问题是在JSON序列化之前发生的 - 这很讨厌,但删除了www前缀:

        return Json(new { 
            totalCount = (int)Session["DocumentTotalCount"], 
            markup = RenderRazorViewToString("_DocumentListAjax", docs).Replace("www.","") 
        },JsonRequestBehavior.AllowGet);
Run Code Online (Sandbox Code Playgroud)

当这样做时,从看似来自局域网外部(听起来很奇怪),所有的网址都有www前置 - 即https://example.com成为https://www.example.com.我正在努力追查为什么会发生这种情况以及如何解决这个问题.

Rom*_*nev 1

对于您的代码,所描述的行为只能在服务不同请求时发生。部分视图在另一个视图内的渲染必须作为处理上下文主机设置为的http请求的结果(例如对https://example.com/viewWithAPartialViewexample.com的请求)。

另一方面,提供包含部分视图的 JSON 是通过处理请求(例如对https://www.example.com/getPartialViewJson/partialViewNamewww.example.com的请求)来完成的。

由于在其主视图中渲染部分视图可能是在通过其“正常”url 浏览网站时完成的 - 一切都按计划进行。

JSON 端点可能通过 AJAX 查询,检查形成请求的代码 - 它是罪魁祸首。另一种可能性是您设置了 URL 重写来去除www前缀,并且由于某种原因重写规则与 JSON 服务端点不匹配。

更新:

鉴于附加信息,该问题似乎与托管配置(IIS 和负载均衡器设置)有关。我可以建议的是尝试将以下行添加到您的 web.config 文件中:

<appSettings>
  ...
  <add key="aspnet:UseHostHeaderForRequestUrl" value="true" />
  ...
</appSettings>
Run Code Online (Sandbox Code Playgroud)

这将强制 ASP.NET 使用传入请求中的主机标头,而不是请求服务器名称变量。如果问题的原因确实是配置问题,这应该会有所帮助。