Nerd dinner在调用Register动作方法的Ajax调用中出现错误

5

我是MVC的新手,正在使用MS MVC2实现Nerd Dinner MVC示例应用程序。 我现在进行到第10步,“启用Ajax接受RSVPs”。 我添加了新的RSVP控制器,并像下面这样添加了Register动作方法:

public class RSVPController : Controller
{
    DinnerRepository dinnerRepository = new DinnerRepository();

    //
    // AJAX: /Dinners/RSVPForEvent/1

    [Authorize, AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Register(int id) {

        Dinner dinner = dinnerRepository.GetDinner(id);

        if (!dinner.IsUserRegistered(User.Identity.Name)) {

            RSVP rsvp = new RSVP();
            rsvp.AttendeeName = User.Identity.Name;

            dinner.RSVPs.Add(rsvp);
            dinnerRepository.Save();
        }

        return Content("Thanks - we'll see you there!");
    }
}

我已经添加了Ajax脚本库的引用,并按照文章中的描述,在详细视图中添加了以下代码:
<div id="rsvpmsg">

<% if(Request.IsAuthenticated) { %>

    <% if(Model.IsUserRegistered(Context.User.Identity.Name)) { %>       

        <p>You are registred for this event!</p>

    <% } else { %>  

        <%= Ajax.ActionLink( "RSVP for this event",
                             "Register", "RSVP",
                             new { id=Model.DinnerID }, 
                             new AjaxOptions { UpdateTargetId="rsvpmsg"}) %>         
    <% } %>

<% } else { %>

    <a href="/Account/Logon">Logon</a> to RSVP for this event.

<% } %>

</div>

当我点击“RSVP参加此活动”的链接时,出现404错误,显示无法找到资源。
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable.  Please review the following URL and make sure that it is spelled correctly.

Requested URL: /NerdDinner/RSVP/Register/24

Version Information: Microsoft .NET Framework Version:2.0.50727.4200; ASP.NET Version:2.0.50727.4205

当我进入代码时,它正确地找到了Register操作方法。在尝试过后,我从Register方法的约束条件中删除了“AcceptVerbs(HttpVerbs.Post)”,然后它就可以工作了。但是它没有重新加载页面,而只是在一个新的空白页面上显示“谢谢 - 我们会在那里见到你”的消息。在详细页面中查看HTML,没有表单提交正在进行,所以我想知道Ajax代码是否需要更多东西来使调用成为Post?这个Nerd Dinner应用程序的这部分是否有已知问题?我认为该应用程序是使用MVC1编写的,而我正在使用MVC2 - 这会有区别吗?
TIA,
Ciaran
8个回答

2

PDF教程(与在线HTML版本相比)在脚本元素的HTML块中使用印刷体ANSI引号字符(0x94),而不是ASCII(0x22)。下面显示了所有引号字符替换后的正确块。

<script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="/Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>

Visual Studio会用警告绿色波浪线标记JavaScript源文件("文件未找到"),但不会标记类型属性,因此您只能在源文件中注意到并纠正问题。然而,type属性仍将格式不正确,这将导致脚本在浏览器中无法正确加载。

使用Chrome开发人员工具,我注意到脚本未列为详细HTML页面的资源。更正type属性的引号字符使注册操作按照教程文档正常工作,无需更改。


1

这是MVC3中使用的Details.cshtml。使用GET而不是POST进行重定向的问题是相似的。

<div id="rsvpmsg">
    @if (Request.IsAuthenticated)
    {
        if (Model.IsUserRegistered(Context.User.Identity.Name))
        {
        <p>
            You are registered for this event</p>
        }
        else
        {
        @Ajax.ActionLink("RSVP for this event",
        "Register",
        "RSVP",
        new { id = Model.DinnerID },
        new AjaxOptions { UpdateTargetId = "rsvpmsg", HttpMethod = "Post" })
        }
    }
    else
    {
        <p>
            <a href="/Account/Logon">Logon</a> to RSVP for this event.</p>
    }
</div>
@section JavaScript
{
    <script src="@Url.Content("~/Scripts/MicrosoftAjax.js")" type="text/javascript"></script>;
    <script src="@Url.Content("~/Scripts/MicrosoftMvcAjax.js")" type="text/javascript"></script>;
}

好的,之前我提到过我也遇到了同样的问题,这是因为MVC 3使用了不显眼的JavaScript。

要让它正常工作,你有两个解决方案,一是在你的webconfig文件中禁用不显眼的JavaScript:

  <appSettings>
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
  </appSettings> 

只需将其设置为false,在页面构建过程中,为Action链接生成的javascript将是正常的内联javascript,这样就可以正常工作,并在HTML中得到类似以下内容的结果:
<a onclick="Sys.Mvc.AsyncHyperlink.handleClick(this, new Sys.UI.DomEvent(event), 
{ insertionMode: Sys.Mvc.InsertionMode.replace, httpMethod: 'Post', updateTargetId: 'rsvpmsg' });" href="/RSVP/Register/13">RSVP for this event</a>

第二种解决方案更符合我的口味,而且同样简单。您只需在头部包含额外的JavaScript源文件:

<head>
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
    @RenderSection("JavaScript",required:false)
</head>

生成的JavaScript是不显眼的,并在HTML中呈现如下内容:

RSVP参加此活动

在这两种情况下,生成的功能是相同的,第二个解决方案更符合新的MVC 3的“精神”。


1
这部分代码解释了为什么你只收到了“见你了”消息。
 return Content("Thanks - we'll see you there!");

这就是返回的全部内容。

你一开始收到404错误的原因是使用了一个actionlink:

 Ajax.ActionLink(...

这将创建一个URL链接,是GET而不是POST,并且 AcceptVerbs(HttpVerbs.Post) 会强制没有匹配。你应该提交一个表单来进行Post操作:

using (Ajax.BeginForm("Controller", "Action", new AjaxOptions { UpdateTargetId = "f1" } )) { %>
 <div id="f1">
 <!-- form fields here -->
 <input type="submit" />
 </div>
<% } %>

嗨Tahbaza,返回的文本应该更新详细页面中的div-UpdateTargetId =“rsvpmsg”。根据Scott Gu在下面的教程中的代码和截图,“注册”链接被点击,div会用返回的文本进行更新。不确定他的示例在他没有进行Post时如何工作: http://nerddinnerbook.s3.amazonaws.com/Part10.htm - Ciarán Bruen

1

如果有人有同样的问题,我在使用 MVC 3 时遇到过这个问题,并且是因为我链接了 MS AJAX 库,而 MVC 3 实际上默认使用 jQuery,所以我只需要取消主页中的注释,问题就解决了。


1
作为调试与这个问题相关的额外评论,身为Java/JSF开发人员,我学到了一个重要的教训。
<script src="/Scripts/MicrosoftAjax.js" type="text/javascript" />

并且

<script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script>

这两个处理方式不同。第一个根本不起作用,而第二个可以正常工作。


0

我试图将代码转换为MVC3 / Razor,正如我通过这个例子工作一样。 我已经被卡在这个确切的问题上至少24个小时了......确切相同的症状。 我尝试了这个页面上我能够理解或认为相关的所有东西。

我在我的web.config中没有unobtrusive javascript提到,并考虑使用“false”值添加它,认为“true”可能是默认值。 但是,我认为这可能会弄乱其他东西(还有谁知道什么)。

我在wrox论坛上找到了以下小贴士。 如果我将以下一行代码添加到RSVPStatus.cshtml部分视图的第二行:

<script src="/Scripts/jquery.unobtrusive-ajax.min.js" type="text/javascript"></script>

一切都按照预期运作。我知道Zak提到了上面的那行代码(以及其他一堆指引我正确方向的东西),但我一直在使用部分视图,自从我开始折腾MVC以来就没有看到过head标签。我知道它可能在某个地方,但是微软编程的所有幻术和迷雾使得解剖变得更加困难,我可能会在某个时候走上Zak的路线。所以,+1给他。

无论如何,希望这能帮助某人节省一天的时间。


0
要使用 Ajax.ActionLink 进行 http post,您需要执行例如 new AjaxOptions { UpdateTargetId="rsvpmsg",HttpMethod="POST"}

嗨nos,我尝试了那个方法,但仍然得到相同的404错误。当我添加HttpMethod="POST"时,它生成了下面的html:<div id="rsvpmsg"> <a href="/NerdDinner/RSVP/Register/25" onclick="Sys.Mvc.AsyncHyperlink.handleClick( this, new Sys.UI.DomEvent(event), { insertionMode: Sys.Mvc.InsertionMode.replace, httpMethod: 'post', updateTargetId: 'rsvpmsg' });"> RSVP参加此活动</a> </div> - Ciarán Bruen

0

如果你在site.master中包含这两个,那就没问题了。

<script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="/Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script> 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接