1

現在、MVC3 で最初のアプリケーションを構築しています。私の見解の 1 つでは、2 つの形式があります。1つは、画像を選択し、AJAXを使用してページに表示/アップロードするだけです(別のコントローラーを呼び出し、この投稿のように非表示のIFrameを使用します)。もう 1 つのフォームは、名前、住所などの情報を入力するためのものです。また、最初のフォームを使用して画像を選択してインポートすると、2 番目のフォームに隠しフィールドが入力され、Create コントローラーが呼び出されたときにすべてが作成されます。データベースで。

これはすべて完全に機能しますが、ユーザーが間違いを犯して 2 番目のフォームの数値フィールドにテキストを入力すると、モデルの検証が行われ、エラーを赤で示すポストバックが表示されます。そうすることで、最初のフォームはすべての情報を失い、ファイル入力コントロールでリセットされ、画像は表示されません。

この問題を回避する方法を知っている人はいますか? 私はMVC3とAJAXに非常に慣れていないので、何か間違っているかもしれません。

私の最終的な目標は、画像がページに表示される (およびアップロードされる) と、2 番目のフォームが検証されて Create コントローラーに送信されるまでそこにとどまることです。

ありがとう!

編集: コードを要求する人もいますが、ここにあります! これはビューです:

@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
        }
    };
}

最後に、2 番目のフォームによって呼び出されるコントローラーを次に示します。

[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 要素の 2 番目のフォームに格納する必要があります。

次に、fliename が使用可能かどうかを確認し、ある場合はそれを表示する document.ready jQuery 関数が必要になります。おそらく、これはアップロードが完了したときに呼び出すのと同じ関数を呼び出す必要があります。

最後に、ajax メソッドでアップロードが完了したら、jQuery を使用して隠しフィールドを画像ファイル名で更新します。これで、モデルをポストバックすると、画像を含む完全なビューを表示するために必要なすべての情報が得られます。

わかる?

于 2012-09-20T19:58:53.187 に答える