4

I need to get string array or list with ajax and Action, this is my Implementation:

This is my html Dom of view of Index action in AccessMenuController:

<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>

My Controller:

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);

   }
  }
}

and the script:

$(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');

}

And the problem is with all change of dropdown just Onfail function run and alert me "in OnFailRoleChangeHandler", also I check the RoleDropDownChanged Action with breakpoint and that never run, where is the problem?

UPDATE

when I load the page by chrome there is an error in console window: http://MyProject/GlobalAccess/AccessMenu/@Url.Action(%22RoleDropDownChanged%22) 404 (Not Found) jquery-1.7.1.js:8102

Saeid
  • 13,224
  • 32
  • 107
  • 173
  • When you debug, does your server method throws exception? Have you tried debugging javascript code? – Kosta Mar 29 '12 at 08:35
  • if you have this `@Url.Action(%22RoleDropDownChanged%22)` than your script is not parsed by the Razor Engine. If you can you could put the script inside a razor view and not in a seperate .js-file. – Silvermind Mar 29 '12 at 08:42
  • If your script resides in a .js file then this is not going to work. Where is your script declared? –  Mar 29 '12 at 08:53

3 Answers3

7

Remove this setting:

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

You are not sending any JSON to the server.

If you want to keep this setting then make sure that you are sending a valid JSON to your server:

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

So:

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

should work (at least it does for me) with the following action:

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

UPDATE:

According to your comments it looks like you are trying to use server side helpers in a separate javascript which is not possible. Here's what I would suggest you. Start by providing the url when generating your dropdown:

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

and then in your separate javascript file:

$(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');
            }
        });        
    });    
});

and then of course you could replace the hardcoded roleId with the currently selected value:

data: { 'roleId': $(this).val() }
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • I try both of your suggestions, there is a same problem. – Saeid Mar 29 '12 at 08:21
  • Try removing `processData: false` as well. Also do you see any errors in your javascript debugger? What's the exact server response to the AJAX request? – Darin Dimitrov Mar 29 '12 at 08:24
  • 1
    Sorry, I am unable to reproduce your problem. I have tested the code I showed and it worked fine for me. What does the server respond to the AJAX request? Look at your js debugging tool. – Darin Dimitrov Mar 29 '12 at 08:29
  • Thank you for answer, when I load the page by chrome there is an error in console window: `http://MyProject/GlobalAccess/AccessMenu/@Url.Action(%22RoleDropDownChanged%22) 404 (Not Found)` – Saeid Mar 29 '12 at 08:36
  • Oh, are you trying to use server side helpers such as `@Url.Action` in a separate javascript file? That's not gonna work. You will have to define the url inside your template so that you have access to url helpers and then you could use the variable in your separate javascript file. – Darin Dimitrov Mar 29 '12 at 08:36
  • As you said, yes i use it in a separate javascript file, but I couldn't understand to how define url inside of View and how use it in script? – Saeid Mar 29 '12 at 08:41
  • @Saeid, I have updated my answer to illustrate how you could achieve that. – Darin Dimitrov Mar 29 '12 at 10:00
2

Move your $(document).ready function to your View like this:

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

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

Then in your JS file add url parameter to your function and change ajax call:

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;
}

This should work as you expected.

Kosta
  • 1,817
  • 1
  • 16
  • 21
1

If your script resides in a .JS file then this is not going to work as it'll be treated as plain text. You can either move entire script to the view or you can re-factor script so that majority of the script remains in the .JS and you then pass relevant values from the view.