简体   繁体   English

打开带有自定义属性和模型的asp.net mvc窗口

[英]asp.net mvc window open with custom properties and model

I have a form with submit, which opens a pdf file 我有一个带有“提交”的表格,它将打开一个pdf文件

@using (Html.BeginForm(null, null, new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, htmlAttributes: new { @class = "custom" }))
  {
   ......
   @Html.TextboxFor(m=>m.Name)
   <input type="submit" value="Open File"/>
  }

I want this to open the file in a new window. 我希望它在新窗口中打开文件。
- I need to pass the model to the post method (solution1) -我需要将模型传递给post方法(solution1)
- I can open the new window but i also need to name it and re-open a file in the same window. -我可以打开新窗口,但我也需要为其命名并在同一窗口中重新打开文件。 (solution2) (解决方案2)

I have the 2 possible solutions but I want to combine their features. 我有2种可能的解决方案,但我想结合它们的功能。

solution1:

@using (Html.BeginForm(null, null, new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, htmlAttributes: new { @class = "custom" }))
  {
   ......
   @Html.TextboxFor(m=>m.Name)
   <input type="submit" value="Open File" formtarget="_blank"/>
  }

solution2:

    @using (Html.BeginForm(null, null, new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, htmlAttributes: new { @class = "custom" }))
  {
    ......
    @Html.TextboxFor(m=>m.Name)
    <a href="#" onclick="fileDownload()" >Download File</a>
  }

<script type="text/javascript">
    function fileDownload() {

        var title = "my file";

        var win = window.open("@Url.Action("DisplayFile", "MyFile")?name=@Model.Name", title);
        win.onload = function () { this.document.title = title; };
    };
</script>

In Solution2 i don't want to pass model as url parameters, i want it to be a POST call. Solution2我不想将模型作为url参数传递,我希望它是POST调用。
In Solution1 i can't seem to customize the title of the new window. Solution1我似乎无法自定义新窗口的title

Either of the solutions are fine by me, so if someone can figureout one of them or a combination i'll just use that. 两种解决方案对我来说都很好,因此,如果有人可以找出其中一种解决方案,或者组合使用,我将使用它。

EDIT: updated with sample model value 编辑:用示例模型值更新

There's a couple of ways you could do this. 您可以通过以下两种方法进行操作。 Firstly, you could use the code from your solution 1 but add a parameter to your controller to accept the title of the new page. 首先,您可以使用解决方案1中的代码,但可以向控制器添加参数以接受新页面的标题。 The value can be set via a hidden field on the form (which you can manipulate via javascript). 可以通过表单上的隐藏字段(您可以通过javascript操作)设置该值。 You can then set a property on the ViewBag and output that in the title: 然后,您可以在ViewBag上设置一个属性,并在标题中输出该属性:

HTML: HTML:

<head>
    <title>@ViewBag.Title</title>
</head>

Form: 形成:

@using (Html.BeginForm(null, null, new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, htmlAttributes: new { @class = "custom" }))
{   
    @Html.TextBoxFor(m=>m.Name)
    @Html.Hidden("Title", "My File")
    <input type="submit" value="Open File" formtarget="_blank" />
}

Controller: 控制器:

[HttpPost]
public ActionResult Index(SomeClass model, string title)
{
    ViewBag.Title = title;

    //do something profound..

    return View(model);
}

Alternatively, you could intercept the submit and perform the post yourself via javascript then write the result manually to a new window. 或者,您可以拦截submit并通过javascript自己执行发布,然后将结果手动写入新窗口。 I've used jQuery below for ease as an example but this would be possible in pure javascript if you can't / don't want to use jQuery. 我在下面使用jQuery作为示例很容易,但是如果您不能/不想使用jQuery,则可以在纯JavaScript中实现。 I've given the form an id so I can access the submit event: 我给了表单一个ID,因此我可以访问Submit事件:

Form: 形成:

@using (Html.BeginForm(null, null, new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, htmlAttributes: new { @class = "custom", id="myForm" }))
{
    @Html.TextBoxFor(m => m.Name)
    <input type="submit" value="Open File" />
}

Script: 脚本:

$(document).on('submit', '#myForm', function (e) {
    $.ajax({
        url: $(this).attr('action'),
        type: 'POST',
        data: $(this).serialize(),
        success: function (response) {
            var win = window.open("about:blank", "_blank");
            var title = "my file";

            win.onload = function () {
                this.document.write(response);
                this.document.title = title;
            };
        }
    });

    return false;
});

Writing a PDF file to browser is tricky, especially cross browser. 将PDF文件写入浏览器非常棘手,尤其是跨浏览器。 You need to ensure that it has the correct Content headers, especially content-type which needs to be application/pdf . 您需要确保它具有正确的Content标头,尤其是content-type ,它需要是application/pdf You cannot set this via JavaScript so server-side rendering is your best option. 您无法通过JavaScript进行设置,因此服务器端渲染是您的最佳选择。 Do note that there are few client side options but they don't work well across all browsers. 请注意,客户端选项很少,但是它们不能在所有浏览器上正常工作。

Secondly, your 1st solution is fine because various browsers handle window title differently while displaying PDF files. 其次,您的第一种解决方案很好,因为各种浏览器在显示PDF文件时对窗口标题的处理方式不同。 Modern browsers read the PDF document's metadata and display Title property, if it has one. 现代浏览器读取PDF 文档的元数据并显示Title属性(如果有)。 If not, they just display the filename. 如果没有,它们只会显示文件名。 Older browser may display the filename if it has one or the temp file path or something else if nothing else is available. 如果旧的浏览器具有一个或临时文件路径,则它可能显示文件名;如果没有其他文件,则显示其他文件名。

Since you're not loading an HTML document, document.title has no meaning in this case. 由于您没有加载HTML文档,因此document.title在这种情况下没有意义。 This is default browser behavior and you can't control it, least of it in a way that works consistently across browsers. 这是默认的浏览器行为,您无法对其进行控制,至少不能以在所有浏览器之间都能正常工作的方式对其进行控制。

If PDF titles are not in your control, you can control the filename that gets shown (assuming the PDF doesn't have a title or for whatever reason, browser doesn't display it) by setting 如果PDF标题不在您的控制范围内,则可以通过设置来控制显示的文件名(假设PDF没有标题,或者由于某种原因,浏览器不会显示它)

Content-Disposition: inline; filename=<your title.pdf>

This header needs to be specified before specifying Content-Type and can only contain ASCII characters. 在指定Content-Type之前需要指定此标头,并且只能包含ASCII字符。

Another alternative (to show a custom title) is to show the PDF in a iFrame in the target page. 另一种选择 (显示自定义标题)是在目标页面的iFrame中显示PDF。 You can remove borders of the iframe, remove padding/margin of body element and adjust the height/width of iframe to match that of the window to make it look like you're only showing the PDF. 您可以删除iframe的边框,删除body元素的填充/边距,并调整iframe的高度/宽度以匹配窗口的高度/宽度,以使其看起来像仅显示PDF。 See this demo and corresponding source (to show the PDF in a iFrame that makes it look like its loaded in the main window). 请参阅此演示和相应的 (以在iFrame中显示PDF,使其看起来就像在主窗口中加载的一样)。

HTML 的HTML

<!DOCTYPE html>
<html>
<head>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
  <meta charset="utf-8">
  <title>Look ma - custom PDF title!</title>
</head>
<body>
  <div id=wrapper>
    <iframe src="http://www.cs.tut.fi/~jkorpela/latin9.pdf">
    </iframe>
  </div>
</body>
</html>

CSS 的CSS

body {
    margin: 0px;
    padding: 0px;
}

div#wrapper {
    position: fixed;
    width: 100%;
    height: 100%;
}

div#wrapper > iframe {
    display: block;
    width: 100%;
    height: 100%;
    border: none;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM