Breeze EntityQuery.from() withParameters POST to API not working - post

I have this peace of code :
function getSopMatches(data) {
return EntityQuery.from('GetSopMatches')
.withParameters({
$method: 'POST',
$encoding: 'JSON',
$data: data
})
.using(manager).execute()
.then(success)
.catch(_queryFailed);
function success(response) {
return response.results;
}
}
and it is called through this :
playerService.getSopMatches({ playerId: vm.player.id, competitionId: career.competitionId, seasonId: career.seasonId, teamId: career.teamId }).then(function (results) { //do something with it });
In my MVC controller (BreezeController) the method is like :
[HttpPost]
public IQueryable<object> GetSopMatches(SopMatch sop)
{
//this method is not called, I get a 405 Method not Allowed
}
Somehow, the actual call is a GET, instead of a POST and therefore I get the 405 Method not Allowed error message.
I have other peaces of code in the same project (client side javascript/breeze calls and server side mvc controller methods) that do work.
Does anybody knows what I'm doing wrong, or why it is changed to a GET method ?

After a day of trying and failing, I found a solution.
It appeared that in the angular controller I was injecting breeze, and that was causing the issue. When breeze is injected into the controller or service, it messes up the URL of the POST and therefore you receive a 405 (because the URL is changed).

Related

Calling controller method with a get type not working in ASP.NET MVC

I have a java script function that calling a controller method using Ajax, this call should get me the user profile page, I have a controller for this purpose. When I run the program and fire the java script function it's trigger the controller and every thing is good but when the debugging has ended no changes happens and the view doesn't present in the screen.
I tracked the call and every thing is working fine, passing parameter and reaching the method in the controller.
Note: the view which has the JS call related to a different controller.
View contain java script call:
<td onclick="ViewProfile('#item.CustomerId')"></td>
Java script file
function ViewProfile(id) {
console.log("sucsses");
$.ajax({
type:"GET",
url: "/ViewUserProfile/Index",
data: { "userId": id }
});
};
Controller: ViewUserProfileController
public ActionResult Index(string userId)
{
var ProfileInformation = new UserProfileVM
{
//some logic here
};
return View(ProfileInformation);
}
You are fetching ViewUserProfile in $.ajax but you are not using .done(function() { }) to process the result you receive from that call.
In your case I would simply suggest to use window.location.href in ViewUserProfile() as below.
function ViewProfile(id) {
window.location.href = "/ViewUserProfile/Index?userId=" + id;
}

web API calling not return response from controller in Aurelia JS?

I'm calling web API controller from Aurelia JS but i'm not getting any response from web API controller.
here is my code :
httpClient.fetch('/api/controllername', {
method: "POST",
headers: {
'content-type': 'application/json'
},
body: JSON.stringify(passvaluetocontroller)
})
.then(response => response.json())
.then(data => {
alert(data);
alert("success");
});
here is my controller code :
public HttpResponseMessage Post(passvaluetocontroller s)
{
return new HttpResponseMessage(System.Net.HttpStatusCode.Accepted);
}
so I am not getting any response and also it is showing error in console:
Uncaught (in promise)
SyntaxError:
Unexpected end of JSON input.
How can I do work when the request is successful?
The cause is very simple. You are not actually sending anything from your controller method:
public HttpResponseMessage Post(passvaluetocontroller s)
{
return new HttpResponseMessage(System.Net.HttpStatusCode.Accepted);
}
By passing the HttpResponseMessage method a System.Net.HttpStatusCode.Accepted, you are creating a response whose header contains the Accepted status code, but its body is empty. Therefore, there is nothing to deserialize. The response.json() will fail if the response is empty, that's why you are getting the error.
There are 2 possible solutions:
If you do not even intend to send any actual content back from the server, then simply don't call response.json() since there is nothing that you need in it. In that case, in your .then(...) method, simply check for response.ok. Doing this will tell you whether the response represents a successful operation - that is, the response status code is 2xx.
If you actually want to deserialize something, then simply send something from the server to deserialize. You can do that like this:
public object Post(passvaluetocontroller s)
{
return new { Test = "Test" };
}
Obviously, you can change the object return type to whatever you want and so can you return an object of your liking from within the action method.

Simple.Odata: how to call a function passing parameters in asp.net mvc request body

The title is a bit misleading, here is my situation: with postman, i can call the following url issuing a post and my function works:
http://localhost/odataservice/odata/Evaluations(9)/CreateEmptyForm
For it to work, i have to send the following in the body portion:
{
"#odata.type": "#Common.Data.Client",
"ClientId": 1
}
My issue arises when i try to replicate this inside my asp.net mvc application. There, im doing
public int CreateRvaForm(int clientId, int evalId, int type)
{
var key = Task.Run(async () =>
{
var data = await
client
.For<Evaluation>(Constants.DataService.PLURAL_EVALUATIONS)
.Key(evalId)
.Function( type==0 ? Constants.DataService.FUNCTION_CREATE_RVA_EMPTY : Constants.DataService.FUNCTION_CREATE_RVA_DUPLICATE)
.Set( new{ClientId=clientId} )
.ExecuteAsScalarAsync<int>();
return data;
}).GetAwaiter().GetResult();
return key;
}
Here, the variable client is the Simple.Odata.Client object.
The error i'm getting is something related to route not found; debug shows me that the library is trying to execute the url
http://localhost/odataservice/odata/Evaluations(9)/CreateEmptyForm(clientId=XX).
I dont have access to modify the odata service.
According to this text ("Executing functions and actions"), you should rather try using Action instead of Function since action is POST-based call while function translates to HTTP GET

405 method not allowed MVC 4 POST was working before

I have a really baffling issue with a customer site. We developed a C# MVC 4.0 application that's running in a subdirectory from another ASP.net application. We use a lot of Ajax calls from JQuery to controllers. Recently there's been an issue where a particular method on a controller has started returning "405 method not allowed" when doing a POST. This method is no different from any of the numerous other Ajax methods which are fine.
Edited to provide code:
Here's the offending function:
JavaScript:
function populateCitiesLike(cityTerm, fnInitialCityNames) {
var serviceBase = 'ProjectCities/';
var cityData = { term: cityTerm };
$.ajax({
type: "POST",
data: JSON.stringify(cityData),
url: serviceBase + "GetCitiesThatStartWith/",
contentType: "application/json",
success: function (result) {
$("#cityCheckboxes").empty();
if (result.length === 0) {
return;
}
addCityCheckboxes(result);
if (fnInitialCityNames != null)
fnInitialCityNames();
},
error: function () {
alert("We have an error");
}
});
}
c# controller :
[AjaxOnly,HttpPost]
public ActionResult GetCitiesThatStartWith(string term)
{
List<string> dbCities = null;
List<Cities> cityList = new List<Cities>();
dbCities = _reposProject.GetCitiesThatStartWith(term);
cityList = GetJsonFormatForCityList(dbCities);
// return Json(result);
return Json(cityList, JsonRequestBehavior.AllowGet);
}
I copied the entire web application and created a new subdirectory just to see what would happen. So for example the current application is running under main\A directory and now the cloned application is running under main\B. the method GetCitiesThatStartWith running under main\A that returns a 405 but the same method under main\B works. However there is one specific method called GetCitiesFromRegion that is always failing on both. That particular method used to work.
I don't think it's a code issue because why would one work and the other not. Resetting IIS does not work either. I can add test methods to the controller and call them from a test Ajax page and sometimes they fail and sometimes not. Once they fail with that particular method name I can no longer make it work. It's almost as if IIS remembers that the method failed and is caching the error.
updated
After spending more time with it I have discovered 2 issues. One issue is that the controllers constructor was throwing an exception because it was not authenticated at that point. I have resolved that issue.
The other issue which is baffling is that I could not get GetCitiesThatStartWith to work and a few other methods. I renamed them by appending V2 to the end of the method name and now they work.
Why would renaming a method on a controller make it work? I suspect that once the method gets an error and it stops working then I have to rename the method. Something about throwing an exception in the controller can be fatal to your method name apparently.
I think this will help you:-
I have changed the method name to CitiesThatStartWith by default it will be mapped with Get request because you are using GetCitiesThatStartWith.
Controller code
[AjaxOnly,HttpPost]
public ActionResult CitiesThatStartWith(string term)
{
List<string> dbCities = null;
List<Cities> cityList = new List<Cities>();
dbCities = _reposProject.GetCitiesThatStartWith(term);
cityList = GetJsonFormatForCityList(dbCities);
// return Json(result);
return Json(cityList, JsonRequestBehavior.AllowGet);
}
Javascript code
function populateCitiesLike(cityTerm, fnInitialCityNames) {
var serviceBase = 'ProjectCities/';
var cityData = { term: cityTerm };
$.ajax({
type: "POST",
data: JSON.stringify(cityData),
url: serviceBase + "CitiesThatStartWith/",
contentType: "application/json",
success: function (result) {
$("#cityCheckboxes").empty();
if (result.length === 0) {
return;
}
addCityCheckboxes(result);
if (fnInitialCityNames != null)
fnInitialCityNames();
},
error: function () {
alert("We have an error");
}
});
}

ASP.NET MVC - Proper way to handle ajax actions with no return object

I have a controller action that does some work in the database and then exits when it's finished. This action is being called via jQuery's ajax function with the dataType set to 'json'.
If I set the return type of the action to void, everything will function just fine except Firefox will show an error in the console that says: "no element found".
It makes sense that Firefox would throw this error if it was expecting XML to come back. However, even when I change the dataType property of the ajax call to "text", I still receive the error. In order to get rid of the error with the return type void, I would have to set the Response's ContentType to "text/html". Or I could set the return type to JsonResult and return a new [empty] JsonResult object.
I'm sure there are several ways I can make this error go away, but I wanted to know the proper way to handle actions with no return values being called via ajax.
If it matters, I'm also using the async controller action pattern.
public void DoSomethingAsync(SomeJsonObjectForModelBinding model)
{
// do some database things
}
public void DoSomethingCompleted()
{
// nothing to do...
// what should my return type be?
// do I need to set the content type here?
}
I know this doesn't exactly answer your question, but I would argue that you should always have a return value coming back from an AJAX or web service call. Even if only to tell you that the operation was successful, or otherwise return the error (message) back to you.
I often define a class like this:
public class JsonResultData
{
private bool _success = true;
public bool Success
{
get { return _success; }
set { _success = value; }
}
public object Value { get; set; }
public List<string> Errors { get; set; }
public JsonResultData()
{
this.Errors = new List<string>();
}
}
And then use it to return data or any other call meta data in the JsonResultData wrapper like so:
return new JsonResult {
Data = new JsonResultData { Value = returnValue, Success = true }
};
I can't comment because of my reputation but I still wanted to contribute to clear the confusion in Kon's answer.
In an application I caught all exceptions within an ActionMethod, set an HttpStatusCode and added an error message to the response. I extracted the message in the Ajax error function and showed it to the user.
Everything worked out fine until the application got put on the staging server, who had some kind of settings that did not allow a return message within an erroneous response. Instead some standard Html was transmitted resulting in a JS error processing the response.
In the end I had to rewrite all my exception handling returning my application errors as successful Ajax call (which it actually is) and then differ within the Ajax success function, just the way it should be.
You should not mix system-level and application-level feedback. You may not be able to control the system-level feedback the way your application needs.

Resources