【问题标题】:MVC Jquery Dialog Box not appearing on POSTMVC Jquery 对话框未出现在 POST 上
【发布时间】:2013-02-05 06:07:53
【问题描述】:

我正在使用带有 Jquery 对话框的 MVC C#。当我做一个 POST 时,我被重定向到一个普通页面 vs 对话框。

我的代码如下所示:

内部视图:

    <div id="dialog" title="" style="overflow: hidden;">
    </div>

在我的点击事件中,我有以下内容:

      $('#dialog').dialog({
                   autoOpen: false,
                   width: 500,
                   resizable: true,
                   title: 'PVT Report',
                   modal: true,           
                   buttons: {
                       "Close": function () {
                       $(this).dialog("close");
                        }
                      }
                  });


       $('#dialog').dialog('open');

                 $.ajax({
                           url: url,
                           type: 'GET',
                           success: function(result) {

                           if (result.success) 
                           {
                             $('#dialog').dialog('close');
                          } 
                           else 
                           {
                              $('#dialog').html(result);
                           }
                         }  
                  });
                 }

它会很好地转到 url 并显示对话框。 当我进行 POST 时,它并没有返回对话框,而是转到常规页面:

以下是我的 GET 和 POST:

     public ActionResult FileUpload(int id)
     {
        var model = new FileUpload { PlNum = id}           
        return PartialView(model);
     }


    [HttpPost]
    public ActionResult FileUpload(HttpPostedFileBase file, FileUpload model)
    {
        // Verify that the user selected a file
        if (file != null && file.ContentLength > 0)
        {
            // extract only the fielname
            var fileName = Path.GetFileName(file.FileName);
            string extension = Path.GetExtension(file.FileName);

            if (extension != ".pdf")
            {
                TempData["ErrMessage"] = "Error, wrong file type. File must be a PDF file.";
                return RedirectToAction("FileUpload", new { id = model.PlNum });
            }

.....

这是我的观点:

@using (Html.BeginForm("FileUpload", "Plt", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
       @Html.HiddenFor(a => a.PlNum)     
       <p>File upload for Pl# @Model.PlNum</p>
       <input type="file" name="file" />
       <input type="submit" value="OK" />
}

我认为使用 $.ajax 会很好。我认为我的问题之一是当我执行重定向操作时,对话框不再 打开..

请注意,无论哪种方式,如果成功或不成功,我都喜欢返回对话框。如果成功,将显示“成功”的消息。如果不成功,将出现错误消息。

【问题讨论】:

  • 发帖后$('#dialog').dialog('close');被解雇了吗?
  • 不确定这是否能回答您的问题,但是当视图出现时,我可以在对话框中的 Close 上点赞,它工作正常。如果我进行提交,我将被重定向到正常页面 - 不会返回对话框。希望这能回答你的问题。谢谢
  • 当你发帖时,你必须有一些 jquery 才能再次“打开”对话框。你是怎么处理的?你说“在我的点击事件中”是什么点击事件?
  • 我目前没有处理这个问题,像这样的脚本通常会去哪里。请注意,我正在使用 Jqgrid,因此单击单元格时我需要启动此对话框。这就是我上面提到的脚本的地方。
  • 你熟悉@Ajax.BeginForm(...吗? stackoverflow.com/questions/5410055/…

标签: jquery asp.net-mvc-3 jquery-ui-dialog


【解决方案1】:

为了确保我正确理解了您的问题,请允许我在回答之前先重申您的目标。如果我错了,请纠正我。

  1. 您希望在 jQuery UI 对话框中显示包含表单的部分视图
  2. 此表单包含一个文件上传输入,允许用户从他的计算机选择文件并将其上传到服务器
  3. 您希望此上传使用 AJAX 异步进行
  4. 如果上传成功,您要感谢用户上传文件并关闭 jQuery 对话框
  5. 如果在请求过程中出现错误,您希望向用户显示错误消息。例如,即使此字段是必填项,他也没有选择任何文件

如果我不理解您的某些目标,您可以停止阅读我的回答并更新您的问题,以提供有关您究竟想要实现什么的更多信息。

这里的挑战在于上传带有 AJAX 请求的文件。如您所知,这对于标准技术是不可能的。虽然有很多解决方法。您可以使用诸如UploadifyFineUploader 之类的插件,或者使用新的HTML5 File API,它允许您实现这一点,并且所有现代浏览器都支持它(不,IE9 不是现代浏览器,抱歉)。我将介绍 lats 选项,因为我们是 2013 年,我们都使用现代浏览器,没有人给出...关于 IE。

因此,就像在每个 ASP.NET MVC 应用程序中一样,我们可以从设计一个视图模型开始,该模型将满足我们的视图要求和我们希望在上传表单中包含的信息:

public class MyViewModel
{
    public int Id { get; set; }

    [Required]
    public HttpPostedFileBase File { get; set; }
}

然后我们可以有一个控制器来处理这个过程:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Upload(int id)
    {
        var model = new MyViewModel
        {
            Id = id
        };
        return PartialView(model);
    }

    [HttpPost]
    public ActionResult Upload(MyViewModel model)
    {
        if (!ModelState.IsValid)
        {
            // There was a validation error, probably the user didn't select any file
            // we set the status code to 400 (BadRequest) and return the 
            // same partial which will contain the validation error
            Response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
            return PartialView(model);
        }

        // at this stage we know that the model is valid => 
        // we could process the uploaded file. In this particular example
        // I am saving the uploaded file to the App_Data folder on the server
        // and ignoring the Id parameter of the view model. Obviously
        // in a more real world application here you might want to store the
        // physical location of this file in your data store as well as it's MIME type
        // so that you could display it later
        var file = Path.Combine(
            Server.MapPath("~/App_Data"), 
            Path.GetFileName(model.File.FileName)
        );
        model.File.SaveAs(file);

        // we have finished => let's set the response status code to 
        // 204 (NoContent) so that the client side javascript that I will show
        // later in my answer could distinguish this case from the error scenario
        Response.StatusCode = (int)System.Net.HttpStatusCode.NoContent;

        // we will return an EmptyResult because in this particular example
        // I don't really care about returning some information to the client
        // from the server. If you care you could of course set the status code 
        // to 200 (Success) and return, say, a JsonResult here
        return new EmptyResult();
    }
}

关于这个控制器没什么好说的。很标准的东西。一个Index 操作,用于提供一些虚拟视图,其中包含一个链接以启动上传过程。一个 Upload (GET) 操作来提供部分上传表单,当然还有一个 Upload (POST) 操作来处理实际文件上传(在这个过于简单的示例中,我将文件存储在服务器上)。

那么我们就可以得到对应的~/Views/Home/Index.cshtml dummy view:

@model MyViewModel
@Html.ActionLink(
    "click here to upload a file", 
    "Upload", 
    new { id = 154 }, 
    new { id = "uploadLink" }
)
<div id="dialog"></div>

简单:一个强类型视图,其中包含一个锚点,该锚点随后(见我的回答后面)将被 AJAX 化,以便在 jQuery 对话框中显示上传部分和对话框的 div 占位符。

接下来我们可以编写包含表单 (~/Views/Home/Upload.cshtml) 的上传部分:

@model MyViewModel

@using (Html.BeginForm(null, null, new { id = Model.Id }, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <div>
        @Html.LabelFor(x => x.File)
        @Html.TextBoxFor(x => x.File, new { type = "file" })
        @Html.ValidationMessageFor(x => x.File)
    </div>
    <button type="submit">Upload</button>
}

再一次,这里是非常标准的东西 => 一个包含文件输入的 HTML 表单,允许用户选择要上传的文件。

最后一步当然是让这一切变得生动的 javascript。您可以将此 javascript 放在您从 _Layout 覆盖的索引视图内的脚本部分中。理想情况下,脚本应该放在文档的末尾,在结束 &lt;/body&gt; 标记之前(这就是我没有将 .click() 处理程序订阅包装在 document.ready 中的原因):

$('#uploadLink').click(function () {
    $.ajax({
        url: this.href,
        type: 'GET',
        cache: false,
        success: function (result) {
            $('#dialog').html(result).dialog({
                autoOpen: true,
                width: 500,
                resizable: true,
                title: 'PVT Report',
                modal: true,
                buttons: {
                    'Close': function () {
                        $(this).dialog("close");
                    }
                }
            });
        }
    });
    return false;
});

$('#dialog').on('submit', 'form', function () {
    var xhr = new XMLHttpRequest();
    xhr.open(this.method, this.action);
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
            if (xhr.status == 204) {
                // upload was successful => thank the user and close
                // the dialog
                alert('Thank you for uploading the file');
                $('#dialog').dialog('close');
            } else if (xhr.status == 400) {
                // validation error occurred on the server => redisplay the form
                $('#dialog').html(xhr.responseText);
            }
        }
    };
    xhr.send(new FormData(this));
    return false;
});

2 个事件由这个 javascript 处理:在显示 jQuery 对话框的主视图中单击锚点,以及将使用 AJAX 请求和 HTML 5 File API 上传文件的表单提交。

【讨论】:

  • 谢谢达林,我修改了我的问题,但我觉得看你的例子,我可以解决这个问题。非常感谢!
猜你喜欢
  • 2020-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多