Sharepoint: Value does not fall within the expected range - sharepoint

I am trying to import a logo of a web and its subsite in sharepoint 2013.
When I try to load the file for subsite then exception occur.
Value does not fall within the expected range
Here is my code
if (siteLogo != null)
{
File = web.GetFileByServerRelativeUrl(siteLogo);
Data = File.OpenBinaryStream();
customContext.Context.Load(File);
customContext.Context.ExecuteQuery();
}
First Time it works fine. But when it loads for subsite it generate exception.
I tried alot to solve this but unable to find the solution. Please help.
This is complete file
public Branding(SharePointClientContext customContext, string siteLogo, string alternateCss, ListItemCollection ltItemCollection, Microsoft.SharePoint.Client.Web web)
{
if (ltItemCollection != null)
{
ListItem item = ltItemCollection.Where(a => a.DisplayName == "Current").FirstOrDefault();
if (item.FieldValuesAsText != null && item.FieldValuesAsText.FieldValues["ThemeUrl"] != null && item.FieldValuesAsText.FieldValues["ThemeUrl"] != "")
{
string themeUrl = item.FieldValuesAsText.FieldValues["ThemeUrl"].Split(',')[1];
string themeFileName = themeUrl.Substring(themeUrl.LastIndexOf('/') + 1).ToLower();
ListItem selectedTheme = ltItemCollection.Where(a =>
a.FieldValuesAsText.FieldValues["ThemeUrl"].Split(',')[1].Substring(a.FieldValuesAsText.FieldValues["ThemeUrl"].Split(',')[1].LastIndexOf('/') + 1) == themeFileName
&& a.DisplayName != "Current").FirstOrDefault();
this.Theme = selectedTheme.DisplayName;
}
}
if (siteLogo != null)
{
File = web.GetFileByServerRelativeUrl(siteLogo);
Data = File.OpenBinaryStream();
customContext.Context.Load(File);
customContext.Context.ExecuteQuery();
File = null;
}
if (alternateCss != null && alternateCss != "")
{
CssFile = web.GetFileByServerRelativeUrl(web.SiteLogoUrl);
CssData = CssFile.OpenBinaryStream();
web.Context.Load(CssFile);
web.Context.ExecuteQuery();
CssFile = null;
}
}
And calling this in following way.
SharePointConstants.branding.Add(new Branding(customContext, siteLogo, AlternateCss, ltItemCollection, web));

Related

Uplaoded Image but with 0 KB size

I'm using .NET Core 3.1 but I encountered a weird problem!
the problem is any uploaded image the size of it is 0KB
when I restart the IIS and trying again will upload it without any problem but after that, the problem returns back.
I tried this solution by making my code async but with no luck
I changed my system file to be accessible by my Application pool user but with no luck
Here is my code :
public Document shareWithUsers([FromForm] CreateDocumentDto documentDto)
{
List<CreateUserType1DocumentsDto> listOfCreateUserType1Documents = new List<CreateUserType1DocumentsDto>();
List<CreateHDDocumentsDto> listOfCreateHDDocuments = new List<CreateHDDocumentsDto>();
if (documentDto.listOfUserType1Documents != null)
{
foreach (var item in documentDto.listOfUserType1Documents)
{
listOfCreateUserType1Documents.Add(JsonConvert.DeserializeObject<CreateUserType1DocumentsDto>(item));
}
}
else if (documentDto.listOfHDDocuments != null)
{
foreach (var item in documentDto.listOfHDDocuments)
{
listOfCreateHDDocuments.Add(JsonConvert.DeserializeObject<CreateHDDocumentsDto>(item));
}
}
if (documentDto.sharedText == null)
{
if (documentDto.document != null) //that mean user upload file
{
if (documentDto.document.Length > 0)
{
var UploadedFilesPath = Path.Combine(hosting.WebRootPath/*wwwroot path*/, "UploadedFiles" /*folder name in wwwroot path*/);
var filePath = Path.Combine(UploadedFilesPath, documentDto.document.FileName);
//documentDto.docUrl = filePath;
var documentObject = new Document();
using (var stream = new FileStream(filePath, FileMode.Create))
{
documentDto.document.CopyToAsync(stream);// Use stream
}
if (documentDto.listOfUserType1Documents != null)
{
documentObject.listOfUserType1Documents = ObjectMapper.Map<List<UserType1Documents>>(listOfCreateUserType1Documents);
}
else if (documentDto.listOfHDDocuments != null)
{
documentObject.listOfHDDocuments = ObjectMapper.Map<List<HDDocuments>>(listOfCreateHDDocuments);
}
documentObject.docTtitle = documentDto.docTtitle;
documentObject.docName = documentDto.docName;
documentObject.docUrl = filePath;
return _repository.Insert(documentObject);
}
}
}
else
{ //that mean user upload text
var documentObject = new Document();
if (documentDto.listOfUserType1Documents != null)
{
documentObject.listOfUserType1Documents = ObjectMapper.Map<List<UserType1Documents>>(listOfCreateUserType1Documents);
}
else if (documentDto.listOfHDDocuments != null)
{
documentObject.listOfHDDocuments = ObjectMapper.Map<List<HDDocuments>>(listOfCreateHDDocuments);
}
documentObject.sharedText = documentDto.sharedText;
return _repository.Insert(documentObject);
}
return null;
}
My code works only if I change both of them (CopyTo and Insert ) to Async with await
await CopyToAsync()
await InsertAsync()

What is the Best Practice to update multiple fields in a Plugin

I have a plugin registered in Post operation that needs to update multiple fields in CRM using data from an XML file. Currently I am using the following code:
if (node["node1"] != null)
{
var sId = sElement.GetElementsByTagName("pId")[0].InnerText;
Guid sGUID = new Guid(sId);
sEntity["Attrib1"] = sGUID;
service.Update(sEntity);
}
if (node["node2"] != null)
{
var sMax = sElement.GetElementsByTagName("pMax")[0].InnerText;
sEntity["Attrib2"] = sMax;
service.Update(sEntity);
}
if (node["node3"] != null)
{
var sMin = sElement.GetElementsByTagName("pMin")[0].InnerText;
sEntity["Attrib3"] = sMin;
service.Update(sEntity);
}
So I am calling the service.Update each time I need to update and in the above case 3 times.
Is there a better way to accomplish what I am trying to do and call the service.Update only one time?
You can just do a single update in the end (eventually you can add a check in case none of the fields changed, to avoid a useless update):
if (node["node1"] != null)
{
var sId = sElement.GetElementsByTagName("pId")[0].InnerText;
Guid sGUID = new Guid(sId);
sEntity["Attrib1"] = sGUID;
}
if (node["node2"] != null)
{
var sMax = sElement.GetElementsByTagName("pMax")[0].InnerText;
sEntity["Attrib2"] = sMax;
}
if (node["node3"] != null)
{
var sMin = sElement.GetElementsByTagName("pMin")[0].InnerText;
sEntity["Attrib3"] = sMin;
}
service.Update(sEntity);

display media library file size in custom module in Orchard

I have custom module for employee and i want to display cv document side on listing of employee in grid view.
how to get size of document? i have used media library to upload cv. can someone help me on it
thanks
Please follow the below code for get the file size.
Add Property in your ABCPart.cs( public string FileSize { get; set; })
After get list of record then add below code for get file size.
int cnt = 0;
foreach (var item in lstDocument)
{
var b = item.Fields.Single(f => f.Name == "YourMediaLibararyPickerFieldName");
if (item.Fields.Single(f => f.Name == "YourMediaLibararyPickerFieldName") != null)
{
var field = _contentManager.Get(((Orchard.MediaLibrary.Fields.MediaLibraryPickerField)item.Fields.Single(f => f.Name == "YourMediaLibararyPickerFieldName")).Ids[0]);
if (field != null && field.ContentType == "Document")
{
long a = ((Orchard.MediaLibrary.Models.DocumentPart)_contentManager.Get(((Orchard.MediaLibrary.Fields.MediaLibraryPickerField)item.Fields.Single(f => f.Name == "YourMediaLibararyPickerFieldName")).Ids[0]).As<Orchard.MediaLibrary.Models.DocumentPart>()).Length;
lstDocument[cnt].FileSize = (a / 1024).ToString() + " KB";
}
else
{
lstDocument[cnt].FileSize = "-";
}
}
else
{
lstDocument[cnt].FileSize = "-";
}
cnt++;
}

Get entity object's property names excluding entitycollection and entityreference

I am working on a method that compares two objects using reflection. The object types are objects created from entity framework. When I use GetProperties() I am getting EntityCollection and EntityReference properties. I only want the properties that belong to the object and not any associated properties or references from foreign keys.
I've tried the following How to get all names of properties in an Entity?.
I thought about passing an array of properties to compare but I don't want to have to type them in for each object type. I am open to some suggestions even those that don't use reflection.
public bool CompareEntities<T>(T oldEntity, T newEntity)
{
bool same = true;
PropertyInfo[] properties = oldEntity.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
var oldValue = property.GetValue(oldEntity, null);
var newValue = property.GetValue(newEntity, null);
if (oldValue != null && newValue != null)
{
if (!oldValue.Equals(newValue))
{
same = false;
break;
}
}
else if ((oldValue == null && newValue != null) || (oldValue != null && newValue == null))
{
same = false;
break;
}
}
return same;
}
Using the suggestions from #Eranga and https://stackoverflow.com/a/5381986/1129035 I was able to come up with a workable solution.
Since some of the properties in the root object are a GenericType there needs to be two different if statements. Only if the current property is an EntityCollection skip over it.
public bool CompareEntities<T>(T oldEntity, T newEntity)
{
bool same = true;
PropertyInfo[] properties = oldEntity.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)
.Where(pi => !(pi.PropertyType.IsSubclassOf(typeof(EntityObject)))
&& !(pi.PropertyType.IsSubclassOf(typeof(EntityReference)))
).ToArray();
foreach (PropertyInfo property in properties)
{
if (property.PropertyType.IsGenericType)
{
if (property.PropertyType.GetGenericTypeDefinition() == typeof(EntityCollection<>))
{
continue;
}
}
var oldValue = property.GetValue(oldEntity, null);
var newValue = property.GetValue(newEntity, null);
if (oldValue != null && newValue != null)
{
if (!oldValue.Equals(newValue))
{
same = false;
break;
}
}
else if ((oldValue == null && newValue != null) || (oldValue != null && newValue == null))
{
same = false;
break;
}
}
return same;
}
Try filtering out EntityObject type and EntityCollection properties.
var properties = oldEntity.GetType().GetProperties().
Where(pi => !(pi.PropertyType.IsSubclassOf(typeof(EntityObject))
|| pi.PropertyType.IsSubclassOf(typeof(EntityCollection));
make it easy for yourself and do this instead
PropertyInfo[] properties = oldEntity.GetType().GetProperties(pi=> pi.PropertyType.NameSpace=="System").ToArray();

Getting a random UserProfile In SharePoint 2010

I am trying to retrieve a random number of users from the UserProfileManager.
But I am encountering errors when deploying to the live servers. I can't seem to see what is causing the error. My code is below:
for (int i = 0; i < NumberOfUserLimit; i++)
{
UserProfile up = profileManager.GetUserProfile(random.Next(1, NumberOfUserLimit));
if (up["FirstName"] != null && up["FirstName"].Value != null && !String.IsNullOrEmpty(up["FirstName"].Value.ToString()))
{
DataRow drUserProfile;
drUserProfile = dtUserProfile.NewRow();
drUserProfile["DisplayName"] = up.DisplayName;
drUserProfile["FirstName"] = up["FirstName"].Value;
drUserProfile["LastName"] = up["LastName"].Value;
drUserProfile["Department"] = up["Department"].Value;
drUserProfile["Location"] = up["SPS-Location"].Value;
drUserProfile["HireDate"] = up["SPS-HireDate"].Value;
drUserProfile["ContactNumber"] = up["Office"].Value;
if (up["PictureURL"] != null && up["PictureURL"].Value != null && !String.IsNullOrEmpty(up["PictureURL"].Value.ToString()))
{
string cleanAccountName = up["AccountName"].Value.ToString().Replace(#"\", "_");
string pictureUrl = String.Format("https://my.someintranet.com/User Photos/Profile Pictures/{0}_MThumb.jpg", cleanAccountName);
drUserProfile["Image"] = pictureUrl;
}
else
{
drUserProfile["Image"] = "~/_layouts/images/O14_person_placeHolder_96.png";
}
drUserProfile["MySiteUrl"] = up.PublicUrl;
dtUserProfile.Rows.Add(drUserProfile);
}
}
My code works when I apply a simple foreach to my code above instead of the "for loop":
foreach (UserProfile up in profileManager)
Which proves I can return userprofiles.
Any help is appreciated.
profileManager.GetUserProfile(long recordId)
expects a recordId from userprofile table. It is not an index, so you cannot use "random".
If you want to check RecordId, you can take a look at SQL tables of ProfileDB. Table "UserProfile_Full" has MasterRecordId column. Your parameter in GetUserProfile has to match of the user profile's MasterRecordId.
you can use the following code to get your random profiles:
IEnumerator profiles = profileManager.GetEnumerator();
int index = new Random().Next(1, 100);
while (index >= 0 && profiles.MoveNext())
index--;
UserProfile currentProfile = (UserProfile)profiles.Current
Code that handles Random better
public class TestClass
{
private random = new Random();
private long totalNumberOfProfiles; //ProfileManager.Count not always returns count correctly
public TestClass()
{
//this does not have to be in constructor but point is to have it cached (reasonably)
IEnumerator profiles = profileManager.GetEnumerator();
long counter = 0;
while (profiles.MoveNext())
counter++;
this.totalNumberOfProfiles = counter;
}
public fillInDataSet()
{
//something is here...
IEnumerator profiles = profileManager.GetEnumerator();
int index = random.Next(1, totalNumberOfProfiles);
while (index >= 0 && profiles.MoveNext())
index--;
UserProfile currentProfile = (UserProfile)profiles.Current
//something is here...
}
}

Resources