Hi,
I understand that a web form can limit functionality based on functions such
CanEditObject() etc.
However I am at a loss as to how I am supposed to restrict a gridview's fields based off roles.
For instance if I have an employer list in a gridview like below
FirstName Surname PhoneExtension Department Salary
I would only want roles (such as accounts) to be able to see the Salary Field.
Now I can easily use the ApplyAuthorizationRules() method and do something like
If !IsInRole(accounts)
gridview1.columns[4].visible = false;
but I am unsure if this is the correct way as to me it seems that the UI now has to know about business functionality?
Is there a better way?
Many Thanks
Jeremy
You can use CanReadProperty("Salary") instead of checking the role directly. Then your code can be simply:
gridview1.columns[4].visible = myObj.CanReadProperty("Salary");
This allows your business object to control which roles are authorized to do what and makes it so your UI code is actually asking the question you want the answer to.
Thanks SonofPirate,
I guess my main gripe is the amount of UI code required to make a GridView work. Especially with all the inserts/edits/read rules
Ideally if I could Create a custom CSLAGridView that for every databinding it would ask the question CanReadProperty then turn its self off/on it would be good.
Not sure if thats possible in a web environment
Cheers
Jeremy
Not sure how much work would be required, but it is certainly possible.
The way I would approach it is to iterate through the grid's columns, using the HeaderText property as the value to query on your BO. For example, using a GridView as the base, I would handle the RowDataBound event (or override OnRowDataBound) and do the following:
if (!_authorized)
{
IAuthorizeReadWrite dataItem = e.Row.DataItem as IAuthorizeReadWrite;
if (dataItem != null)
{
foreach col in myGrid.Columns
col.visible = dataItem.CanReadProperty(col.HeaderText);
_authorized = true;
}
}
I am using the RowDataBound because it gives me quick access to the individual list element that is being bound. However, I don't want to repeat this for every item so I use a boolean flag to test if the routine has already executed.
The first part makes sure that the bound object implements IAuthorizeReadWrite so that you know it supports the CanReadProperty method. If it does, I iteratate over the grid columns and check to see if the property corresponding to the column's header text is authorized and set the column's visible property accordingly.
The only drawback I see here, and I suppose with a little more time I could work it out, is that it requires the HeaderText property and your BO property names to match. If you localize or make the header text user-friendly, by putting spaces between words, for instance, then this wouldn't work. I'm thinking the SortExpression property on the GridView could be used instead of HeaderText, but I'm just thinking out loud...
This may not be the best solution, just a first pass. But, hopefully it helps get you started.
Thanks SonofPirate,
That definately looks like a good solution to the problem.
I will give that a go :)
Thanks
Jeremy
Copyright (c) Marimer LLC