get count from oData enabled web api Get function - odata

i have an oData enabled classic REST web api controller with a Get function like
[EnableQuery()]
public IQueryable<StoreCommand> Get()
{
return _storeCommandService.GetAllStoreCommands().AsQueryable();
}
i need to understand how i can make a call to get only the count of records using some url
i tried
http://localhost:9910/api/storeCommandsrest?$count
but i get
Message: "The query parameter '$count' is not supported."
please note that i am using MongoDb that is returning IQueryable of collection.

If you want to get only the count, try
http://localhost:9910/api/storeCommandsrest/$count

Related

EnableQuery always perform SingleOrDefault on IEnumerable<T> result

I have the following Api Endpoint:
[EnableQuery()]
[Route("rankingreport", Name = "GetRankingReport")]
public IQueryable<RefereeRankingReport> GetRankingReport()
{
var data = (from r in _context.RefereeRankings
join m in _context.Referees on r.RefereeId equals m.ID
join mg in _context.RefereeGradings on r.GradingId equals mg.ID
select new RefereeRankingReport
{
...
})
.AsNoTracking();
return data;
}
I was able to query this endpoint in ASP.NET MVC as such http://url.base/api/referee/rankingreport and got all the results. If needed I then add the odata filters etc on the url to filter the data. http://url.base/api/referee/rankingreport?$filter=GradingId eq 5&$orderby=GradingId,Ranking
However I'm busy upgrading to .net core 3.1 and seeing an exception where it will always return the result as SingleOrDetault. I don't know why it wants to do this as the method is clearly returning IQueryable.
In the startup I have declared this:
services.AddOData();
...
app.UseMvc(routeBuilder =>
{
routeBuilder.EnableDependencyInjection();
routeBuilder.Count().Filter().OrderBy().Expand().Select().MaxTop(null);
});
I don't have the odata route defined, because I don't need or want it.
What am I missing to get this to return the resulting list or records as expected?
In .NET Core 3.1 - Endpoint routing isn't supported (yet), you have to have the OData route there for your functionality to work.

sending multiple objects to back-end post method using angular 4 http services

Hi I am trying to send two objects using http post method to backend
my environment is angular4, typescirpt, asp.net MVC 5
but it is throwing 500 internal server error
the same approach if I am passing single object to the backend my backend method is getting called
here is the code with passing single object
clientSidePostCall(Results:any,Details:any):Observable<any>{
return this._http.post(Global.ENDPOINT +'BackendMethod/',Results)
.map((response: Response) => <any>response.json())
.catch((err:any) => { throw err; });
}
the above code is working fine if I send Results object to BackendMethod if it is expecting single parameter
The same code is not working if I send multiple objects to backendMethod when it is expecting two objcets.
clientSidePostCall(Results:any,Details:any):Observable<any>{
return this._http.post(Global.ENDPOINT +'BackendMethod/',Results,Details)
.map((response: Response) => <any>response.json())
.catch((err:any) => { throw err; });
}
The above code is not working and throwing 500 internal server error
here is my backend method signature
[HttpPost]
public HttpResponseMessage BackendMethod([FromBody] resultsType Results, [FromBody] detailsType Details)
please help me with this
and I am having another doubt that can we pass object in http.get in angular 4 and typescript
In your angular code make the Results, and Details be properties of a larger object... So send this object:
const myPostBody = { resultsType: Results, detailsType: Details }
return this._http.post(Global.ENDPOINT +'BackendMethod', myPostBody)
.map((response: Response) => <any>response.json())
.catch((err:any) => { throw err; });
}
Also make sure that your API class type Results actually matches the Class Results that you're sending it
I don't know how asp.net works but the third argument of HttpClient.post is not for another post body. In fact a post request cannot have two bodies. If your backend expects an array, do:
this._http.post(url, [Results, Details])
Wrapping up child entities in a parent entity is required for HTTP Post. The child entity would usually be a business entity.
On the receiving service end, you will use the entity names as properties to receive the individual items. All this assume your entity itself is serializable.

Load service in functional test (Symfony4)

I'm trying to test a controller made with Symfony 4 with PHPUnit.
I'm using https://github.com/lexik/LexikJWTAuthenticationBundle to manage JWT.
This controllers should return a 200 if a valid JWT is given, a 401/403 otherwise.
The first part with the 401 response is easy: I just don't send any token
<?php
namespace App\Tests\Controller;
Class GraphQLControllerTest extends \Symfony\Bundle\FrameworkBundle\Test\WebTestCase {
function test_token(){
$client = static::createClient();
$client->request('GET', '/graphql');
// Check 401 response
$response = $client->getResponse();
$this->assertSame(401, $response->getStatusCode());
$this->assertSame('"Not authenticated"', $response->getContent());
}
}
The next part is tricky: how do I get my JWT encoder service in my test_token method in order to generate some tokens to test 200 and 403 responses?
If I were in a controller I could use Symfony autowiring or make a public alias of lexik_jwt_authentication.encoder to be used like this:
$this->container->get('lexik_jwt_authentication.encoder')
Loading manually the service in my test like this bellow seems inefficient as some of the arguments of the constructor are some objects, and some arguments of their own constructor are objects, and ...
new Lexik\Bundle\JWTAuthenticationBundle\Encoder\DefaultEncoder([some objects here])
This is what is nice with autowiring: you just get the service you want ready to be used.
=> What's the best way to get this service in my test?
Thanks!
It's now possible with Symfony 4.1 to load a private service within a test using the KernelTestCase

Using OData with breeze - query not executed

i am trying to query webapi asp.net odata controller using breeze
in my query
function getIncidentsInternal() {
var query = breeze.EntityQuery
.from("Customers");
//var serverAddress = "http://localhost:53809/odata/";
var serverAddress = "/odata";
var manager = new breeze.EntityManager(serverAddress);
return manager.executeQuery(query)
.then(getSucceededInternal); // caller to handle failure
after the metadata request there is no actual request to get the items
i see one error of
OPTIONS http://localhost:53809/odata/$metadata 405 (Method Not Allowed)
after this request there is a GEt request with the metadata which pass but no query
If you got a 405, I bet you have issues with CORS. Does you OData service support CORS? Also, looks like you need to change breeze to use OData instead of web api. you can do that like so..
breeze.config.initializeAdapterInstances({ dataService: "OData" });

Breeze Web API Controller Method Name Convention

In Official Docs about breeze and the Web API controller, we see some kind of naming convention for the method names on web Api controller. For example, for the Todo entity type, there is a Todos() method.
Suppose I have an entityType "Customer". Then I create a method on apiController:
[HttpGet]
public IQueryable<Customer> GetCustomers() { ... }
In my client javascript app, I run EntityQueries like that:
//api method: GetCustomers
//type name: Customer
var query = EntityQuery.from("GetCustomers");
manager.execute(query); //works
manager.fetchEntityByKey("Customer", 53) //doesn't works!
It fails, I receive the folowwing error:
No HTTP resource was found that matches the request URI
'http://localhost:4119/api/SomeController/Customers?$filter=Id eq 53'
So, Am I forced to rename my GetCustomers method to Customers() or Am I missing something ?

Resources