Showing posts with label Reporting Services. Show all posts
Showing posts with label Reporting Services. Show all posts

Thursday, July 5, 2012

Request for the permission of type "System.DirectoryServices failed"


I created a ssrs report with custom dll execution. The custom dll would retrieve the active directory groups of the report user. Code of custom dll function was:

// Get groups of user with specific prefix and extract the store information
public static List GetStoresSecurity(string groupprefix, string userName)
{
List result = new List();
// establish domain context
PrincipalContext yourDomain = new PrincipalContext(ContextType.Domain);
// find your user
UserPrincipal user = UserPrincipal.FindByIdentity(yourDomain, userName);
// if found - grab its groups
if (user != null)
{
PrincipalSearchResult groups = user.GetAuthorizationGroups();
// iterate over all groups
foreach (Principal p in groups)
{
// make sure to add only group principals
if (p is GroupPrincipal)
{
if (p.Name.StartsWith(groupprefix))
{
result.Add(p.Name.Replace(groupprefix, ""));
}
}
}
}
return result;
}

When I deployed the report I added to rssrvpolicy.config the following permission assign (ReportFunctions.dll contains my function):

<CodeGroup>

class="UnionCodeGroup"
version="1"
PermissionSetName="FullTrust"
Name="Report Functions"
Description="This code group grants full permissions to directory functions ">
class="UrlMembershipCondition"
version="1"
Url="C:\Program Files\Microsoft SQL Server\MSRS10_50.R2\Reporting Services\ReportServer\bin\ReportFunctions.dll"
/>
</CodeGroup>

When I tried to execute the report I got the error: Request for the permission of type "System.DirectoryServices failed". This was a permission error and the way I found to overpass it was to give full trust to .net assemblies. The way to do this was to edit again rssrvpolicy.config and make the following change:

<CodeGroup>

class="UnionCodeGroup"
version="1"
PermissionSetName="FullTrust"
Name="Report_Expressions_Default_Permissions"
Description="This code group grants default permissions for code in report expressions and Code element. ">
class="StrongNameMembershipCondition"
version="1"
PublicKeyBlob="0024000004800000940000000602000000240000525341310004000001000100512C8E872E28569E733BCB123794DAB55111A0570B3B3D4DE3794153DEA5EFB7C3FEA9F2D8236CFF320C4FD0EAD5F677880BF6C181F296C751C5F6E65B04D3834C02F792FEE0FE452915D44AFE74A0C27E0D8E4B8D04EC52A8E281E01FF47E7D694E6C7275A09AFCBFD8CC82705A06B20FD6EF61EBBA6873E29C8C0F2CAEDDA2"
/>
</CodeGroup>

Tuesday, May 22, 2012

Pass multivalue parameter to drillthrough report


Recently I had a request to create a drillthrough report for an aging report (actually 5 reports). I had 2 choices. One to create 5 reports or two to make one with multivalue parameters (each one of the parent reports must pass different values witch were static). Of course I decided to follow the second option. In order to do that I created the desired parameter in the parent report and I set it as multivalue and as internal.



Next I set the available values, and I set the same values and as defaults




Finally on the textbox witch I wanted to trigger the drillthrough action I inserted the parameter (OrderStatus is a multivalue parameter of the drillthrough report)




The text exression of the parent parameter was



Monday, November 8, 2010

Deserialization failed: The 'DataType' attribute is not declared

I faced the above problem when I tried to open a report in Visual Studio 2008. I had edited the report many times in the past and I don’t know what caused the problem. In my opinion it must be a bug of the report builder of Visual Studio 2008. I opened the xml definition of the report and compared it with a version of the report witch was working. The difference can be found below.

Working xml

      <ValidValues>
        <ParameterValues>
          <ParameterValue>
            <Value>-1</Value>
            <Label>Less Than</Label>
          </ParameterValue>
          <ParameterValue>
            <Value>0</Value>
            <Label>Equal</Label>
          </ParameterValue>
          <ParameterValue>
            <Value>1Value>
            <Label>Greater Than</Label>
          </ParameterValue>
        </ParameterValues>
      </ValidValues>

Not working xml

      <ValidValues>
        <ParameterValues>
          <ParameterValue>
            <Value DataType="Integer">-1</Value>
            <Label>Less Than</Label>
          </ParameterValue>
          <ParameterValue>
            <Value DataType="Integer">0</Value>
            <Label>Equal</Label>
          </ParameterValue>
          <ParameterValue>
            <Value DataType="Integer">1</Value>
            <Label>Greater Than</Label>
          </ParameterValue>
        </ParameterValues>
      </ValidValues>


I removed the DataType attribute and everything worked fine

Tuesday, June 1, 2010

How to iterate on Tablix rows?

I have implemented a custom renderer for sql server 2005 in order to send direct information from a report to Microsoft Dynamics CRM. When they announced me that I have to port the solution to sql server 2008 I encountered the following problems:

1. The namespace have been changed from

Microsoft.ReportingServices.ReportRendering;

to

Microsoft.ReportingServices.OnDemandReportRendering;

2. Control Table did not exist and had been replaced with Tablix. The iteration of table rows was easy, and I have implement it like this

Table table = reportItem as Table;

for (int j = 0; j < table.DetailRows.Count; j++)
{
    TableDetailRowCollection tableDetailRow = table.DetailRows[j];
    for (int k = 0; k < tableDetailRow.Count; k++)
    {
       
    }
}

But the Tablix control does not work like this. In order to iterate through the tablix rows I implemented the following code

Tablix table = reportItem as Tablix;                                               

int pos = -1;
foreach (TablixMember memberDef in table.RowHierarchy.MemberCollection)
{
    pos++;
    if (memberDef.IsStatic)
        continue;
    TablixDynamicMemberInstance instance = (TablixDynamicMemberInstance)memberDef.Instance;
    instance.ResetContext();
    while (instance.MoveNext())
    {
        foreach (TablixCell tableCell in table.Body.RowCollection[pos])
        {
            if (tableCell.CellContents.ReportItem is TextBox)
            {
                ...
            }
        }                               
    }
}