Arianit
Arianit

Reputation: 553

Calling partial view through AJAX in Asp.net MVC 5

I'm using the following code to call a partial view:

$('#btnGetMilestones').click(function () {
$.ajax({
    url: "GetMilestones",
    type: "get",
    success: function (result) {
        $('#milestonesContainer').html(result);
    },
    error: function (xhr, status, error) {
        var msg = "Response failed with status: " + status + "</br>"
        + " Error: " + error;
        $('#milestonesContainer').html(msg);
    },
    complete: function (xhr, status) {
        var doneMsg = "Operation complete with status: " + status;
        alert(doneMsg);
    }
});

});

for this ActionResult:

public PartialViewResult GetMilestones()
    {
        return PartialView("_GetMilestones");
    }

The partial view has the milestones for a project (milestones and project are models). When I call the partial view like this:

<div id="milestonesContainer">
    @Html.Partial("_GetMilestones")
</div>

it works fine, it gets all the milestones for the project. But when I try to call the partial view via ajax, the error gets called: Response failed with status: error

Error: Bad Request

I'm in the details view of a projects so the url is like this http://localhost:55623/Projects/Details/2002

I'm new in ajax and javascript, so please if possible, explain me like you do to a beginner.

UPDATE:

After getting some answer and playing around to find a solution, I understand why the error appears. I'm inside the details view, so the url is like this: http://localhost:55623/Projects/Details/2002 see there is an ID parameter. When I make the ajax call, the url is like this http://localhost:55623/Projects/Details without the id parameter. So in return I get a 400 error code

Upvotes: 1

Views: 5337

Answers (5)

Arianit
Arianit

Reputation: 553

Thanks to all for answering. I got an answer for my problem, maybe it's kinda not expected. Her it is: change the ajax method:

$('#btnGetMilestones').click(function () { 
        $.ajax({
            url: '/Projects/GetMilestones/' + "?id=" + window.location.href.split('/').pop(),                
            type: "GET",
            success: function (data) {
                $('#milestonesContainer').html(data);
            },
            error: function (xhr, status, error) {
                var msg = "Response failed with status: " + status + "</br>"
                + " Error: " + error;
                $('#milestonesContainer').html(msg);
            },
            complete: function (xhr, status) {
                var doneMsg = "Operation complete with status: " + status;
                alert(doneMsg);
            }
        });
    });

and the action result:

public ActionResult GetMilestones(int? id)
    {             
        var forProject = db.Projects.Where(x => x.ID == id).SingleOrDefault();
        return PartialView("_GetMilestones",forProject);
    }

Or same action result but the ajax request slightly dirrent:

$('#btnGetMilestones').click(function () { 
  var id;
   id = @Model.ID;

    $.ajax({
        url: '/Projects/GetMilestones',
        type: "GET",
        data: "id="+id,
        success: function (data) {
            $('#milestonesContainer').html(data);
        },
        error: function (xhr, status, error) {
            var msg = "Response failed with status: " + status + "</br>"
            + " Error: " + error;
            $('#milestonesContainer').html(msg);
        },
        complete: function (xhr, status) {
            var doneMsg = "Operation complete with status: " + status;
            alert(doneMsg);
        }
    });
});

Upvotes: 1

ermir
ermir

Reputation: 877

You need to change first url to something that match the route:

 '/<Controller>/GetMilestones/'

switch from PartialViewResult to ActionResult

go for ajax like:

url: "GetMilestones",
type: "get",
contentType: 'application/html; charset=utf-8',
dataType : 'html'

Upvotes: 2

Shyju
Shyju

Reputation: 218732

You should consider taking advantage of the helper methods like Url.Action to generate the correct relative path to the action method you want to call via ajax. If you are js code is inside the view, you can simply call the method like

url: "@Url.Action("GetMilestones","Project")",

If it is in an external js file, you can still use the helper method to generate the path and set it to a variable which your external js file. Make sure to do javascript namespacing when you do so to avoid possible overwriting of js global variables.

so in your view/layout you can do this

<script>
    var myApp = myApp || {};  
    myApp.Urls = myApp.Urls || {};     
    myApp.Urls.mileStoneUrl= '@Url.Action("GetMilestones","Project")';
</script>
<script src="~/Scripts/PageSpecificExternalJsFile.js"></script>

And in your PageSpecificExternalJsFile.js file, you can read it like

$(function(){
   $('#btnGetMilestones').click(function () {
      $.ajax({
           url: myApp.Urls.mileStoneUrl,
           //Your existing code goes here

           })
     });
});

Upvotes: 2

Ceshion
Ceshion

Reputation: 706

Instead of url: "GetMilestones", try using url: "@Url.Action("GetMilestones")" which will render the actual relative path of the action i.e. /{Controller}/GetMilestones.

Also ensure that you are referring to the correct file name in your controller, as in your view you refer to "_GetMilestone" and you say that works, but in your controller you reference "_GetMilestones" which would not resolve if your filename is indeed "_GetMilestone"

If you're getting a 500 error, that means it's likely that you're hitting the action and an exception is occurring before or while it renders the partial view. Try navigating directly to the partial view's action in your browser by typing localhost:port/Projects/GetMilestones and see if an exception page appears. Make sure you do something like this in the Configure method of your Startup class:

public void Configure (IApplicationBuilder app) 
{    
    app.UseDeveloperExceptionPage();
}

Upvotes: 2

Gavin
Gavin

Reputation: 4515

To build on my comment:

Sorry, I was being ambiguous with the term url. Here's what I meant:

Unless your currentl url in the browser is http://<hostname>/<Controller that contains GetMilestones>, your AJAX url is incorrect. The AJAX url needs to be /<Controller>/GetMilestones.

The beginning / takes you to the root of the project, then the rest is taken care of by your route config (typically /Controller/Method/Id). That's why the AJAX url usually needs to be /Controller/Method. However, if you are at the Index view, your url is typically http://<hostname>/Controller. So, if this is the case and your AJAX url is just Method, it will take you to http://<hostname>/Controller/Method since you didn't prepend your AJAX url with a /.

Upvotes: 2

Related Questions