2016-05-22 58 views
-1

我有一個問題,並且到目前爲止我還沒有能夠解決它。當通過jQuery調用MVC JsonResult替換整個頁面ajax

讓我先解釋一下在這個簡單的頁面上如何設置事物。

我有一個用於輸入新的和編輯現有數據的視圖。這個視圖將得到一個類型爲category的強類型模型。

public class Category 
{ 
    public int CategoryID { get; set; } 
    public string CategoryName { get; set; } 
    public string CategoryDescription { get; set; } 
    public string CategoryImage { get; set; } 
} 

我的控制器動作是這樣設置的。

[HttpPost] 
[ValidateAntiForgeryToken] 
public JsonResult Edit(Category category) 
{ 
    Database db = new Database(); 

    if (!category.IsNew) 
    db.Category.Attach(category); 

    if (Request.Files.Count > 0) 
    { 
     var uploadedFile = Request.Files[0];   
     string fileName = string.Format("{0}.{1}", category.CategoryName, uploadedFile.ContentType.Split('/')[1]); 
     var path = Path.Combine(Server.MapPath("~/images/category"), fileName); 
     Request.Files[0].SaveAs(path); 
     category.CategoryImage = string.Format("/images/category/{0}", fileName); 
    } 

    if (db.Entry<Category>(category).State == System.Data.Entity.EntityState.Detached) 
    db.Category.Add(category); 

    db.SaveChanges(); 
    Response.StatusCode = (int)HttpStatusCode.InternalServerError; 

    return Json(Newtonsoft.Json.JsonConvert.SerializeObject(category)); 
} 

因此,我得到強類型的對象,並返回JSON結果。這是因爲我可以替換客戶端上的圖像,因爲用戶選擇的圖像將被重命名爲類別名稱。

這是我的看法。

@model Category 

@{ 
    var id = Model.CategoryID; 
    var name = Model.CategoryName; 
    var description = Model.CategoryDescription; 
    var image = Model.IsNew ? "/images/image_default.png" : Model.CategoryImage; 
} 

<style> 
    img { 
     width: 128px; 
    } 
</style> 

@{ 
    ViewBag.Title = "Category"; 
} 

<br /> 

<div class="card"> 
    <div class="card-content"> 
     <div class="card-title"> 
      <h2 class="header">Category</h2> 
     </div> 
     <form id="editForm" method="post" enctype="multipart/form-data"> 
      @Html.AntiForgeryToken() 
      <div class="center-align"> 
       <img id="image" class="responsive-img circle" src="@image" /> 
      </div> 
      <br /> 
      <input id="CategoryID" name="CategoryID" type="hidden" value="@id" /> 
      <div class="input-field"> 
       <input name="CategoryName" type="text" class="" value="@name"> 
       <label for="CategoryName" data-errord="">Name</label> 
      </div> 
      <div class="input-field"> 
       <textarea name="CategoryDescription" class="materialize-textarea">@description</textarea> 
       <label for="CategoryDescription" data-error="">Description</label> 
      </div> 
      <div class="file-field input-field"> 
       <div class="btn"> 
        <span>Image</span> 
        <input name="CategoryImage" type="file" accept=".jpg,.gif,.png"> 
       </div> 
       <div class="file-path-wrapper"> 
        <input name="CategoryImagePath" class="file-path" placeholder="Upload category image" type="text"> 
        <label for="CategoryImagePath" data-error=""></label> 
       </div> 
      </div> 
      <br /> 
      <br /> 
      <div class="card-action"> 
       <button id="save" type="submit" class="waves-effect waves-light btn-large">Save</button> 
       <a id="delete" class="waves-effect waves-light btn-large">Delete</a> 
       <a id="back" href="@Url.Action("Index", "Category")" class="waves-effect waves-light btn-large">Back</a> 
      </div> 
     </form> 
    </div> 
</div> 
@section Script{ 
    <script> 
     $('#delete').click(function(event){ 
      event.preventDefault(); 
      var form = $('#editForm'); 
      $.ajax(
       { 
        url: '@Url.Action("Delete", "Category")', 
        data: JSON.stringify({id: $('#CategoryID').val()}), 
        type: 'DELETE', 
        contentType: "application/json;charset=utf-8" 
       }); 
     }); 

     $("#editForm").validate({ 
      errorClass: 'invalid', 
      validClass: "valid", 
      rules: { 
       CategoryName: { 
        required: true, 
        maxlength: 64 
       }, 
       CategoryDescription: { 
        required: true, 
        maxlength: 512 
       }, 
       CategoryImagePath: { 
        required: @Model.IsNew.ToString().ToLower() 
       } 
      }, 
      //For custom messages 
      messages: { 
       CategoryName: { 
        required: "Name is required", 
        maxlength: $.validator.format("Maximum nuber of characters is {0}") 
       }, 
       CategoryDescription: { 
        required: "Description is required", 
        maxlength: $.validator.format("Maximum nuber of characters is {0}") 
       }, 
       CategoryImagePath: { 
        required: "Please select image for category" 
       } 
      }, 
      submitHandler: function() { 
       var form = $('#editForm'); 
       if(form.valid() == false) 
        return; 
       var formData = new FormData($('#editForm')[0]); 
       $.ajax(
       { 
        async: true, 
        type: 'POST', 
        data: formData, 
        dataType: 'json', 
        contentType: 'application/json; charset=utf-8', 
        success: function(data, textStatus, jqXHR){ 
         alert(''); 
         $('#image').attr('src', jQuery.parseJSON(data).CategoryImage); 
         Materialize.toast("Successfully saved.", 3000); 
        }, 
        error: function(jqXHR, textStatus, errorThrown){ 
         alert(''); 
        } 
       }) 
      }, 
      errorPlacement: function (error, element) { 
       element.next("label").attr("data-error", error.contents().text()); 
      } 
     }); 
    </script> 
} 

問題是整個頁面被Json結果取代。此外,成功方法永遠不會被調用。錯誤也沒有。我可以在網絡中看到我得到了響應200 OK。

這是我得到的錯誤控制檯,但它對我沒有意義。

enter image description here

任何想法,爲什麼發生這種情況?我用lint工具檢查了Json結果,並報告它是有效的,所以沒有畸形的Json。我還想指出,我使用ajax選項,並使用dataType,沒有它和內容類型一樣,沒有它。沒什麼區別。

+0

請將'processData:false'添加到您的ajax文章中。 – Berkay

+0

你正在做一個正常的提交以及你的ajax提交。 –

+0

@ B.Yaylaci如果我添加processData:false,那麼我的操作根本不會被調用。我只會得到內部服務器錯誤。在這種情況下,錯誤方法將被調用,我會得到內部服務器錯誤。 – Rob

回答

0

首先我要感謝所有人。我有一些很好的評論,幫助我很多。

其次,我不知道這個技巧是什麼,因爲我是這種網絡編程的新手。我想說,我沒有改變服務器端的任何東西。我唯一做的事情就是玩阿賈克斯選項。

submitHandler: function (form, event) { 
        var formObj = $('#editForm'); 
        if(formObj.valid() == false) 
         return false; 
        var formData = new FormData($('#editForm')[0]); 
        $.ajax(
        { 
         type: 'POST', 
         data: formData, 
         dataType: 'json', 
         processData: false, 
         contentType: false, 
         success: function(responseData){ 
          $('#image').attr('src', responseData.CategoryImage); 
          Materialize.toast("Successfully saved.", 3000); 
         } 
        }); 
       } 

這似乎是processDatacontentType的伎倆在一定程度上。

如果我假設processData爲false並且完全刪除contentType我將得到內部服務器錯誤。如果我完全刪除processData並將contentType設置爲false,我將得到完整的JSON結果,它將完全替換我的頁面,並且我的成功方法將永遠不會被調用。

如果有人想解釋爲什麼這是非常必要的。

我也認爲,因爲我發佈文件以及這得到了更復雜,因爲我必須張貼表單數據而不是純字符串。

相關問題