【问题标题】:MVC JsonResult replaces whole page when called through jQuery ajax通过 jQuery ajax 调用时,MVC JsonResult 替换整个页面
【发布时间】:2016-05-22 10:57:59
【问题描述】:

我有一个问题,到现在我还没有解决它。

首先让我解释一下如何在这个简单的页面上进行设置。

我有一个用于输入新数据和编辑现有数据的视图。该视图将获得一个类型为 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。

这是我得到的错误控制台,但对我来说毫无意义。

任何想法为什么会发生这种情况?我用 lint 工具检查了 Json 结果,它报告它是有效的,所以没有格式错误的 Json。我还想指出,我使用了 ajax 选项,使用了 dataType 和没有它,以及使用了 content type 和没有它。没有区别。

【问题讨论】:

  • 请将 processData: false 添加到您的 ajax 帖子中。
  • 你在做一个普通的提交以及你的 ajax 提交。
  • @B.Yaylaci 如果我添加 processData: false 那么我的操作根本不会被调用。我只会得到内部服务器错误。在这种情况下,将调用错误方法,我将收到内部服务器错误。
  • @StephenMuecke 我很好奇。你是什​​么意思我正在提交以及ajax提交。我的提交处理程序是验证器的一部分,所以如果一切顺利,该方法将被调用,并且该方法本身具有 ajax。我认为这只是发给服务器的一篇文章。
  • 是的,它调用了你的ajax,但是你没有在哪里取消提交按钮的默认操作。 (一旦你取消它,ajax 代码无论如何都会失败)

标签: jquery json ajax asp.net-mvc


【解决方案1】:

首先我要感谢所有人。我得到了一些对我帮助很大的不错的 cmets。

其次,我不知道有什么诀窍,因为我是这种网络编程的新手。我想说我没有改变服务器端的任何东西。我唯一做的就是玩弄 ajax 选项。

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 结果,该结果将完全替换我的页面,并且永远不会调用我的成功方法。

如果有人想解释为什么这是必要的,那就太好了。

我还认为,因为我还要发布一个文件,所以这变得更加复杂,因为我必须发布表单数据而不是纯字符串。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-06
    • 1970-01-01
    • 1970-01-01
    • 2017-01-15
    • 2014-06-03
    • 2014-01-27
    • 1970-01-01
    相关资源
    最近更新 更多