在ASP.NET MVC 3中使用Ajax和JsonResult

4

我需要通过ajax和Action获取字符串数组或列表,以下是我的实现:

这是AccessMenuController中Index动作的视图的HTML DOM:

<div class="RoleAccess">
   <select name="RoleDropDown">
    <option value="0">Select Role</option>
    <option value="61AD3FD9-C080-4BB1-8012-2A25309B0AAF">AdminRole</option>
    <option value="8A330699-57E1-4FDB-8C8E-99FFDE299AC5">Role2</option>
    <option value="004E39C2-4FFC-4353-A06E-30AC887619EF">Role3</option>
   </select>
</div>

我的控制器:

namespace MyProject.Areas.GlobalAccess.Controllers {

public class AccessMenuController : Controller {

    public ActionResult Index() { return View();}

    [HttpPost]
    public JsonResult RoleDropDownChanged(string roleId) {

     Guid RoleId = new Guid(roleId);

    //Some implement

    List<string> actions = new List<string>();
    for(int i = 0; i <= 10; i++) 
            actions.Add(i.ToString());

return Json(actions.ToArray(), JsonRequestBehavior.AllowGet);

   }
  }
}

还有脚本:

$(document).ready(function () {

//Handle Checks of Actions by RoleName Changed
$('div.RoleAccess select').change(function () {
    RoleChangeHandler();
});

function RoleChangeHandler() {

    $.ajax({
        url: '@Url.Action("RoleDropDownChanged")',
        type: 'POST',
        data: { 'roleId': '61AD3FD9-C080-4BB1-8012-2A25309B0AAF' },
        dataType: 'json',
        processData: false,
        contentType: 'application/json; charset=utf-8',
        success: function (data) { SuccessRoleChangeHandler(data); },
        error: OnFailRoleChangeHandler
    });
    return false;
}


function SuccessRoleChangeHandler(data) {

    alert("in success role change");

}

function OnFailRoleChangeHandler(result) {
    alert('in OnFailRoleChangeHandler');

}

问题在于每次下拉菜单更改时,都会运行OnFail函数并弹出“在OnFailRoleChangeHandler中”的警告,我还检查了具有断点的RoleDropDownChanged操作,但从未运行,问题在哪里?
更新:
当我用Chrome加载页面时,控制台窗口会出现错误: http://MyProject/GlobalAccess/AccessMenu/@Url.Action(%22RoleDropDownChanged%22) 404 (未找到) jquery-1.7.1.js:8102

当你调试时,你的服务器方法是否会抛出异常?你尝试过调试JavaScript代码吗? - Kosta
如果你有这个 @Url.Action(%22RoleDropDownChanged%22),那么你的脚本没有被 Razor 引擎解析。如果可以的话,你可以把脚本放在 Razor 视图中而不是单独的 .js 文件中。 - Silvermind
如果你的脚本存储在.js文件中,那么这是行不通的。你的脚本声明在哪里? - user338195
3个回答

7

删除此设置:

contentType: 'application/json; charset=utf-8',

您没有向服务器发送任何JSON数据。

如果您想保持此设置,请确保向服务器发送有效的JSON数据:

data: JSON.stringify({ 'roleId': '61AD3FD9-C080-4BB1-8012-2A25309B0AAF' })

所以:
$.ajax({
    url: '@Url.Action("RoleDropDownChanged")',
    type: 'POST',
    data: { 'roleId': '61AD3FD9-C080-4BB1-8012-2A25309B0AAF' },
    success: SuccessRoleChangeHandler,
    error: OnFailRoleChangeHandler
});

这个应该可以工作(至少对我而言),使用以下操作:

[HttpPost]
public ActionResult RoleDropDownChanged(Guid roleId) 
{
    var actions = Enumerable.Range(1, 10).Select(x => x.ToString()).ToList();
    return Json(actions);
}

更新:

根据你们的评论,看起来你们正在尝试在单独的javascript中使用服务器端帮助程序,这是不可能的。这是我建议你做的:首先在生成下拉列表时提供URL:

<div class="RoleAccess">
    @Html.DropDownListFor(
        x => x.RoleDropDown, 
        Model.Roles, 
        "-- Select role --",
        new { 
            data_url = Url.Action("RoleDropDownChanged") 
        }
   )
</div>

然后在您单独的JavaScript文件中:

$(document).ready(function() {
    $('div.RoleAccess select').change(function () {
        var url = $(this).data('url');
        $.ajax({
            url: url,
            type: 'POST',
            data: { 'roleId': '61AD3FD9-C080-4BB1-8012-2A25309B0AAF' },
            success: function(result) {
                alert('success');
            },
            error: function() {
                alert('error');
            }
        });        
    });    
});

当然,你可以用当前选择的值替换硬编码的roleId:

data: { 'roleId': $(this).val() }

我尝试了你提出的两个建议,但问题依旧存在。 - Saeid
尝试将 processData: false 也移除掉。另外,您在 JavaScript 调试器中是否看到任何错误?AJAX 请求的确切服务器响应是什么? - Darin Dimitrov
1
抱歉,我无法重现您的问题。我已经测试了我展示的代码,并且它对我来说运行良好。服务器对AJAX请求做出了什么响应?查看您的js调试工具。 - Darin Dimitrov
哦,你想在单独的JavaScript文件中使用服务器端帮助程序,例如@Url.Action吗?那是行不通的。您必须在模板内定义URL,以便可以访问URL帮助程序,然后您可以在单独的JavaScript文件中使用该变量。 - Darin Dimitrov
@Saeid,我已经更新了我的答案,以说明您如何实现这一点。 - Darin Dimitrov
显示剩余2条评论

2

把你的$(document).ready函数移动到视图中,像这样:

<script type="text/javascript">
$(document).ready(function () {

    //Handle Checks of Actions by RoleName Changed
    $('div.RoleAccess select').change(function () {
        RoleChangeHandler('@Url.Action("RoleDropDownChanged")');
   });
});
</script>

然后在您的JS文件中,将url参数添加到函数中并更改ajax调用:

function RoleChangeHandler(pageUrl) {

    $.ajax({
        url: pageUrl,
        type: 'POST',
        data: { 'roleId': '61AD3FD9-C080-4BB1-8012-2A25309B0AAF' },
        dataType: 'json',
        processData: false,
        contentType: 'application/json; charset=utf-8',
        success: function (data) { SuccessRoleChangeHandler(data); },
        error: OnFailRoleChangeHandler
    });
    return false;
}

这应该可以按照你的预期工作。

1
如果您的脚本位于 .JS 文件中,则此方法将无法正常工作,因为它将被视为纯文本。您可以将整个脚本移动到视图中,或者重新设计脚本,使大部分脚本保留在 .JS 文件中,并从视图传递相关值。

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