Hello
Ok, here’s a sample app. It uses the PCTrade SQLite database shipped with Data Abstract, so you should be able to build and run it without any changes.
DAFilter.zip (126.8 KB)
The client app here provides 3 buttons that allow to
- Load some data as user 1
- Load the same data as user 2
- A attempt to cheat and override filters
Despite the data displayed in for 2 users is completely different, it is loaded using the same method:
private void GetData(string username)
{
var dm = new DataModule();
dm.LogOn(username, username);
var data = from o in dm.DataAdapter.GetTable<Orders>(new[] {new DataParameter("ClientID", "")}) select o;
this.dataGridView.AutoGenerateColumns = true;
this.dataGridView.DataSource = data.ToList();
}
Note the DataParameter passed from client to the server. Client cannot set its value. All it can is just to create a placeholder for this parameter.
Server side contains several points of interest.
1st is the Schema itself. SQL statement for the Orders table there looks like
SELECT
"Id", "OrderDate", "OrderStatus",
"CustomerId"
FROM
"Orders"
WHERE
"CustomerID" IN (SELECT "Id" FROM Customers WHERE "Id" = :ClientID)
AND {WHERE}
:ClientID
is defined in the Schema as a parameter for this table
2nd is the LoginService. There a set of hardcoded values is set for the filter:
public override bool LoginEx(String loginString)
{
...
// Store filter value
if (loginParameters.Username == "alpha")
{
this.Session["ClientID"] = "{6a71e27c-5e20-469d-8956-5b2a4aae6be1}";
}
else
{
this.Session["ClientID"] = "{b25b3cf8-f77b-48c1-8404-43e904a5b863}";
}
...
}
3rd is the place where this filter is actually applied:
DataService, event handler for the BeforeGetData event:
private void DataService_BeforeGetData(RemObjects.DataAbstract.Server.DataAbstractService sender, RemObjects.DataAbstract.Server.DataAbstractServiceGetDataEventArgs e)
{
var filerClientId = (string)this.Session["ClientID"];
foreach (var tableRequest in e.TableRequestInfoArray)
{
if (tableRequest == null)
{
continue;
}
foreach (var parameter in tableRequest.Parameters)
{
if (string.Equals(parameter.Name, "ClientID", StringComparison.OrdinalIgnoreCase))
{
parameter.Value = filerClientId;
}
}
}
}
Code here is very straightforward:
For each received request:
If there is a parameter named ClientID (name check is not case-sensitive) then assign filter value to this parameter.
As you can see the server doesn’t care about value of this parameter provided by the client. It just sets a value it considers as a correct one.
The testcase also provides a handler for the BeforeExecutingGetDataReader event. This event allows to investigate the Db Command right before it is sent to the underlying database. Try to run the sample and then look at the debug pane to make sure that the correct filter value has been used.
Regards