1

我目前正在 MVC3 中构建我的第一个应用程序。在我的一种观点中,有两种形式。一种方法是仅使用 AJAX 选择图像并在页面中显示/上传它(调用另一个控制器并使用隐藏的 IFrame,如本文中所示。另一种形式是输入姓名、地址等信息。此外,当使用第一种形式选择并导入图像时,会在第二种形式中填充一个隐藏字段,以便在调用 Create 控件时创建所有内容在数据库中。

所有这一切都完美无缺,但如果用户犯了错误并在第二种形式的数字字段中输入文本,我的模型的验证会得到注意,并且有一个以红色显示错误的回发。通过这样做,第一个表单会丢失所有信息,并使用文件输入控件重置,并且不显示图像。

有谁知道如何解决这个问题?我对 MVC3 和 AJAX 很陌生,所以也许我做错了什么。

我的最终目标是,一旦图片显示在页面中(并上传),它将保留在那里,直到第二个表单被验证并发送到我的创建控制器。

谢谢!

编辑:有些人要代码,就在这里!这是视图:

@model RecettesMaison.Models.Recipe

@{
    ViewBag.Title = "Create";
}

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.min.js" type="text/javascript"></script>

<script type="text/javascript">
    var isFirstLoad = true;
    var loadingImg;

    function UploadImage() {
        var fileUploader = document.getElementById("fileuploader");
        $(fileUploader).hide();

        //Create a new image and insert it into the Images div.  Just to be fancy, 
        //we're going to use a "FadeIn" effect from jQuery
        var imgDiv = document.getElementById("Images");
        loadingImg = new Image();
        loadingImg.src = "../../Pictures/ajax-loader.gif";

        //Hide the image before adding to the DOM
        $(loadingImg).hide();
        imgDiv.appendChild(loadingImg);
        //Now fade the image in
        $(loadingImg).fadeIn(500, null);

        $("#ImgForm").submit();
    }

    function UploadImage_Complete() {
        //Check to see if this is the first load of the iFrame
        if (isFirstLoad == true) {
            isFirstLoad = false;
            return;
        }

        //Reset the image form so the file won't get uploaded again
        document.getElementById("ImgForm").reset();

        //Grab the content of the textarea we named jsonResult .  This shold be loaded into 
        //the hidden iFrame.
        var newImg = $.parseJSON($("#UploadTarget").contents().find("#jsonResult")[0].innerHTML);

        //If there was an error, display it to the user
        if (newImg.IsValid == false) {
            alert(newImg.Message);
            return;
        }

        //Create a new image and insert it into the Images div.  Just to be fancy, 
        //we're going to use a "FadeIn" effect from jQuery
        var imgDiv = document.getElementById("Images");
        var img = new Image();
        img.src = newImg.ImagePath;
        img.name = "uploadedImage";


        var input = document.createElement("input");
        input.setAttribute("type", "hidden");
        input.setAttribute("name", "Picture");
        input.setAttribute("id", "Picture");
        input.setAttribute("value", newImg.RealName);
        document.getElementById("Hidden").appendChild(input);

        //Hide the image before adding to the DOM
        $(img).hide();
        imgDiv.removeChild(loadingImg)
        imgDiv.appendChild(img);
        $(img).addClass('img-polaroid');

        //Now fade the image in
        $(img).fadeIn(500, null);
    }
</script>

<iframe id="UploadTarget" name="UploadTarget" onload="UploadImage_Complete();" style="position: absolute; left: -999em; top: -999em;"></iframe>
    <fieldset>
        <div class="row-fluid">
          <div class="span12">
            <h4>Publier une recette</h4>
            <div class="row-fluid">
              <div class="span3">

                @using (Html.BeginForm("UploadImage", "Recipe", FormMethod.Post,
                    new
                    {
                        enctype = "multipart/form-data",
                        id = "ImgForm",
                        name = "ImgForm",
                        target = "UploadTarget"
                    }))
                {
                    <div id="fileuploader">
                    <input id="lefile" type="file" style="display:none" name="imageFile" accept="image/x-png, image/jpeg" />
                    <div class="input-append">
                       <input id="photoCover" class="input-large" type="text" />
                       <a class="btn" onclick="$('input[id=lefile]').click();">Parcourir...</a>
                    </div>

                    <script type="text/javascript">
                        $('input[id=lefile]').change(function () {
                            $('#photoCover').val($(this).val());
                        }); 
                    </script>
                    <input type="button" class="btn btn-success" value="Sauvegarder l'image" onclick="UploadImage()" />
                    </div>

                    <div id="Images"></div>
                }
              </div>
              <div class="span9">
              @using (Html.BeginForm("Create", "Recipe", FormMethod.Post, new { id = "realForm", name = "realform" }))
              {
                @Html.ValidationSummary(true)
                <div id="Hidden"></div>
                <div class="editor-label">
                    @Html.LabelFor(model => model.RecipeName) <div class="alert alert-info">Soyez original!</div>
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.RecipeName)
                    @Html.ValidationMessageFor(model => model.RecipeName)
                </div>

                <div class="editor-label">
                    @Html.LabelFor(model => model.Source) <div class="alert alert-info">(Exemple: Ricardo, Food Channel, Blog de Jean Cuisine, etc...)</div>
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.Source)
                    @Html.ValidationMessageFor(model => model.Source)
                </div>

                <div class="editor-label">
                    @Html.LabelFor(model => model.PreparationTime)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.PreparationTime) minutes
                    @Html.ValidationMessageFor(model => model.PreparationTime)
                </div>

                <div class="editor-label">
                    @Html.LabelFor(model => model.CookingTime)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.CookingTime) minutes
                    @Html.ValidationMessageFor(model => model.CookingTime)
                </div>

                <div class="editor-label">
                    @Html.LabelFor(model => model.MacerationTime)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.MacerationTime) minutes
                    @Html.ValidationMessageFor(model => model.MacerationTime)
                </div>

                <div class="editor-label">
                    @Html.LabelFor(model => model.Portions) <div class="alert alert-info">Combien d'adultes cette recettes peut nourir?</div>
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.Portions)
                    @Html.ValidationMessageFor(model => model.Portions)
                </div>

                <div class="editor-label">
                    @Html.LabelFor(model => model.Commentary) <div class="alert alert-info">Partagez votre expérience avec cette recette, que ce soit au moment de sa création ou de sa préparation. <br />Dites les modifications que vous faites à la recette originale.<br />Rendez cette recettes personnelle! </div>
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.Commentary)
                    @Html.ValidationMessageFor(model => model.Commentary)
                </div>
                <p>
                    <input type="submit" class="btn btn-success" value="Publier la recette!" />
                </p>
              }
              </div>
            </div>
          </div>
        </div>
    </fieldset>

这是发送图片的控制器

[HttpPost]
public WrappedJsonResult UploadImage(HttpPostedFileWrapper imageFile)
{

    if (imageFile == null || imageFile.ContentLength == 0)
    {
        return new WrappedJsonResult
        {
           Data = new
           {
                IsValid = false,
                Message = "No file was uploaded.",
                ImagePath = string.Empty
            }
        };
    }

    if (imageFile.ContentType != "image/jpeg" && imageFile.ContentType != "image/png")
    {
        return new WrappedJsonResult
        {
            Data = new
            {
                IsValid = false,
                Message = "Mauvais format de fichier!",
                ImagePath = string.Empty
            }
        };
    }

    int nIndexPoint = imageFile.FileName.IndexOf(".");
    string strExtension = imageFile.FileName.Substring(nIndexPoint + 1);

    var fileName = String.Format("{0}.{1}", Guid.NewGuid().ToString(), strExtension);

    var imagePathFull = Path.Combine(Server.MapPath(Url.Content("~/Pictures/Upload/FullSize")), fileName);
    var imagePathThumb = Path.Combine(Server.MapPath(Url.Content("~/Pictures/Upload/Thumbnail")), fileName);

    imageFile.SaveAs(imagePathFull);
    ThumbnailGenerator generator = new ThumbnailGenerator();
    generator.GetThumbnail(imagePathFull, imagePathThumb);

    return new WrappedJsonResult
    {
        Data = new
       {
            IsValid = true,
            Message = string.Empty,
            ImagePath = Url.Content(String.Format("~/Pictures/Upload/Thumbnail/{0}", fileName)),
            RealName = fileName
        }
    };
}

最后,这是第二种形式调用的控制器。

[HttpPost]
public ActionResult Create(Recipe recipe)
{
      if (ModelState.IsValid)
      {
          db.Recipes.Add(recipe);
          db.SaveChanges();
          return RedirectToAction("Index");  
      }

      return View(recipe);
}
4

1 回答 1

2

您需要将图像(或者看起来只是文件名)作为配方模型的一部分,并将其以第二种形式存储在 Html.HiddenFor 元素中。

然后,您将需要一个 document.ready jQuery 函数来查看是否有一个 flyname 可用,如果有则显示它。可能这应该调用您在上传完成时调用的相同函数。

最后,当在 ajax 方法中完成上传时,使用 jQuery 使用图像文件名更新隐藏字段,现在当您回发时,您的模型具有显示完整视图所需的所有信息,包括图片。

有道理?

于 2012-09-20T19:58:53.187 回答