Calling partial view through AJAX in Asp.net MVC 5 - ajax

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

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

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

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

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'

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

Related

How can i get a value from the controller to my gsp page using AJAX

I am new to AJAX and grails so any help is appreciated. on my GSP page, on button click I am trying to retrieve a variable from the controller:
$.ajax({
url:'${createLink(controller: 'store', action: 'getNum')}',
type: 'GET',
dataType: 'json',
data: {num: num}, // the num is defined before and access properly
error: function() {
alert("error");
},
success: function(data) {
alert(data);
}
});
this is my controller function:
def getNum(){
String num = params.num
Long locnum = num as Long
int result = storeService.getNum(locnum)
String json = JsonOutput.toJson([count: result])
return json
}
I am going into the error and getting an "error" alert. I was wondering how I could utilize AJAX to get the number I need for my GSP page?
Thank you.
I would modify your JavaScript code like so:
$.ajax({
url:'store/getNum',
method: 'POST'
data: {'num': num}, // the num is defined before and access properly
error: function() {
alert("error");
},
success: function(data) {
alert(data);
}
});
And then modify your Grails controller code like so:
def getNum() {
Long locnum = = params.long('num')
int result = storeService.getNum(locnum)
return render([count: result] as JSON) // you will need to import grails.converters.JSON
}
A tip for the future is to set a breakpoint in your Grails controller method and run the application in Debug mode to ensure that the controller method is being called. If it is not being called, click on the Network tab on your internet browser's Developer Tools and then press the button on your GSP page to inspect the HTTP request being made by the AJAX call.

Not found error for ajax in ASP.NET MVC release configuration

I am currently working on an ASP.NET MVC site and I am having trouble with ajax posts in my release build. The site has two database connections, one to a "dummy" server that allows me to test code without affecting the live server. So, I had to configure the site to point to the live server for the release configuration, and the dummy server for the debug configuration.
Everything other than the database connection is the same, but for some reason my ajax call works fine on the debug build but throws an error on the release build. I get an ERROR THROWN: Not found alert on the ajax failure, but it only fails in the release build.
My call to the controller method looks like this:
$.ajax({
type: "GET",
url: "#Url.Action("ReleasePlotFieldName", "TestRecord")" + '?fieldName=' + x + '&fileName=' + filename,
contentType: "application/json; charset=utf-8",
data: {},
dataType: "json",
success: function (data) {
alert("success");
for (var key in data) {
let b = {
name: data[key][0],
value: data[key][1],
line: data[key][2],
arc: data[key][3]
};
chartData.push(b);
}
PlotData();
//the parameter data contains the array returned from the json PlotFieldName function
},
error: function (xhr, textStatus, errorThrown) {
alert('STATUS: ' + textStatus + '\nERROR THROWN: ' + errorThrown);
}
and the controller method looks like this:
[HttpPost]
public JsonResult ReleasePlotFieldName(string fieldName, string fileName)
{
var spiData = (DataDecoder)Session["dataDecode"];
var selectedItem = fieldName;
spiData.DecodeData(selectedItem);
List<float[]> toPlot = spiData.returnPlotVector();
return new JsonResult()
{
Data = toPlot,
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
MaxJsonLength = int.MaxValue // Use this value to set your maximum size for all of your Requests
};
}
I have absolutely no clue why the release build is not executing as expected (as the debug build is doing). I welcome any and all suggestions.
Here is the network tab of the browser when the call is made
Your controller action is decorated with a [HttpPost] attribute but your jquery .ajax() request is a GET. Change one or the other depending on your use case (looks like GET could be more appropriate).

How do I request views from a layout using AJAX?

In my MVC application I don't want the layout page to reload everytime a view is selected. It would be great if the views could be loaded using ajax to keep things nice and fast and allow me to persist certain interface states that are wiped out when you move around.
My initial approach was to add some ajax to the _Layout.cshtml and then whent he view was requested pass that request to the controller method which will grab that page. All I ended up doing however was returning the WHOLE view again.
Here is the code I have so far, am I on the right tracks here or is this totally wrong?
Layout Ajax Script
<script>
$(function () {
var content = document.getElementById('content');
//When a user selects a link, pass the data attribute and
//use it to construct the url
$('#sidebar a').on("click", function () {
var page = $(this).data('page');
console.log("Data Attrib : " + page);
$.ajax({
type: 'GET',
url: '#Url.Content("~/Home/")' + page,
success: function (data) {
$('#content').html(data);
console.log("Success");
},
error: function (xhr, ajaxOptions, thrownError) {
console.log("Error: " + thrownError);
}
})
})
});
</script>
As I say, this sort of works, but it's not perfect as it returns the whole page into the content area including layout, ideally I just want the core view data.
you can create a Single Page Application that have 1 layout and in home controller and index action method create menu or user setting or another things
and now you can load other action with Ajax call with data-content html that does not have layout file and append that in container
when user click another menu clean older content and add new or you can create tab strip or window
Layout.cshtml
<script>
$(function () {
//When a user selects a link, pass the data attribute and
//use it to construct the url
$('#sidebar a').on("click", function () {
var page = $(this).data('page');
$.ajax({
type: 'POST',
url: '/Home/Pages',
data: { pageValue: page },
success: function (data) {
$('#content').html(data);
console.log("Success");
},
error: function (xhr, ajaxOptions, thrownError) {
console.log("Error: " + thrownError);
}
})
})
});
Controller
public class HomeController : Controller
{
[HttpPost]
public string Pages(string pageValue)
{
string result = //Whatever
return result;
}
}
Controller
public ActionResult SomeAction(String someparams)
{
//Make the model
SomeModel someModel = new SomeModel();
someModel.someparams = someparams;
return PartialView("SomePartialView", someModel);
}
In View
$.ajax({
url: "/Home/SomeAction",
type: "POST",
dataType : "html",
data: json,
contentType: 'application/json; charset=utf-8',
success: function(data){
$('#SomeDivID').html(data);
}
});

406 Error when returning JSON object – Unexpected content

A few colleagues and I have a problem whereby the response from an ajax call returns some unexpected content. Rather than getting a simple JSON object back with various properties, the value of result.responseText is the HTML markup of a generic 406 status error page, saying the MIME type is not accepted by the browser.
The call is made like so:
$.ajax({
url: '/promociones/cincogratis/canjear-codigo-promocional',
type: this.method,
data: $(this).serialize(),
success: function (result) {
$('.promotion_banner .loader').hide();
$('.promotion_banner').html(result);
},
error: function (result) {
var obj = result.responseText;
if (obj.isRedirect) {
document.location = obj.redirectUrl;
}
else {
$('.promotion_banner .loader').hide();
$(".error-wrapper").removeClass("hidden");
var generic_error = document.getElementById('generic_error').value;
$(".error-wrapper p").html(generic_error);
}
},
beforeSend: function() {
$('.promotion_banner .loader').show();
}
});
The controller response to the call is like so:
Response.StatusCode = (int)HttpStatusCode.NotAcceptable; // 406
return Json(new { errorMessage = LocalErrorMessages.Website_Promotions_FreeFiver_General_Problem, isRedirect = false } );
We would expect result.responseText to contain key values for errorMessage and isRedirect, but they’re not there.
It’s worth pointing out that this code is multi-tenanted, shared by the current application and another one, where it works absolutely fine.
We’ve tried:
- Configuring IIS to show detailed error responses rather than a custom page for more detail – gives us nothing extra towards solving the problem.
- Allowing all response content types to the call
- Changing the culture of our site (which is currently es-ES)
- Various web.config tweaks
Has anyone ever had this problem?
Simplify your request. Maybe something like:
$.ajax({
url: '/promociones/cincogratis/canjear-codigo-promocional',
type: 'GET',
data: {foo:'bar', one:'two'},
dataType: 'json',
success: function (result) {
console.dir(result);
},
error: function (xhr) {
console.dir(xhr)
}
});
And post the response from the server. This kind of error seems a request problem rather than server configuration issue

Express res.jsonp returns two callback names to Safari Extension AJAX call

I'm building an extension in Safari, using Express.js on the back end. I make an AJAX call to the server, and the server responds with what appears to be a double callback name:
jQuery191026131771644577384_1364321159940 && jQuery191026131771644577384_1364321159940([
{
"foo": "bar"
}
]);
Here's the AJAX:
$.ajax({
type : "GET",
data : { 'something': 'something more'},
url : "http://localhost:3001/api/login/?callback=?",
dataType: 'jsonp',
success: function(data, text){
console.log(data)
},
error: function (request, status, error) {
console.log("ERROR: " + status + error );
}
});
...and here's the Express.js:
app.get('/api/login', function(req, res){
res.jsonp([{'foo':'bar'}]);
});
The browser is reporting a parse error, likely because of the double callback stamp above.
Clues?
It's not a double callback, it's the same as doing func && func(), it just makes sure that the function exists before calling it, so avoid throwing an exception.
Hector has it right in the comments: Try removing callback=? from the URL

Resources