I am creating Sitecore item programtically and want to add some images for my item while creating programatically.It should get that image from Sitecore media, How to do that, need help.I Know how to do that using content item
If you only want to assign an image to a field you have to add this code:
item.Editing.BeginEdit();
ImageField imageField = item.Fields["Your Image Field"];
imageField.MediaID = new ID("IMAGE ID");
item.Editing.EndEdit();
If you want to create an image dynamically from a URL and then assign it to your item, you could use the following code:
var destinationPath = StringUtil.EnsurePostfix('/', imagesFolder.Paths.Path);
string imageName = ItemUtil.ProposeValidItemName(model.Title);
var options = new MediaCreatorOptions
{
Database = ItemHelpers.GetMasterDatabase(),
Versioned = false,
Destination = destinationPath + imageName,
FileBased = false,
IncludeExtensionInItemName = false,
KeepExisting = true,
AlternateText = imageName
};
try
{
WebClient cli = new WebClient();
byte[] imgBytes = cli.DownloadData(imageUrl);
using (var memStream = new MemoryStream(imageBytes))
{
Item scImage = MediaManager.Creator.CreateFromStream(memStream, imageUrl, options);
//Publish your Item
//scImage.ID is the one you need to assign to you image field
}
}
catch (Exception)
{
//Your code
}
Related
I am using powerbi embedded and I would like an export button similar to the one used on powerbi.com, that asks if you want to apply the current filters or not.
How can I get the current filters in javaScript in such a way that these can be passed to the back end, or to the javascript api to generate a PDF?
I am using the following code to generate the PDF currently, I just don't know how to get the current configuration current filters and current page selected in javaScript
public PowerBiExportViewModel CreateExport(Guid groupId,
Guid reportId,
IEnumerable<PowerBiReportPage> reportPages,
FileFormat fileFormat,
string urlFilter,
TimeSpan timeOut)
{
var errorMessage = string.Empty;
Stream stream = null;
var fileSuffix = string.Empty;
var securityToken = GetAccessToken();
using (var client = new PowerBIClient(new Uri(BaseAddress), new TokenCredentials(securityToken, "Bearer")))
{
var powerBiReportExportConfiguration = new PowerBIReportExportConfiguration
{
Settings = new ExportReportSettings
{
Locale = "en-gb",
IncludeHiddenPages = false
},
Pages = reportPages?.Select(pn => new ExportReportPage { PageName = pn.Name }).ToList(),
ReportLevelFilters = !string.IsNullOrEmpty(urlFilter) ? new List<ExportFilter>() { new ExportFilter(urlFilter) } : null,
};
var exportRequest = new ExportReportRequest
{
Format = fileFormat,
PowerBIReportConfiguration = powerBiReportExportConfiguration
};
var export = client.Reports.ExportToFileInGroupAsync(groupId, reportId, exportRequest).Result;
You can go to PowerBi playground and play around with their sample report. Next to "Embed" button you have "Interact" and option to get filters. In response you get JSON with filters. If you are too lazy to go there, here is the code it created for me
// Get a reference to the embedded report HTML element
var embedContainer = $('#embedContainer')[0];
// Get a reference to the embedded report.
report = powerbi.get(embedContainer);
// Get the filters applied to the report.
try {
const filters = await report.getFilters();
Log.log(filters);
}
catch (errors) {
Log.log(errors);
}
I am on Sitecore 7.2
I am experiencing issues trying to retrieve media URL.
I have a template (PageBanner) with just one field called BannerImage. Field type is Image.
Another template named Homepage inherits this template PageBanner.
A content item Home uses template Homepage. I can see the BannerImage field as a part of the Home content item. An image has been assigned to this field as well.
Now, the back-end bit where the issue is encountered.
homeItem.Field["BannerImage"] returns image item.
homeItem["BannerImage"] returns empty string.
If I try to cast it to ImageField -(ImageField)homeItem.Field["BannerImage"], the resultant ImageField item doesn't have MediaItem or any other field set.
I can do :
var imageFieldItem = Sitecore.Context.Database.GetItem(homeItem.Fields["BannerImage"].ID);
var mediaUrl = MediaManager.GetMediaUrl(imageFieldItem);
But that gives me a dynamic media url in the form of -~/media/a2c15f35836746f398e772c81d040607.ashx
I am looking to get the media URL by path.
Any idea what am I missing here?
You are making the correct call to get the URL using the MediaManager but you need to pass the inner MediaItem to the GetMediaUrl() method:
string imageURL = string.Empty;
Sitecore.Data.Fields.ImageField imageField = homeItem.Field["BannerImage"];
if (imageField != null && imageField.MediaItem != null)
{
Sitecore.Data.Items.MediaItem image = new Sitecore.Data.Items.MediaItem(imageField.MediaItem);
imageURL = Sitecore.StringUtil.EnsurePrefix('/', Sitecore.Resources.Media.MediaManager.GetMediaUrl(image));
}
As for the dynamic URL being generated, if it is in Edit mode then this is normal, Check in Normal mode that the media URL is fully rendered.
Try this code out in some utility class.
var imageUrl = GetImageUrl(homeItem, "BannerImage" false);
public static string GetImageUrl(Item item, string fieldname, bool includeServerUrl)
{
// do the checks
if (item == null) { return ""; }
if (fieldname.Length == 0) { return ""; }
// create media options
Sitecore.Resources.Media.MediaUrlOptions mediaUrlOptions = new Sitecore.Resources.Media.MediaUrlOptions { AlwaysIncludeServerUrl = true };
mediaUrlOptions.AbsolutePath = true;
// do we want to include the FQDN?
if (includeServerUrl)
mediaUrlOptions.AlwaysIncludeServerUrl = true;
// convert to image field
Sitecore.Data.Fields.ImageField imagefield = item.Fields[fieldname];
if (imagefield == null) { return ""; }
// get the item so we can process it
Item mediaitem = Sitecore.Context.Database.GetItem(imagefield.MediaID);
if (mediaitem == null) { return ""; }
// pass in the item with the options to get the URL
string mediaurl = Sitecore.Resources.Media.MediaManager.GetMediaUrl(mediaitem, mediaUrlOptions);
if (mediaurl == null) { return ""; }
return mediaurl;
}
I want to be able to create/update media items in code and also use language versioning. Here are more specifics. I have a Product content item. When that item is saved I want to be able to generate a PDF version of that item and save it to the media library. If the PDF version already exists in the media library I need to be able to update it. In addition this is a multi-language site. So if someone saves the French version of the Product content item I need to be able to generate the French version of the PDF and only save/update the French version of the associated PDF in the media library - not touch any of the other language versions of the PDF. I can't seem to figure out how to do this. The code that I have currently does the following: if I save the English version of the Product then it creates and English version of the PDF. But then if I save the French version of the Product, it creates a French version of the PDF and removes the English version of the PDF.
Anyone know how to do this?
public static Item AddMediaItem(byte[] fileBuffer, string fullMediaPath, string fileNameWithExtension, string title, Language language)
{
try
{
var db = Sitecore.Configuration.Factory.GetDatabase("master");
var options = new MediaCreatorOptions();
options.FileBased = false;
options.IncludeExtensionInItemName = false;
options.KeepExisting = false;
options.Versioned = true;
options.Destination = fullMediaPath;
options.Database = db;
options.Language = language;
var creator = new MediaCreator();
var fileStream = new MemoryStream(fileBuffer);
var pdfItem = db.GetItem(fullMediaPath, language);
if (pdfItem != null)
{
var updatedItem = creator.AttachStreamToMediaItem(fileStream, fullMediaPath, fileNameWithExtension,
options);
updatedItem.Editing.BeginEdit();
updatedItem.Fields["Title"].Value = title;
updatedItem.Editing.EndEdit();
return updatedItem;
}
else
{
//Create a new item
var newItem = creator.CreateFromStream(fileStream, fileNameWithExtension, options);
newItem.Editing.BeginEdit();
newItem.Fields["Title"].Value = title;
newItem.Editing.EndEdit();
return newItem;
}
}
catch (Exception ex)
{
return null;
}
}
Thanks to #JanBluemink for pointing me in the right direction. I found the right approach in the following article: Sitecore.Resources.Media.MediaCreator deletes versions of media. I just had to modify the code to use MediaManager instead of MediaCreator when updating.
public static Item AddMediaItem(byte[] fileBuffer, string fullMediaPath, string fileNameWithExtension, string title, Language language)
{
try
{
var db = Sitecore.Configuration.Factory.GetDatabase("master");
var options = new MediaCreatorOptions();
options.FileBased = false;
options.IncludeExtensionInItemName = false;
options.KeepExisting = false;
options.Versioned = true;
options.Destination = fullMediaPath;
options.Database = db;
options.Language = language;
var creator = new MediaCreator();
var fileStream = new MemoryStream(fileBuffer);
var pdfItem = db.GetItem(fullMediaPath, language);
if (pdfItem != null)
{
var mediaItem = new MediaItem(pdfItem);
var media = MediaManager.GetMedia(mediaItem);
media.SetStream(fileStream, "pdf");
pdfItem.Editing.BeginEdit();
pdfItem.Fields["Title"].Value = title;
pdfItem.Editing.EndEdit();
return pdfItem;
}
else
{
//Create a new item
var newItem = creator.CreateFromStream(fileStream, fileNameWithExtension, options);
newItem.Editing.BeginEdit();
newItem.Fields["Title"].Value = title;
newItem.Editing.EndEdit();
return newItem;
}
}
catch (Exception ex)
{
return null;
}
}
I had to add couple of more lines for updating media item stored in File System with versioning.
if (mediaItem.FileBased)
{
string uniqueFilename = FileUtil.GetUniqueFilename(FileUtil.MakePath(Settings.Media.FileFolder, MediaManager.Creator.GetMediaStorageFolder(mediaItem.ID, fileshortname)));
using (new Sitecore.SecurityModel.SecurityDisabler())
{
mediaItem.BeginEdit();
mediaItem.FilePath = uniqueFilename;
mediaItem.EndEdit();
}
}
Media media = MediaManager.GetMedia(mediaItem);
using (FileStream stream = new FileStream(fileName, FileMode.Open))
{
media.SetStream(stream, FileUtil.GetExtension(fileshortname));
}`
I am trying to figure out how to tag friends and the location when an media object such as a image has been attached to the post. I understand it's possible to use the "tags" and "location" parameters when posting a message to your own feed (/me/feed), but result differ for posting to /me/photo and unfortunately doesn't work at all. The code snippet below is what I have so far:
var photoIndex = 0;
var facebookBatchParameters = new List<FacebookBatchParameter>();
foreach (var photo in photos)
{
IDictionary<string, Object> parameters = new ExpandoObject();
parameters["message"] = message;
parameters["tags"] = "###, ###";
parameters["place"] = "###";
parameters[string.Format("photo{0}", photoIndex++)] =
new FacebookMediaObject {ContentType = "image/jpeg", FileName = photo.FileName}.SetValue(
photo.Data);
facebookBatchParameters.Add(new FacebookBatchParameter
{
HttpMethod = HttpMethod.Post,
Path = "/me/photo",
Parameters = parameters
});
}
await App.FacebookClient.BatchTaskAsync(facebookBatchParameters.ToArray());
I'm trying to reproduce the Activities page in Microsoft CRM 4.0 via web services. I can retrieve a list of activities, and I believe I need to use ActivityPointers to retrieve the entities but have so far been unsuccessful. Would I need to loop through every single entity returned from the first query to retrieve the ActivityPointer for it? And if so, how would I then get the "Regarding" field or Subject of the activity (eg: email).
The code to retrieve the activities is:
var svc = GetCrmService();
var cols = new ColumnSet();
cols.Attributes = new[] { "activityid", "addressused", "scheduledstart", "scheduledend", "partyid", "activitypartyid", "participationtypemask", "ownerid" };
var query = new QueryExpression();
query.EntityName = EntityName.activityparty.ToString();
query.ColumnSet = cols;
LinkEntity link = new LinkEntity();
//link.LinkCriteria = filter;
link.LinkFromEntityName = EntityName.activitypointer.ToString();
link.LinkFromAttributeName = "activityid";
link.LinkToEntityName = EntityName.activityparty.ToString();
link.LinkToAttributeName = "activityid";
query.LinkEntities = new[] {link};
var activities = svc.RetrieveMultiple(query);
var entities = new List<ICWebServices.activityparty>();
RetrieveMultipleResponse retrieved = (RetrieveMultipleResponse) svc.Execute(request);
//var pointers = new List<activitypointer>();
foreach (activityparty c in activities.BusinessEntities)
{
entities.Add(((activityparty)c));
//the entities don't seem to contain a link to the email which they came from
}
Not sure if I understand your problem, but the field "activityid" in the activitypointer object is the same activityid as the underlying activity (email, task, phonecall, etc). The regardingobjectid is the link to the regarding entity.
Heres what you need to get the equivalent of the Activities page
ColumnSet cols = new ColumnSet()
{
Attributes = new string[] { "subject", "regardingobjectid", "regardingobjectidname", "regardingobjectidtypecode", "activitytypecodename", "createdon", "scheduledstart", "scheduledend" }
};
ConditionExpression condition = new ConditionExpression()
{
AttributeName = "ownerid",
Operator = ConditionOperator.Equal,
Values = new object[] { CurrentUser.systemuserid.Value } //CurrentUser is an systemuser object that represents the current user (WhoAmIRequest)
};
FilterExpression filter = new FilterExpression()
{
Conditions = new ConditionExpression[] { condition },
FilterOperator = LogicalOperator.And
};
QueryExpression query = new QueryExpression()
{
EntityName = EntityName.activitypointer.ToString(),
ColumnSet = cols,
Criteria = filter
};
BusinessEntityCollection activities = svc.RetrieveMultiple(query);
foreach (activitypointer activity in activities)
{
//do something with the activity
//or get the email object
email originalEmail = (email)svc.Retrieve(EntityName.email.ToString(), activity.activityid.Value, new AllColumns());
}