Я настроил веб-приложение для поиска в Active Directory нашей организации. Запрос (динамическое обёртывание SQL OpenQuery) возвращает также шестнадцатеричные данные для thumpnailPhoto.
Когда я показываю изображение, я получаю 40% успеха на всех отображаемых изображениях. «Плохие» обычно хороши в первых 15%, начиная сверху и заканчивая черными полосами. Иногда есть данные изображения, повторяющиеся в полосах ... Некоторые изображения профиля не отображаются вообще, а другие идеально. Должны быть разные форматы изображений, но без доступа к местам хранения этих изображений я больше не получаю.
Вот что я делаю:
Я связываю данные из запроса с GridView.
protected void FillGrid(Object sender, EventArgs e)
{
SqlConnection objConn = new SqlConnection("Data Source=XXXXXXXXXX");
SqlDataAdapter adapter = new SqlDataAdapter();
SqlCommand objCommand = new SqlCommand(@"declare @SQL nvarchar(4000)
declare @Asterisc nvarchar(1)
declare @Sub nvarchar(12)
set @SearchName = CASE WHEN @SearchName = '' THEN '*' ELSE @SearchName END
set @SearchSurename = CASE WHEN @SearchSurename = '' THEN '*' ELSE @SearchSurename END
set @Asterisc = '*'
set @Sub = CASE WHEN @Subsidiary = '*' THEN '' ELSE (@Subsidiary+', OU=') END
set @SQL ='SELECT TOP (100) PERCENT samAccountName AS UserAccount, givenName AS FirstName, sn AS LastName, department, title AS Position,
physicaldeliveryofficename AS Office, extensionAttribute1 AS PersonnelID, initials, mail AS email, telephonenumber AS Phone, extensionattribute5 AS Extension,
mobile, extensionattribute3 AS MobileExt, thumbnailPhoto
FROM OPENQUERY(ADSI, ''SELECT samAccountName, givenName, sn, legacyExchangeDN, department, title, physicaldeliveryofficename, extensionAttribute1, distinguishedName, initials,
mail, telephonenumber, extensionattribute5, mobile, extensionattribute3, thumbnailPhoto
FROM ''''LDAP://OU=' + @Sub + 'XXXX, DC=XXXX,DC=XXXX,DC=XXXX''''
WHERE objectClass=''''Person'''' AND objectClass = ''''User'''' AND givenName = ''''' + @SearchName + ''''' AND samAccountName = ''''' + @SearchSurename + ''''' AND extensionAttribute1 = ''''' + @Asterisc + ''''' '') AS AD_Users
ORDER BY UserAccount'
exec (@SQL)", objConn);
objCommand.Parameters.Add("@SearchName", SqlDbType.NVarChar).Value = TextBoxSearchName.Text;
objCommand.Parameters.Add("@SearchSurename", SqlDbType.NVarChar).Value = TextBoxSearchSureName.Text;
objCommand.Parameters.Add("@Subsidiary", SqlDbType.NVarChar).Value = DDSubsidiary.Text;
DataTable t = new DataTable();
adapter.SelectCommand = objCommand;
objConn.Open();
adapter.Fill(t);
objConn.Close();
GridView.DataSource = t;
GridView.DataBind();
}
Затем во время события RowDataBound я кодирую данные следующим образом и привязываю эти данные к элементу управления asp: image:
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView dr = (DataRowView)e.Row.DataItem;
if(!String.IsNullOrEmpty(Convert.ToString(dr["thumbnailPhoto"])))
{
string imageUrl = "data:image/jpg;base64," + Convert.ToBase64String((byte[])dr["thumbnailPhoto"]);
(e.Row.FindControl("Image1") as Image).ImageUrl = imageUrl;
}
}
}
С какой проблемой я здесь сталкиваюсь и как с ней бороться?
Я только что обнаружил, что те картинки, которые отображаются частично или с полосами, - это все картинки, которые хранятся в большем формате 600x600, в то время как хорошие имеют формат 96x96. Это приводит меня к подозрению, что что-то идет не так при получении thumbprintPhoto в шестнадцатеричном формате с помощью SQL.
Как предположил Габриэль, я попытался использовать DirectorySearcher. Отпечаток пальца был отображен правильно, но мне понадобилось более 10 секунд, чтобы получить 44 записи AD: Вот мой код
protected void SearchAD(object sender, EventArgs e)
{
string Name = TextBoxSearchFirstName.Text;
Name = Name.Replace("*", "") + "*";
DirectorySearcher dsSearcher = new DirectorySearcher();
dsSearcher.Filter = "(&(objectClass=user) (sn=" + Name + "))";
results = dsSearcher.FindAll();
DataTable t = new DataTable("ActiveDir");
t.Columns.Add(new DataColumn("SecondName", System.Type.GetType("System.String")));
t.Columns.Add(new DataColumn("FirstName", System.Type.GetType("System.String")));
t.Columns.Add(new DataColumn("UserID", System.Type.GetType("System.String")));
t.Columns.Add(new DataColumn("data", System.Type.GetType("System.Byte[]")));
if (results != null)
{
foreach (SearchResult searchResult in results)
{
DataRow myRow;
myRow = t.NewRow();
myRow[0] = searchResult.GetDirectoryEntry().Properties["sn"].Value;
myRow[1] = searchResult.GetDirectoryEntry().Properties["givenName"].Value;
myRow[2] = searchResult.GetDirectoryEntry().Properties["samAccountName"].Value;
myRow[3] = searchResult.GetDirectoryEntry().Properties["thumbnailPhoto"].Value;
t.Rows.Add(myRow);
}
}
GridView1.DataSource = t;
GridView1.DataBind();
}
Решено: Габриэль настроил код поиска AD, и теперь он быстрее, чем SQL-запрос.
Чтобы отображать изображения AD Thumnail Profil без использования обработчика, выполните декодирование во время события GridViews OnRowDataBound:
protected void OnRowDataBoundAdUser(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView dr = (DataRowView)e.Row.DataItem;
if (!String.IsNullOrEmpty(Convert.ToString(dr["data"])))
{
byte[] data = dr["data"] as byte[];
MemoryStream s = new MemoryStream(data);
byte[] imageBytes = s.ToArray();
string base64String = Convert.ToBase64String(imageBytes);
string imageUrl = "data:image/jpg;base64," + base64String;
(e.Row.FindControl("Image1") as System.Web.UI.WebControls.Image).ImageUrl = imageUrl;
}
}
}