I want to get the date of creation of a video file, commonly known as Media Created property (not to be confused with the File Creation Date)
I'm trying with this code:
var clip = await MediaClip.CreateFromFileAsync(x);
var encodingProps = clip.GetVideoEncodingProperties();
var props = encodingProps.Properties.ToList();
Inside the props reference I'm getting a list of Guids and values, but I'm lost there.
You can use Extended properties to get the specific property you need:
var dateEncodedPropertyName = "System.Media.DateEncoded";
var propertyNames = new List<string>()
{
dateEncodedPropertyName
};
// Get extended properties
IDictionary<string, object> extraProperties =
await file.Properties.RetrievePropertiesAsync(propertyNames);
// Get the property value
var propValue = extraProperties[dateEncodedPropertyName];
if (propValue != null)
{
Debug.WriteLine(propValue);
}
Note I am using the System.Media.DateEncoded property in the example. If you need a different property, check out the full list of supported properties with their exact names in documentation.
Related
I'm new in developing acumatica I am stuck at getting the value of a custom TextEdit field that I created. I can get all of the built-in field value through this code
InventoryItem items = (InventoryItem)Base.Item.Cache.Current;
but I cannot get the one that I have created at acumatica customization
here is the field I want to get
https://i.stack.imgur.com/gPln4.png
I already tried
InventoryItem items = (InventoryItem)Base.ItemSettings.Cache.Current;
var shortdesc = items.UsrShortDescription;
But it's not working and does not show the value inside the textbox
thank you in advance for helping
InventoryItem items = (InventoryItem)Base.ItemSettings.Current;
var itemExt = PXCache<InventoryItem>.GetExtension<InventoryItemExt>(items);
var shortdesc = itemExt.UsrShortDescription;
Vardan showed one way, for completeness of picture want to show another as well:
InventoryItem items = (InventoryItem)Base.ItemSettings.Current;
var itemExt = items.GetExtension<InventoryItemExt>();
This is an example of getting value from a non-extension field. I did not use extension DAC to add the Gift card field to the store setup screen.
In a method I need to get the value of that field. I should check whether the order contains Gift card item or not.
public static bool GiftcardName(OrderModel orders, BZWoocommerceStore store)
{
// "ZGift CArd W" => "giftcard"
string wooCommName = string.Empty;
string wooCommNameNoSpases = string.Empty;
bool containsGiftcardName = false;
bool isGiftcard = false;
foreach (OrderLineModel line in orders.LineItems)
{
string gNameInAcumatica = store.GiftcardIdentifier;
string gNameInAcumaticaWithoutSpaces = gNameInAcumatica.Replace(" ", "");
wooCommName = line.Name; //pattern
wooCommNameNoSpases = wooCommName.Replace(" ", "");
//wooCommNameNoSpases = new string(wooCommName.ToCharArray()
// .Where(c => !Char.IsWhiteSpace(c))
// .ToArray());
//woCommNameNoUperCase= wooCommNameNoSpases.ToLower();
//isGiftcardName= woCommNameNoUperCase.Contains(gName);
//containsGiftcardName = wooCommNameNoSpases.Contains(gName);
containsGiftcardName = Regex.IsMatch(wooCommNameNoSpases, gNameInAcumaticaWithoutSpaces, RegexOptions.IgnoreCase);
if(containsGiftcardName)
{
isGiftcard = true;
}
}
return isGiftcard;
}
So, when I call this method I give to that 2 arguments, orders and store.
The store argument was created in this way.
public PXSelect<BZWoocommerceOrder> Order;
In an action method I wrote this.
string storeCode = this.Order.Current.StoreCode;
BZWoocommerceStore store = PXSelect<BZWoocommerceStore, Where<BZWoocommerceStore.storeCode, Equal<Required<BZWoocommerceStore.storeCode>>>>.Select(this, storeCode);
My GiftcardName() method sees the value of original field. Writing "Original" I mean that you do not use any technique like this one.
BZSOOrderExt rowExt = sender.GetExtension<BZSOOrderExt>(row);
I have the following helper function that uses reflection to look at the supplied model, check if any fields are non-null, and overwrite those with new values in MongoDB.
It works fine until I try updating a List<string> field. Instead of saving the list as an array to MongoDB, it saves a string value of "(Collection)" in MongoDB. What am I missing to make this work?
I don't want to hardcode that any List should default to List<string> either. It's possible I could have lists of ints.
public override MyObj Update(MyObj model)
{
var builder = Builders<MyObj>.Update;
var builder_def = builder.Set(x => x.Id, model.Id);
foreach (PropertyInfo prop in model.GetType().GetProperties())
{
var value = model.GetType().GetProperty(prop.Name).GetValue(model, null);
if (value != null)
{
builder_def = builder_def.Set(prop.Name, value); // Not setting lists correctly
}
}
var filter = Builders<MyObj>.Filter;
var filter_def = filter.Eq(x => x.Id, model.Id);
Connection.Update(filter_def, builder_def);
return model;
}
Edit
I think my problem is related to this open bug https://jira.mongodb.org/browse/CSHARP-1984. Given that, is there any way for me to make this work in that context?
In our company we created a custom Issues app. Additionally to using this app in the web interface, we also want to be able to change the state of an issue (new, acknowledged, test, resolved, ...) automatically via git commit hooks. The basics are working fine (ie change state, add notes, ...), but we also want to change the responsibility for the current item to a specific user. In that special case, it's the creator if this item.
My first try was the following:
var appid = 1234; var itemid = 1;
var item = podio.ItemService.GetItemByAppItemId(appid, itemid);
var update = new Item {ItemId = item.ItemId};
var creator = item.CreatedBy.Id;
var resp = update.Field<ContactItemField>("responsibility");
resp.ContactIds = new List<int>{creator.Value};
//change some other fields as well
podio.ItemService.UpdateItem(update);
This throws an "Object not found" exception, because in the resp.ContactIds one must not set the UserId but the ProfileId.
I then tried to get the ProfileId of the item-creator via
podio.ContactService.GetUserContactField(creator.Value, "profile_id");
but this also throws an exception "(Authentication as app is not allowed for this method").
So how can I get an appropriate profile id for the user when I use authentication as app?
OK, I found a workaround for it, not sure, if this is possible for other scenarios, but it works for the current case.
Instead of using the C# interface for setting the ContactIds for the ContactItemField, I set the json values directly.
var appid = 1234; var itemid = 1;
var item = podio.ItemService.GetItemByAppItemId(appid, itemid);
var update = new Item {ItemId = item.ItemId};
var creator = item.CreatedBy.Id;
var resp = update.Field<ContactItemField>("responsibility");
resp.ContactIds = new List<int>(); // set to an empty list, so that resp.Values is initialized to an empty JArray
var u = new JObject { {"value", new JObject { {"type" , "user" }, {"id", creator } } } };
responsibleField.Values.Add(u); //add the new user to the Values of the field
//change some other fields as well
podio.ItemService.UpdateItem(update);
And if I set the value with type user I can use the known userid and the API on the server takes care of the lookup.
I will attempt to be as specific as possible. So we are using Sitefinity 8.1.5800, I have a couple dynamic content modules named ReleaseNotes and ReleaseNoteItems. ReleaseNotes has some fields but no reference to ReleaseNoteItems.
Release Note Items has fields and a related data field to ReleaseNotes.
So I can query all ReleaseNoteItems as dynamic content pretty quickly less than a second.
I then use these objects provided by sitefinity and map them to a C# object so I can use strong type. This mapping process is taking almost a minute and using over 600 queries for only 322 items (N+1).
In Short: I need to get all sitefinity objects and Map them to a usable c# object quicker than I currently am.
The method for fetching the dynamic content items (takes milliseconds):
private IList<DynamicContent> GetAllLiveReleaseNoteItemsByReleaseNoteParentId(Guid releaseNoteParentId)
{
DynamicModuleManager dynamicModuleManager = DynamicModuleManager.GetManager(String.Empty);
Type releasenoteitemType = TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.ReleaseNoteItems.Releasenoteitem");
string releaseNoteParentTypeString = "Telerik.Sitefinity.DynamicTypes.Model.ReleaseNotes.Releasenote";
var provider = dynamicModuleManager.Provider as OpenAccessDynamicModuleProvider;
int? totalCount = 0;
var cultureName = "en";
Thread.CurrentThread.CurrentUICulture = new CultureInfo(cultureName);
Type releasenoteType = TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.ReleaseNotes.Releasenote");
// This is how we get the releasenote items through filtering
DynamicContent myCurrentItem = dynamicModuleManager.GetDataItem(releasenoteType, releaseNoteParentId);
var myMasterParent =
dynamicModuleManager.Lifecycle.GetMaster(myCurrentItem) as DynamicContent;
var relatingItems = provider.GetRelatedItems(
releaseNoteParentTypeString,
"OpenAccessProvider",
myMasterParent.Id,
string.Empty,
releasenoteitemType,
ContentLifecycleStatus.Live,
string.Empty,
string.Empty,
null,
null,
ref totalCount,
RelationDirection.Parent).OfType<DynamicContent>();
IList<DynamicContent> allReleaseNoteItems = relatingItems.ToList();
return allReleaseNoteItems;
}
This is the method that takes almost a minute that is mapping sitefinity object to C# object:
public IList<ReleaseNoteItemModel> GetReleaseNoteItemsByReleaseNoteParent(ReleaseNoteModel releaseNoteItemParent)
{
return GetAllLiveReleaseNoteItemsByReleaseNoteParentId(releaseNoteItemParent.Id).Select(rn => new ReleaseNoteItemModel
{
Id = rn.Id,
Added = rn.GetValue("Added") is bool ? (bool)rn.GetValue("Added") : false,
BugId = rn.GetValue<string>("bug_id"),
BugStatus = rn.GetValue<Lstring>("bugStatus"),
Category = rn.GetValue<Lstring>("category"),
Component = rn.GetValue<Lstring>("component"),
#Content = rn.GetValue<Lstring>("content"),
Criticality = rn.GetValue<Lstring>("criticality"),
Customer = rn.GetValue<string>("customer"),
Date = rn.GetValue<DateTime?>("date"),
Grouped = rn.GetValue<string>("grouped"),
Override = rn.GetValue<string>("override"),
Patch_Num = rn.GetValue<string>("patch_num"),
PublishedDate = rn.PublicationDate,
Risk = rn.GetValue<Lstring>("risk"),
Title = rn.GetValue<string>("Title"),
Summary = rn.GetValue<Lstring>("summary"),
Prod_Name = rn.GetValue<Lstring>("prod_name"),
ReleaseNoteParent = releaseNoteItemParent,
McProductId = GetMcProductId(rn.GetRelatedItems("McProducts").Cast<DynamicContent>()),
}).ToList();
}
Is there any way to optimize this all into one query or a better way of doing this? Taking almost a minute to map this objects is too long for what we need to do with them.
If there is no way we will have to cache the items or make a SQL query. I would rather not do caching or SQL query if I do not have to.
Thank you in advance for any and all help you can provide, I am new to posting questions on stackoverflow so if you need any additional data please let me know.
Is there a reason why you are doing a .ToList() for the items? Is it possible for you to avoid that. In my opinion, most of the time(of the 1 minute) is taken to convert all your items into a list. Conversion from Sitefinity object to C# object is not the culprit here.
Look Arno's answer here: https://plus.google.com/u/0/112295105425490148444/posts/QrsVtxj1sCB?cfem=1
You can use the "Content links manager" to query dynamic modules relationships (both by parent -ParentItemId- or by child -ChildItemId-) much faster:
var providerName = String.Empty;
var parentTitle = "Parent";
var relatedTitle = "RelatedItem3";
DynamicModuleManager dynamicModuleManager = DynamicModuleManager.GetManager(providerName);
Type parentType = TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.ParentModules.ParentModule");
Type relatedType = TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.RelatedModules.RelatedModule");
ContentLinksManager contentLinksManager = ContentLinksManager.GetManager();
// get the live version of all parent items
var parentItems = dynamicModuleManager.GetDataItems(parentType).Where(i => i.GetValue<string>("Title").Contains(parentTitle) && i.Status == ContentLifecycleStatus.Live && i.Visible);
// get the ids of the related items.
// We use the OriginalContentId property since we work with the live vesrions of the dynamic modules
var parentItemIds = parentItems.Select(i => i.OriginalContentId).ToList();
// get the live versions of all the schedules items
var relatedItems = dynamicModuleManager.GetDataItems(relatedType).Where(i => i.Status == ContentLifecycleStatus.Live && i.Visible && i.GetValue<string>("Title").Contains(relatedTitle));
// get the content links
var contentLinks = contentLinksManager.GetContentLinks().Where(cl => cl.ParentItemType == parentType.FullName && cl.ComponentPropertyName == "RelatedField" && parentItemIds.Contains(cl.ParentItemId) && cl.AvailableForLive);
// get the IDs of the desired parent items
var filteredParentItemIds = contentLinks.Join<ContentLink, DynamicContent, Guid, Guid>(relatedItems, (cl) => cl.ChildItemId, (i) => i.OriginalContentId, (cl, i) => cl.ParentItemId).Distinct();
// get the desired parent items by the filtered IDs
var filteredParentItems = parentItems.Where(i => filteredParentItemIds.Contains(i.OriginalContentId)).ToList();
I would imagine that every release note item under a single release note would be related to the same product wouldn't it?
If so, do you need to do the GetMcProductId method for every item?
I am trying to update a row in a (typed) MongoDB collection with the C# driver. When handling data of that particular collection of type MongoCollection<User>, I tend to avoid retrieving sensitive data from the collection (salt, password hash, etc.)
Now I am trying to update a User instance. However, I never actually retrieved sensitive data in the first place, so I guess this data would be default(byte[]) in the retrieved model instance (as far as I can tell) before I apply modifications and submit the new data to the collection.
Maybe I am overseeing something trivial in the MongoDB C# driver how I can use MongoCollection<T>.Save(T item) without updating specific properties such as User.PasswordHash or User.PasswordSalt? Should I retrieve the full record first, update "safe" properties there, and write it back? Or is there a fancy option to exclude certain fields from the update?
Thanks in advance
Save(someValue) is for the case where you want the resulting record to be or become the full object (someValue) you passed in.
You can use
var query = Query.EQ("_id","123");
var sortBy = SortBy.Null;
var update = Update.Inc("LoginCount",1).Set("LastLogin",DateTime.UtcNow); // some update, you can chain a series of update commands here
MongoCollection<User>.FindAndModify(query,sortby,update);
method.
Using FindAndModify you can specify exactly which fields in an existing record to change and leave the rest alone.
You can see an example here.
The only thing you need from the existing record would be its _id, the 2 secret fields need not be loaded or ever mapped back into your POCO object.
It´s possible to add more criterias in the Where-statement. Like this:
var db = ReferenceTreeDb.Database;
var packageCol = db.GetCollection<Package>("dotnetpackage");
var filter = Builders<Package>.Filter.Where(_ => _.packageName == packageItem.PackageName.ToLower() && _.isLatestVersion);
var update = Builders<Package>.Update.Set(_ => _.isLatestVersion, false);
var options = new FindOneAndUpdateOptions<Package>();
packageCol.FindOneAndUpdate(filter, update, options);
Had the same problem and since I wanted to have 1 generic method for all types and didn't want to create my own implementation using Reflection, I end up with the following generic solution (simplified to show all in one method):
Task<bool> Update(string Id, T item)
{
var serializerSettings = new JsonSerializerSettings()
{
NullValueHandling = NullValueHandling.Ignore,
DefaultValueHandling = DefaultValueHandling.Ignore
};
var bson = new BsonDocument() { { "$set", BsonDocument.Parse(JsonConvert.SerializeObject(item, serializerSettings)) } };
await database.GetCollection<T>(collectionName).UpdateOneAsync(Builders<T>.Filter.Eq("Id", Id), bson);
}
Notes:
Make sure all fields that must not update are set to default value.
If you need to set field to default value, you need to either use DefaultValueHandling.Include, or write custom method for that update
When performance matters, write custom update methods using Builders<T>.Update
P.S.: It's obviously should have been implemented by MongoDB .Net Driver, however I couldn't find it anywhere in the docs, maybe I just looked the wrong way.
Well there are many ways to updated value in mongodb.
Below is one of the simplest way I choose to update a field value in mongodb collection.
public string UpdateData()
{
string data = string.Empty;
string param= "{$set: { name:'Developerrr New' } }";
string filter= "{ 'name' : 'Developerrr '}";
try
{
//******get connections values from web.config file*****
var connectionString = ConfigurationManager.AppSettings["connectionString"];
var databseName = ConfigurationManager.AppSettings["database"];
var tableName = ConfigurationManager.AppSettings["table"];
//******Connect to mongodb**********
var client = new MongoClient(connectionString);
var dataBases = client.GetDatabase(databseName);
var dataCollection = dataBases.GetCollection<BsonDocument>(tableName);
//****** convert filter and updating value to BsonDocument*******
BsonDocument filterDoc = BsonDocument.Parse(filter);
BsonDocument document = BsonDocument.Parse(param);
//********Update value using UpdateOne method*****
dataCollection.UpdateOne(filterDoc, document);
data = "Success";
}
catch (Exception err)
{
data = "Failed - " + err;
}
return data;
}
Hoping this will help you :)