代码之家  ›  专栏  ›  技术社区  ›  Phil.Wheeler

更多Ajax/MVC的怪异之处

  •  4
  • Phil.Wheeler  · 技术社区  · 14 年前

    我有一个MVC操作结果,它接受一个项目ID和一个复杂的Json对象,如下所示:

    [HttpPost]
    public JsonResult AddStory(int projectid, Story story)
    {
        try
        {
            Project prj = repository.Single(p => p.ID == projectid);
    
            //prj.Stories.Add(story);
            //repository.SaveChanges();
    
            return Json(new { Result = story });
        }
        catch (Exception ex)
        {
            ErrorSignal.FromCurrentContext().Raise(ex);
    
            return Json(new { Result = 0 });
        }
    }
    

    $.ajax({
        url: '/Project/1/AddStory',
        data: { Summary: myStory.Summary, Size: myStory.Size },
        dataType: 'json',
        processData: false,
        traditional: true,
        type: 'POST'
    });
    

    我的问题是,无论我如何张贴这个对象;即使我将其发送到另一个控制器和操作,请求似乎也不会命中服务器,并且页面会自动重定向到以下URL:

    http://localhost:57932/Project/1/Board?story.Summary=Test+description&story.Size=8&story.Priority=2&story.Deadline=08%2F31%2F2010&story-owner=http%3A%2F%2Ftestaccount.myopenid.com

    Firebug的控制台显示jQuery.min.js 标题正确,但没有POST或RESPONSE值。

    接受application/json, /

    查询字符串中肯定有一个对象正在发送。那我还缺什么?我相信事情变得如此糟糕肯定有一个简单的原因。

    编辑:

    路线(从Global.asax)是以下加上默认映射路由:

        routes.MapRoute(
            "Project",
            "Project/{projectid}/{action}/{id}",
            new { controller = "Project", action = "Index", id = "" });
    
    4 回复  |  直到 14 年前
        1
  •  3
  •   Igor Zevaka    14 年前

    结果发现解决方法很简单。由于以下原因,当前形状中的ajax调用根本不发送任何POST数据 processData = false

    $.ajax({
        url: '/Project/1/AddStory',
        data: { Summary: myStory.Summary, Size: myStory.Size },
        dataType: 'json',
        traditional: true,
        type: 'POST'
    });
    

    jQuery API文档有点迟钝:

    过程数据
    默认值:true

    默认情况下,数据传递到 作为对象的选项(技术上, 除了字符串以外的任何东西)都将 字符串,符合默认值 如果要发送文档,或 选项为false。

    $.ajax 不会将数据对象转换为名称值参数。不确定它的用途,但设置为false似乎是个坏主意:)

        2
  •  1
  •   Oleg    14 年前

    我没有你完整的源代码,所以很难说 您已请求从“/Project/1/AddStory”重定向到

    http://localhost:57932/Project/1/Board?story.Summary=Test+description&...
    

    我没试着重现你的问题。我用这个动作创建了一个小的mvc2应用程序 AddStory 在控制器中 Project 看起来像你的:

    [HttpPost]
    public JsonResult AddStory (int projectid, Story story) {
        return Json (new {
            Result = story,
            myNewProjectid = projectid,
            myNewSummary = story.Summary + ". " + "Bla bla",
            myNewSize = story.Size + 20
        });
    }
    

    哪里 Story 我宣布的班级如下:

    public class Story {
        public string Summary { get; set; }
        public int Size { get; set; }
    }
    

    我像你贴的那样插入了路线并添加了以下内容 jQuery Index 视图 Home 控制器:

    jQuery(document).ready(function () {
        var myStory = { Summary: 'Test description', Size: 8 };
        $.ajax({
            url: '/Project/1/AddStory',
            data: { Summary: myStory.Summary, Size: myStory.Size },
            dataType: 'json',
            success: function (data, textStatus, xhr) {
                alert('myNewSummary="' + data.myNewSummary +
                      '", Result.Summary="' + data.Result.Summary +
                      '", Result.Size=' + data.Result.Size);
            },
            error: function (xhr, textStatus, errorThrown) {
                alert("error");
            },
            type: 'POST'
        });
    });
    

    代码可以正常工作,并生成包含文本的消息框 myNewSummary="Test description. Bla bla", Result.Summary="Test description", Result.Size=8

    traditional: true 如果您在发布更复杂的数据结构时遇到问题。当前测试不需要使用 .

    为了便于您将代码与我的工作示例进行比较,我将完整的VisualStudio2010项目放在下面 http://www.ok-soft-gmbh.com/ForStackOverflow/MvcApplicationJson.zip . 我希望这能帮助您快速找到代码中的错误并修复它。

        3
  •  0
  •   Stefanvds    14 年前

    我建议你用 $.post 代替

                var jsonbox = { Summary: myStory.Summary, Size: myStory.Size }
                $.post("/Project/1/AddStory", jsonbox, function doneit(data) {
                    if (data.succes == true) {
                        //do something like return a message 'saved, all ok'
                    } else {
                        /give an error.
                    }
                }, "json");
    

    我总是用这种行动方式

        [HttpPost]
        public ActionResult SomeAction(int id, FormCollection collection) {
            try {
               //some code
            } catch (Exception e) {
                return Json(new { succes = false, error = "An error occured. Details: " + e.Message });
            }
    
            return Json(new { succes = true });
        }
    

    $邮政 如果您不需要任何花哨的东西,只需要一个post、一个要发送的变量和一个要在得到结果时执行的函数,那么这个方法就很有用。

        4
  •  0
  •   Phil.Wheeler    14 年前

    啊。PEBKAC问题。

    原来问题是因为我以前在一组 <form>

    抱歉浪费大家的时间。有一些非常有用的建议和许多实用的想法来解决我的问题。