How to properly send action parameter along with q

2019-02-08 11:08发布

问题:

Currently I am calling all data queries as showed on BreezeJs docs / examples:

getEntityList = function (predicate) {
  var query = new entityModel.EntityQuery().from("EntityList");
  if (predicate)
    query = query.where(predicate);
  return manager.executeQuery(query);
}

But I want to pass additional parameter to controller action before any queryable result is returned:

[AcceptVerbs("GET")]
public IQueryable<Entity> EntityList(string actionParam) {
  //here goes logic that depends on actionParam
  //and returns IQueryable<Entity>
}

As we know from documentation:

Breeze converts the query into an OData query string such as this one:

?$filter=IsArchived%20eq%20false&$orderby=CreatedAt

This is where the problem starts. How should I build query to pass param to controller action?

getEntityList = function (predicate, actionParam) {
  var query = new entityModel.EntityQuery().from("EntityList");
  if (predicate)
    query = query.where(predicate);
  if(actionParam)
    // ???
  return manager.executeQuery(query);
}

I already tried setting route to:

routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{actionParam}",
            defaults: new { query = RouteParameter.Optional }
        );

and sending actionParam by applying it in a from section,

var query = new entityModel.EntityQuery()
  .from("EntityList/" + encodeURIComponent(actionParam));

but encoding fails on some special chars and bad request is being thrown.

How can I properly send actionParam in such scenario? Please help.

回答1:

As of v 0.76.1, you can use the EntityQuery.withParameters method to pass additional parameters to any service method. So you can now construct a query like the following that both passes parameters and uses breeze's IQueryable support.

EntityQuery.from("EmployeesFilteredByCountryAndBirthdate")
                 .withParameters({ BirthDate: "1/1/1960", Country: "USA" })
                 .where("LastName", "startsWith", "S")
                 .orderBy("BirthDate");

where your controller method would look something like this:

[HttpGet]
public IQueryable<Employee> EmployeesFilteredByCountryAndBirthdate(DateTime birthDate, string country) {
      return ContextProvider.Context.Employees.Where(emp => emp.BirthDate >= birthDate && emp.Country == country);
}

The API docs have more information.



回答2:

UPDATE: AS OF BREEZE v.0.76.1 THIS IS NO LONGER THE CORRECT ANSWER. BREEZE NOW SUPPORTS PARAMETERS ON QUERIES. SEE THE "withParameters" QUERY CLAUSE.

Support for parameterized queries was added to Breeze thanks in part to this question on SO. Thank you.

This answer used to describe a workaround which is no longer needed. I have revised my answer, eliminating my description of that workaround.



标签: breeze