【问题标题】:Showing message in a razor view based on a result from execution of controller method根据控制器方法的执行结果在剃刀视图中显示消息
【发布时间】:2013-05-30 07:56:57
【问题描述】:

我正在开发 asp.net mvc 3 应用程序。我正在实现一个具有两个主要功能的剃须刀视图 - 根据数据库中的数据构建/显示表单,并在允许上传和删除的自定义(由我制作)图像库中显示与此表单相关的图像图片。

所以一般来说,这是我对两种表单的看法,用于可视化表单以及显示和上传图像:

@model List<DataAccess.MCS_DocumentFields>

@{
    ViewBag.Title = "Документ";
}
<div id="alabala">
<div id="drawForm">
@using (Html.BeginForm("UpdateDocument", "Forms", FormMethod.Post))
{
    <table border="1" id="drawDocument">
        <colgroup>
            <col span="1" style="width: 10%;" />
            <col span="1" style="width: 40%;" />
            <col span="1" style="width: 25%;" />
            <col span="1" style="width: 25%;" />
        </colgroup>
        @Html.Partial("_PartialHeader", Model)
        @Html.Partial("_PartialDrawing", Model)
        @Html.Partial("_PartialBody", Model)
        @Html.Partial("_PartialFooter", Model)

    </table>
    if (ViewBag.Status == 1)
    {
        <button type="submit" id="submitDocument">Запази</button> 
        <button style="float:right;" id="finalizeDocument">Приключи</button>  
    }
    else
    { 
        @Html.ActionLink("Назад", "Index")
    }
}
</div>
<div id="imageContainer">
<div id="imageGallery" style="overflow: scroll">
 <img src="file:\\..." alt="docImg" style="width: 190px; height: auto"/>
 @Ajax.ActionLink("Delete", "DeletePicture", new { documentID = Model[0].Id },
                        new AjaxOptions
                        {
                            Confirm = "Are you sure?",
                            OnComplete = "$('#blah').attr('src', '#').attr('style', 'display:none;'); $('#Image1').attr('src', '#').attr('style', 'display:none;'); $('#DelPic').attr('style', 'display:none;');"
                        })
 <img src="file:\\..." alt="docImg" style="width: 190px; height: auto"/>
  @Ajax.ActionLink("Delete", "DeletePicture", new { documentID = Model[0].Id },
                        new AjaxOptions
                        {
                            Confirm = "Are you sure?",
                            OnComplete = "$('#blah').attr('src', '#').attr('style', 'display:none;'); $('#Image1').attr('src', '#').attr('style', 'display:none;'); $('#DelPic').attr('style', 'display:none;');"
                        })
</div>
@using (Html.BeginForm("Upload", "Forms", FormMethod.Post))
{

    <input name=@Model[0].DocumentId type="hidden" />

    <input type="file" name="datafile" id="file" onchange="readURL(this);" />
    <input type="button" name="Button" value="Upload" id="UploadButton" onclick="fileUpload(this.form,'/forms/upload','upload'); return false;"/>
    <div id="upload" style="display: inline-block;">
        <img id="blah" src="#" alt="your image" style="display:none;"/>
    </div>
}
</div>
</div>

第一个表单是我显示当前表单/文档数据的地方,因为它们是可编辑的,所以我有提交按钮。我需要第二个表单将选定的图片提交给我的控制器并在那里执行业务逻辑。

因此,一旦选择了图片并单击了Upload 按钮,我就会进入我的控制器:

public ActionResult Upload(FormCollection collection)
        {
            WebImage UploadImage = WebImage.GetImageFromRequest();
            long documentID;
            string finalImageName = null;
            if (!long.TryParse(collection.AllKeys[0], out documentID))
            //More code...

我有图像和它所属的文档的 ID,我需要执行一些检查/验证,最后将选定的图像复制到专用目录并将名称保存到数据库。

问题是我已经编写了所有逻辑,除了会为不同输出显示正确消息的逻辑,例如:

if (imagePath.Length > 247)
                            {
                                //TODO message that the path is too long
                                //TODO this return View() is temp, replace with something suitable
                                return View();
                            }
                    //...
                         System.IO.File.Copy(UploadImage.FileName, imagePath);
                        }
                        catch (Exception ex)
                        {
                            //TODO copy failed return message
                            return View();
                        }
                    //...

这些都是执行相同方法的不同输出,在主视图中,我想为它们中的每一个显示适当的消息。我不确定我是否仍然可以选择保存我的工作并仍然实现消息逻辑?现在想想,如果我以某种形式使用 Ajax,现在会容易得多,但我不是。我能想到的唯一想法是创建 ViewBag 属性,并将其与模型一起返回到视图中,在该视图中检查不同的属性并在必要时显示一些消息,但这意味着在我的视图,重新发送我已经在视图中显示的数据库中的数据,简而言之,很多双重工作说,我认为这是一个糟糕的编程,但也许我自己陷入了这个困境。那么从这里开始最好的行动方案是什么。最好只删除我的代码并寻找使用 AJAX 的方法吗?

【问题讨论】:

    标签: c# jquery asp.net-mvc-3 razor


    【解决方案1】:

    您无法使用 AJAX 上传文件 - 您需要某种第 3 方解决方法。您需要使用适当的模型从 Upload() 方法返回原始视图,以及 ViewBag 中某处的标志以显示消息,例如

    public ActionResult Upload(UpdateDocumentModel model) {
    ...
      if (imagePath.Length > 247) {
        model.ErrorMessage = Errors.Over247;
        return View("UpdateDocument", model);
      }
    ...
    return RedirectToAction("UploadOk");
    }
    

    为了便于阅读,我已将您的 FormCollection 更改为强类型模型,而且这也是 MVC.net 的用途。 Errors.Over247 可以是项目中某处的字符串资源,或者是视图随后读取以显示某段 HTML 的布尔标志。

    【讨论】:

    • 您不需要 ViewBag,这只是为了说明,您可以将“Message”属性添加到您应该使用的 UpdateDocumentModel 中。
    【解决方案2】:

    只需使用 TempData 而不是 ViewBag

    TempData["ErorrMessegge"] = "SomeMessage to view";
    
    
    @TempData["ErorrMessegge"]
    

    【讨论】:

    • 嗯,我之前没见过TempData是asp.net mvc中的那个关键字吗?
    • 它是抽象类 ControllerBase 的 TempDataDictionary 属性。此字典中的数据仅在当前请求中“活动”。
    【解决方案3】:

    您可以简单地使用 TempData[] 将参数从控制器传递到视图,如下所示:

    控制器:

    [HttpPost]
    public ActionResult Add(Applicant applicant)
    {
        repository.SaveApplicant(applicant);
        TempData["message"] = "The applicant has been saved succesfully.";
        return View(applicant);
    }
    


    查看:

    @if (TempData["message"] != null)
    {
        <div>@TempData["message"]</div>
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多