Editing Media Properties programmatically in Umbraco (4.11) - c#

Howdie,
Having some issues with implementing a video like system in umbraco and was wondering if any uber smart people were willing to make me feel dumb(learn something) and point me in the right direction.
The problem:
As I have edited properties on the documents before I decided to create a custom media type with an int “likes” property. I would then increment this if the user hasn’t liked this video before on post back or disable the button if they have.
I imagined doing something like this:
Document doc = new Document(mediaItemId);
int curValue = doc.getProperty("likes").Value;
doc.getProperty("likes").Value = (curValue + 1);
doc.Save();
http://our.umbraco.org/wiki/reference/api-cheatsheet/modifying-document-properties
The issue arose when I discovered that umbraco treats the document types and media types differently and the code I was using previously (insert code) no longer works.
Been hacking away for some time and the only two possibilities I have left I don't really want to do. The first being to create a new media item, copy over the properties and then "save over" the original in the db, the other is to create a custom table and not worry about the umbraco API.
http://our.umbraco.org/documentation/Reference/management/Media/
I am sure there has to be an easier way to do this (hoping I am being thick).
Thanks for taking the time to read and respond!

you should be able to exactly what you've already done but replace the line:
Document doc = new Document(mediaItemId);
with
Media doc = new Media(mediaItemId);
You will of course have to make sure that your Media type has a "likes" property. This can be done in the "Settings > Media types" section of Umbraco in the same way that you can add properties to document types.

Related

Revit : Get All ViewSheet is very slow

for a plugin I need to get all the viewsheet in the rvt file and display informations from them in an xaml dialog
but my process is very very slow the first time I use it
(with the debuger : 500 ms for 83 viewplan , it is very slow without the debuger too)
(if I execute my code again, the execution is istantaneous)
my code bellow
can you help me ?
thanks in advance
Luc
protected IEnumerable<Element> GetAllEl(Document document)
{
var filteredElementCollector = new FilteredElementCollector(document);
filteredElementCollector = filteredElementCollector
.OfCategory(BuiltInCategory.OST_Sheets)
.WhereElementIsNotElementType()
.OfClass(typeof(ViewSheet));
var fcElements = filteredElementCollector.ToElements();
return fcElements;
}
I do not think there is currently a known generic solution for that problem.
Here is a recent discussion with the development team on this:
Question: for a given element id, we need to find the list of sheet ids displaying it.
Current solution: we loop through all the sheets and views and use FilteredElementCollector( doc, sheet.Id)
With the results from that, we perform one more call to FilteredElementCollector( doc, view.Id) and look for the element id.
Issue: the current solution takes a lot of time and displays a Revit progress bar saying Generating graphics.
Is there any better way to know if a given element id is available in the sheet or not?
For example, something like this would be very useful:
getAllSheets(ElementId) // returns array of sheet id
hasGuid(ElementId,sheetId) // return true/false
Does the API provide any such methods, to check whether a given ElementId is available in the sheet?
Answer: So the goal is to find a view that displays a particular element on a sheet?
Many model elements could be visible on multiple views, while most annotation elements are typically present only in one view.
What type of elements are you checking for?
And what will you do with that info?
Response: the goal is to find a view that displays a particular element on a sheet.
It can be any type of element.
Answer: Here are some previous related discussions:
Determining Views Showing an Element
The inverse, Retrieving Elements Visible in View
Response: The problem is that the first call to FilteredElementCollector( doc, viewId ) shows generating graphics in the progress bar.
Only the first time search does so. The second time, search on the same view has no issues with performance.
Answer: The first time is slow because in order to iterate on the elements visible in a view the graphics for that view must be generated.
I can't think of a workaround to get a precise answer.
You might be able to skip sheets which don't have model views in their viewport list to save a bit of time.
Some sheets may only have drafting views and schedules and annotations.
The development team provided a very helpful suggestion which helped work around the generating graphics call in a special case,
to Loop through sheets - generating graphics.
Maybe you can optimise in a similar manner for your specific case?
I think you may be over-filtering the ElementCollector. In my add-in, I just use this code to get the view sheets: new FilteredElementCollector(_doc).OfClass(typeof(ViewSheet));

SalesForce - Get all the fields of an object using .Net SDK or Api

We have our system from where we want to push the records (e.g. Contact, Account, Opportunity, etc.) to SalesForce.
To achieve this, we have used ForceToolKit for .Net. We are able to insert\update the records successfully using the ForceToolKit functions.
Example:
dynamic contact = new ExpandoObject();
contact.FirstName = "FirstName";
contact.LastName = "Last";
contact.Email = "test#test.com";
contact.MobilePhone = "1234567890";
var successResponse = await forceClient.CreateAsync("Contact", contactList);
The Issue we are facing is as mentioned below.
In our source system, we have few custom fields which are not standard field in SalesForce and it can be different for different users.
So, first we have to map the custom fields between our source system and the SalesForce.
We want to fetch all the fields of SalesForce object in order to map the fields.
We are unable to find any function in ForceToolkitForNet.
As described here, we have tried QueryById function by using the dynamic return type, but it is throwing an exception.
var contactFields = await forceClient.QueryByIdAsync<dynamic>("Contact", successResponse.Id);
Exception: "SELECT FROM Contact where Id = '{contactId}' Incorrect syntax near FROM".
What are the ways to get the fields of any object of SalesForce.
Can anyone help us on getting the fields of an object using SalesForceToolkit or SalesForceApi?
SOQL doesn't have a SELECT * FROM Account concept, you need to learn the fields beforehand. You have few options here.
You can use "describe" calls. I've recently answered similar question but it was about REST API: https://stackoverflow.com/a/48436870/313628, I think your solution is SOAP-based.
If you'd be doing this by hand...
Start here: https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_calls_list_describe.htm
List of all objects visible to your user: describeGlobal()
Get details (incl field names) for one object: describeSobject() or more: describeSobjects()
As you're using the toolkit - there's a chance these methods already are in there somewhere. Experiment a bit. Between the C# examples under the links I gave you and the library you should be able to figure something out.
I mean I'm naive but just searching the repo for "describe" looks promising: https://github.com/developerforce/Force.com-Toolkit-for-NET/search?utf8=%E2%9C%93&q=describe&type=, maybe this example
There's also a way to not learn this info at runtime but consume a WSDL file generated out of Salesforce with all fields & generate C# code out of it. The downside is that you'd need to regenerate it every time you want to support new object/field in your app. Read about "Enterprise WSDL" to get started.
Last but not least - there are more or less friendly tools that dump the Salesforce metadata. i'm a fan of https://www.datasert.com/products/realforce/ but just have a look around. Hell, even exporting some records with DataLoader will give you all field names if that's all you need.

Regarding WPF, need advice on data sources and data binding

I am not new to WPF, but I am still a rookie. Let's say, I want to build an application which stores data about a person in an unique and separate file, and not in a database, sort of, like, Notepad. My application should do the following things.
It should be able to save a person's info in an unique file.
It should be able to open an user specified file and auto fill the properties/form.
How do I achieve this? Is the XML binding only way to achieve this, or is there an any other alternative? What I mean is, If I use XML binding I can write code which will enable the user to open and save different XML files, but I also read that binding to XML should be avoided from the architecture perspective. So, is there an alternative solution for my problem?
I think if you try doing the stuff by using a Reading and writing the things to a CSV(Comma separated values) file(If not planning to implement databases) then you can achieve what you wanted.
Also if you are planning to have a separate file for each user its not at all a good idea.
Its not possible to explain everything thing here . So please have a look to link posted below , in which it has explained in detail how to achieve Reading and Writing to a csv file .
This example has been posted from here for getting full detail please look to following link Reading and writing to a csv file
Apparently your requirement is to save person details into a unique file. If you really want to use that approach, one option is using XMLSerialization.
You can create your normal person object for data binding.
When you want to save data into the specific person's file you can serialize the object and save file with a proper name (person id or so)
When you want to get Person data back from the file, you can deserialize the it directly to a person object.
// Serialize and write to file
Person person = myPerson;
var serializer = new XmlSerializer(person.GetType());
using (var writer = XmlWriter.Create("person1.xml"))
{
serializer.Serialize(writer, person);
}
// Deserialize back to an instance
var serializer = new XmlSerializer(typeof(Person));
using (var reader = XmlReader.Create("person1.xml"))
{
var person= (Person)serializer.Deserialize(reader);
}
For saving user data, such as sessions and settings. There are plenty of ways you can do this.
Saving to data to txt files. See here.
Saving data to a database. See here.
My personal favourite, saving to the Settings file. See here.
These are only some of the ways you can save data locally.
Note that I mentioned saving data to a database because it is something that you shouldn't completely knock, especially if you will be saving lots of data.
To answer your question more directly, I would suggest that you go with option 3. For relatively small sets of data, like user info and user settings, it would be your best bet to save them to the built in Settings file. It's dead easy.
Good luck!

Read-Only merge fields in Word C#

I have a requirement to create read-only merge fields in Word.
I've already tried using the Locked property which can be seen below.The description of this property states - When a field is locked you cannot update field results which sounds like a perfect fit for my problem but this doesn't seem to be working
Below is the code i use to add the merge field to MS Word:
using Word = Microsoft.Office.Interop.Word;
Word.Range currentRange = Globals.ThisAddIn.Application.Selection.Range;
Word.MailMerge merge = Globals.ThisAddIn.Application.ActiveDocument.MailMerge;
merge.Fields.Add(currentRange, selectedNode.LocalName).Locked = true;
Once I run the code above and the field is created in Word, I am still able to right click it and select "Edit Field" where I can potentially rename the field or perform other changes without getting any errors or preventions from Word.
If anyone implemented something like this before, please share your knowledge.
Here is some insight on the technologies:
The solution is targeted at MS Word Office 2010
It must be written in .NET C# 3.5
Cannot use Open Xml SDK, the fix must be performed using Office Interop
The solution must achieve the desired goals without making the whole document read-only
Thank you for the replies, however I needed to only make the merge fields read-only the rest of the document should still stay as is.
A colleague of mine found a nice way to achieve what I was looking for, just sharing it in case someone else may need this functionality:
All you need to do is create a ContentControl object and add your merge field to the content control.
Set the LockContents property to true. This property is used to determine whether a user is allowed to edit the contents of a content control.
using Word = Microsoft.Office.Interop.Word;
object missing = System.Type.Missing;
Word.Selection PosRange = Globals.ThisAddIn.Application.Selection;
Microsoft.Office.Interop.Word.ContentControl cntCtrl;
cntCtrl = PosRange.Range.ContentControls.Add(Microsoft.Office.Interop.Word.WdContentControlType.wdContentControlRichText, ref missing);
object fldType = Microsoft.Office.Interop.Word.WdFieldType.wdFieldMergeField;
object fldText = "Employee";
Microsoft.Office.Interop.Word.Field fld = cntCtrl.Range.Fields.Add(cntCtrl.Range, ref fldType, ref fldText);
cntCtrl.LockContents = true;
In the image below a merge field is hosted inside a content control, note users are now unable to edit the field
Using the Locked property will only prevent the value of the field from changing, which I'm assuming is not what you want.
The only way I know to prevent the field code from changing is to protect the document. The fields themselves should still be updatable.

Making a Simple Database Program in C#

I'm currently writing a simple text analysis program in C#. Currently it takes simple statistics from the text and prints them out. However, I need to get it to the point where in input mode you input sample text, specifying an author, and it writes the statistics to a database entry of that specific author. Then in a different mode the program will take text, and see if it can accurately identify the author by pulling averages from the DB files and comparing the text's statistics to sample statistics. What I need help with is figuring out the best way to make a database out of text statistics. Is there some library I could use for this? Or should I simply do simple reading and writing from text files that I'll store the information in? Any and all ideas are welcome, as I'm struggling to come up with a solution to this problem.
Thanks,
PardonMyRhetoric
You can use and XmlSerializer to persist your data to file really easily. There are numerous tutorials you can find on google that will teach you how in just a few minutes. However, most of them want to show you how to add attributes to your properties to customize the way it serializes, so I'll just point out that those aren't really necessary. So long as you have the [Serializeable] tag over your class all you need is something that looks like this to save:
void Save()
{
using (var sw = new StreamWriter("somefile.xml"))
(new XmlSerializer(typeof(MyClass))).Serialize(sw, this);
}
and something like this in a function to read it:
MyClass Load()
{
XmlSerializer xSer = new XmlSerializer(typeof(MyClass));
using (var sr = new StreamReader("somefile.xml"))
return (MyClass)xSer.Deserialize(sr);
}
I don't think in this stage you'll need a database. Try to select appropriate data structures from the .NET framework itself. Try to use dictionary or lists, don't use arrays for this, and the methods you write will become simpler. Try to learn LINQ - it's like queries to database, but to regular data structures. When you'll get this and the project will grow, try to add a database.

Categories