0

I needed to implement some business logic on the server side during the process of fetching entities to ensure that the user had permission to the item being retrieved.

To accomplish this, my client-side breeze query code changed from something like:

var query = breeze.EntityQuery
    .from(theUrl)
    .expand("RelatedEntity")
    .where(breeze.Predicate.create("id", "==", id));

to:

var query = breeze.EntityQuery
    .from(theUrl)
    .withParameters({ id: id })
    .expand("RelatedEntity");

On the server side, my controller action changed from:

[HttpGet]
[BreezeQueryable]
public IQueryable<MyEntity> MyEntities()
{
    return _uow.MyEntityRepo.All();
}

to something like:

[HttpGet]
[BreezeQueryable]
public IHttpActionResult FindById(int id)
{
    var userId = HttpContext.Current.User.Identity.GetUserId();
    var hasPermission = CheckPermission(id, userId); // some implementation ...

    if (hasPermission) {
        var myEntity = _uow.MyEntityRepo.GetById(id);
        return Ok(myEntity)
    } else {
        return NotFound();
    }
}

I can see the query come across the wire with the filter:

http://localhost:42789/breeze/MyEntity/FindById?$expand=RelatedEntity&id=1002

However, RelatedEntity is undefined. When using the EntityQuery, but not withParameters, the related entity expands fine and is available in the result set.

Thank you

George Durzi
  • 1,632
  • 1
  • 19
  • 31

1 Answers1

1

The withParameters call needs to refer to an IQueryable endpoint and you also need that endpoint to be named on the client. Further if you want to call expand then the queryable that you return must support an EF 'Include' operation. So for example if you have a server side method like this

[HttpGet]
public IQueryable<Customer> CustomersStartingWith(string companyName) {
  return ContextProvider.Context.Customers.Where(c => c.CompanyName.StartsWith(companyName));
}

Then you could query it with a client side query like this:

var q = EntityQuery.from("CustomersStartingWith")
        .withParameters({ companyName: "C" })
        .expand("orders");

Note the 'CustomersStartingWith' as the argument to the 'from' clause.

Jay Traband
  • 17,053
  • 1
  • 23
  • 44
  • Thanks, Jay. That works for me, but the only drawback I see is that I can't use HttpActionResult to properly communicate a 404 or 401 back to the client. I can work around that though. – George Durzi Jun 11 '14 at 02:09
  • 1
    Actually you can return a 401 or 404 by throwing a HttpResponseException inside of your server method: [HttpGet] public IQueryable CustomersWithHttpError() { var responseMsg = new HttpResponseMessage(HttpStatusCode.NotFound); responseMsg.Content = new StringContent("Custom error message"); responseMsg.ReasonPhrase = "Custom Reason"; throw new HttpResponseException(responseMsg); } – Jay Traband Jun 11 '14 at 16:16