【问题标题】:Empty first line in razor mvc 4 rcrazor mvc 4 rc中的空第一行
【发布时间】:2012-07-04 11:02:22
【问题描述】:

我已经从 mvc 3 迁移到 mvc 4 并且遇到了以下问题。

@using InvoiceDocflow.Controllers
@{
    Response.ContentType = "text/xml";
}
<?xml version="1.1" encoding="UTF-8" ?>
<dc>
    @foreach (var dcLink in (IEnumerable<DcLink>)ViewData["SupportedDcs"])
    {
        <link rel="@dcLink.RelUri.ToString()" href="@dcLink.DcUri.ToString()" />
    }
</dc>

这是我的看法。我的布局只有一行

@RenderBody()

所以在 mvc 3 中 &lt;?xml version="1.1" encoding="UTF-8" ?&gt; 出现在第一行,但现在,它出现在第二行,第一行为空。

我可以让它像在 mvc 3 中一样呈现在第一行吗?

顺便说一句。

@using InvoiceDocflow.Controllers
@{
    Response.ContentType = "text/xml";
}<?xml version="1.1" encoding="UTF-8" ?>

这可行,但这根本不是我想做的。

【问题讨论】:

  • 我在 Mvc4 行为中看不到任何 bsd :它在页面中复制代码块之外的所有回车符,所以如果你不想要回车符,你必须放
  • 我不需要代码块来隐式影响输出。这是错误的。在 MVC 3 中没问题。
  • 重点是回车在代码块外所以在outpunt中报告。虽然 Vb 是面向行的,但 C# 不是。很明显,Mvc 4 对代码块的定义与 Mvc3 不同……但我认为不能说 Mvc 4 的定义“是错误的”……只是不同而已。
  • 为什么不使用自定义操作结果来生成 XML?像在视图中那样手动创建 XML 而不是使用 XML 解析器是非常危险的。

标签: razor asp.net-mvc-4


【解决方案1】:

我在尝试返回缓存清单文件时遇到了类似的问题,页面顶部有空白行。解决方案,添加一个 Response.Write("..."),这将在页面的第一行。

 @{
     Layout = null;
     Response.Write("CACHE MANIFEST");

} .......

【讨论】:

  • 这个被低估的答案对我有用。 XML 文件的第一行必须有 doctype,并且没有任何前导空格。 @{ } 部分在页面上的任何其他内容之前执行。因此 Response.Write() 也将在 Razor 在页面内容之前添加领先的无关空白之前执行。正如其他一些答案中所建议的那样,将文档类型移动到视图顶部并没有解决问题。
【解决方案2】:

临时修复? ActionFilter 并去掉空的第一行?显然,如果合适,您还可以对响应进行其他缩小。

public class TranslationFilter : MemoryStream
{
    private Stream filter = null;

    public TranslationFilter(HttpResponseBase httpResponseBase)
    {
        filter = httpResponseBase.Filter;
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        var response = UTF8Encoding.UTF8.GetString(buffer);

        // remove all newlines
        response = response.Replace(System.Environment.NewLine, "");

        /* remove just first empty line
          if (response.Substring(0, 2) == "\r\n")
        {
            response = response.Substring(2, response.Length - 2);
        } */

        filter.Write(UTF8Encoding.UTF8.GetBytes(response), offset, UTF8Encoding.UTF8.GetByteCount(response));
    }
}

public class ResponseFilter : ActionFilterAttribute
{
    public ResponseFilter()
    {
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        base.OnResultExecuted(filterContext);
        filterContext.HttpContext.Response.Filter = new TranslationFilter(filterContext.HttpContext.Response);
    }
}

并将其添加到 Controller 方法中?

[ResponseFilter]
public ActionResult Index()
{
return View();
}

【讨论】:

  • 这不是完整的解决方案。每个 @{} 块上都会出现新行(不仅是第一个),所以我更喜欢能够处理该问题的解决方案。但是,如果没有其他选择,我会接受你的问题。
  • 已调整以删除所有新行,但显然这可能不是您想要的 - 使得在浏览器中阅读 html 源代码变得更加困难。很高兴我得到了帮助。
  • 这不是删除所有新行。这是关于删除由 @{} 块引起的行。
  • 我相信这个错误在 WhitespaceRewriter.csRazorParser.cs 的某个地方。任何人都可以发送带有更正的拉取请求吗?
【解决方案3】:

我知道这是一个老问题,但我在寻找该问题的解决方案时发现了它。 由于没有人有一个简单的解决方案,这里是我的:

我能够通过使用局部视图而不是普通视图来解决此问题。 我相信问题归结于布局,即使您将其设置为 null 它似乎仍然会添加一个空白的第一行。 @{} 广告也是一个空白行,因此您必须将其移至视图底部。

所以只需添加一个局部视图并让您的控制器返回局部视图:

public ActionResult GenerateXML()
{
    return PartialView("_XML");
}

然后在您的局部视图中,您需要像这样设置它(底部带有您的@{}):

@model string
<?xml version="1.0" encoding="UTF-8" ?>
<response>
    <message>@Model</message>
</response>
@{ Response.ContentType = "text/xml";}

这将产生一个 HTML 源代码:

<?xml version="1.0" encoding="UTF-8" ?>
<response>
    <message>Response Message</message>
</response>

我希望这对遇到此问题的其他人有所帮助。

【讨论】:

    【解决方案4】:

    我知道您建议将标签移到 @{} 的末尾,但为什么不把它放在前面。此外,这个空白是否会导致错误或问题?您可以清楚地看到这是因为您的代码创建了空白,而不是来自 mvc 或 razor。

    大概是这样的:

    @using InvoiceDocflow.Controllers
    <?xml version="1.1" encoding="UTF-8" ?>
    @{
     Response.ContentType = "text/xml";
    }
    

    【讨论】:

      【解决方案5】:

      上面的解决方案都不适合我,所以在花了很长时间尝试修复它之后 - 它应该很容易,因为它只是一个空行 - 我写了一篇关于它的博客文章。

      http://devstuffs.wordpress.com/2014/02/07/first-line-empty-in-razor/

      【讨论】:

      • “解决方案 2”效果很好(我正在生成一个缓存清单文件)。感谢分享!
      • evanswd 在评论中的建议对我来说效果很好,真的很简单!
      • 请在答案中嵌入解决方案的摘要或将此链接转换为评论。
      【解决方案6】:

      我用这种方式解决了类似的问题:

      _ViewStart.cshtml

      @{
          Layout = null;
          Response.Write("<!DOCTYPE html>");
      }
      

      另一个.cshtml

      @model ViewModel<EshopWebsiteOrder>
      <html>
      <head>
          <meta charset="utf-8" />
      

      最后,在一处定义通用 DOCTYPE 是有意义的。

      【讨论】:

        【解决方案7】:

        另一个没有 ResponseFilter 的简单修复。只需将 @using 放在 cshtml 文件的底部即可:

        <?xml version="1.1" encoding="UTF-8" ?>
        <dc>
            @foreach (var dcLink in (IEnumerable<DcLink>)ViewData["SupportedDcs"])
            {
                <link rel="@dcLink.RelUri.ToString()" href="@dcLink.DcUri.ToString()" />
            }
        </dc>
        @using InvoiceDocflow.Controllers
        @{
            Response.ContentType = "text/xml";
        }
        

        【讨论】:

          【解决方案8】:

          如果你搬家:

          <?xml version="1.1" encoding="UTF-8" ?>
          

          进入布局模板的顶部,然后让您的 xml 页面继承它并输出它应该工作的 xml 数据。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-06-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-07-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多