Manipulate umbraco content using a console application - c#

This is a noob question but I'm searching for some time and can't find any useful information.
I need to develop a rotine (console application) that will read and write content into a umbraco site. I've already read that you can do that with web forms and mvc application.
But I need to use umbraco like an external source. I need to do something like we do with Word documents. For example: open the file, read the file, write some things and save it.
I've already installed the API using
PM> Install-Package UmbracoCms -Pre
Some things I've already read:
http://nishantwork.wordpress.com/2012/09/27/umbraco-create-custom-content-node-in-umbraco-by-c/
https://github.com/sitereactor/umbraco-console-example
What is the best to achieve that? I don't know how to do it exactly...

You can create an Umbraco node (document), write to it and save it from a console application. Umbraco is basically a bunch of .Net libraries:
//Get the type you would like to use by its alias and the user who should be the creator of the document
DocumentType dt = DocumentType.GetByAlias("Textpage");
User author = User.GetUser(0);
//create a document with a name, a type, an umbraco user, and the ID of the document's parent page. To create a document at the root of umbraco, use the id -1
Document doc = Document.MakeNew("My new document", dt, author, 1018);
// Get the properties you wish to modify by it's alias and set their value
doc.getProperty("bodyText").Value = "<p>Your body text</p>";
doc.getProperty("articleDate").Value = DateTime.Now;
//after creating the document, prepare it for publishing
doc.Publish(author);
//Tell umbraco to publish the document
umbraco.library.UpdateDocumentCache(doc.Id);
See:
http://our.umbraco.org/wiki/reference/api-cheatsheet/creating-a-document
http://our.umbraco.org/wiki/reference/api-cheatsheet/modifying-document-properties

Just to help anyone with the same issue. I'm find out a web service in umbraco and i'm currently using that (until now for reading information only, but as far as I know we can write infomation also). Altought there's little documentation is easy to use.
But to use that you need to set <webservices enabled="False"> in umbracoSettings.config . This fie is in the folder Config inside umbraco.
We have to set user rights into the webservices node also to allow the user to use the web service
DocumentServiceReference.documentServiceSoapClient client = new DocumentServiceReference.documentServiceSoapClient();
client.WebservicesEnabled();
DocumentServiceReference.ArrayOfDocumentCarrier documents = client.readList(parentId, username, password);
foreach (DocumentServiceReference.documentCarrier doc in documents)
{
DocumentServiceReference.ArrayOfDocumentProperty properties = doc.DocumentProperties;
foreach (DocumentServiceReference.documentProperty property in properties)
{
string key = property.Key;
string value = property.PropertyValue.ToString();
}
}

Related

How to download a file from a shared folder in asp.net using <a href>?

Background:
There is an asp.Net MVC application, which I am currently re-creating without using MVC.
In the MVC application, the <a> elements that enables users to download a document is like:
download
and it works when I click download, because I could use a method like below in MVC:
public async Task<IActionResult> Download(string path)
{
var memory = new MemoryStream();
using (var stream = new FileStream(path, FileMode.Open))
{
await stream.CopyToAsync(memory);
}
memory.Position = 0;
return File(memory, GetContentType(path), Path.GetFileName(path));
}
Note that there is an HTML table with 500+ rows in the page, some data has a file to be downloaded and for only those rows, the href link exists in a specific cell.
Here, when I try to visit http://myapplication/api/file/2187/filter.jpg, I could see the link exists.
Problem:
I couldn't use the same Download method in .net only Application because IActionResult looks for the namespace Microsoft.AspNet.MVC. Tried to set the <a> element in my asp.net application like below:
download
However, this does not work in Chrome giving me the error: Not allowed to load local resource
I couldn't find a way to create a link on http for the file like the way it is in the MVC application. How can I enable a link in the application like: http://myapplication/api/file/2187/filter.jpg to use in the href?
Note: The files to be downloaded are located in a Shared folder, can't move them into my local PC or can't import them inside the project etc..
Note 2: There should be no page-refresh after downloading the file.
Any help or advice should be appreciated! Thanks.
File Paths Should Not Be Accepted From URL or Query String:
I would strongly recommending not using filepath in the querystring or URL.
I see in the code that you are not validating the filePath and directly downloading a file. This can be very dangerous. People can try downloading web.config or any other file on your web server if the permissions are not set correctly or if there is no other mechanism to block such request.
I would strongly recommend using Indirection for file download.
What is Indirection ?
In indirection, you would create an identifier for the file. It may be a GUID as well.
Then you can accept this GUID through QueryString or through URL.
Then in your action you would map it to right file and then download it.
Code Example:
Below code example, uses file ID.
When the file id is passed, it tries to get the file details in CustomDocumentObj.
These details contains actual file path.
You can then perform validations to check if this is the application related file and if your application allows to download that file.
public class ServiceController : Controller
{
public ActionResult DownloadFile(string id)
{
CustomDocumentObj document = new CustomDocumentObj(Int32.Parse(id));
// OPTIONAL - validation to check if it is allowed to download this file.
string filetype = Helpers.GetMimeType(document.FilePath);
return File(document.FilePath, filetype, Path.GetFileName(document.FilePath));
}
}
Then in URL it can be something like below:
Download File
Refer this blog for further details.

c# HtmlAgilityPack class inside many classes, need to check if class exist

I am working on this for days without a solution.
For example, I have this link: https://www.aliexpress.com/item/32682673712.html
I am trying to check if the Buy now button disable
if I have this line inside the DOM : Buy Now
the problem is that this line inside a class that inside a class and so on...
I know there is an option to get a specific node with HtmlAgilityPack But I didn't succeed
var nodes = doc.DocumentNode.SelectNodes("//div[(#class='next-btn next-large next-btn-primary buynow disable')]/p");
but I don't get anything
I tried to get the entire dom and then search with inside but didn't succeed
var getHtmlWeb = new HtmlWeb();
var document = getHtmlWeb.Load(url);
I just got the html and not the DOM
another thing I tried to do is:
var Driver = new FirefoxDriver();
Driver.Navigate().GoToUrl(url);
string pagesource = Driver.PageSource;
and it did works! but this solution open the browser and I don't want that (I am running over many links)
Please help a frustrated guy :)
thanks.
This is happening because the buynow button is being loaded via JavaScript.
If you open network tab in chrome dev tools, you will notice that the page is making a call to some api to load the product information.
The url with json data for the product looks like this:
https://www.aliexpress.com/aeglodetailweb/api/store/header?itemId=32682673712&categoryId=100007324&sellerAdminSeq=202460364&storeNum=720855&minPrice=4.99&maxPrice=4.99&priceCurrency=USD
You will most probably have to send same headers as chrome is sending for the request in order to load the api endpoint in your app.

Apache SOLR and C# windows application

Am newbie to Apache SOLR 7.4. Am trying to upload XML file to remote server where the SOLR 7.4 is hosted.I need to update the collection with new XML file uploaded to the server. How can I re-index the collection ?
Things I have tried like using Simple Post Tool, CURL command with update etc.
If you're writing a C# application, using SolrNet is the suggested way. To upload a file to Solr Cell (which is what the module that extracts content from most file types is called), you can follow the example given in the manual. To parse the file for content to see how it behaves with the file you've uploaded:
ISolrOperations<Something> solr = ...
using (var file = File.OpenRead(#"test.pdf")) {
var response = solr.Extract(new ExtractParameters(file, "some_document_id") {
ExtractOnly = true,
ExtractFormat = ExtractFormat.Text,
});
Console.WriteLine(response.Content);
}
Set ExtractOnly to false to index the content, and use Fields to set additional field values (i.e. an id field, etc.).

how to do API calls of Kentico using ASP.NET MVC?

I'm struggling with API calls of Kentico forms using ASP.NET MVC, so that I can use AngularJS to display the return data (JSON format).
Specifically, my client is using Kentico on their server to create data using "Forms" on Kentico and I want to get the records stored in these forms via API calls using ASP.NET MVC. What I'm thinking is that in the general section of the "Forms", I see the "Form code name" showing that "Code name is a string identifier of the object that can be used by developers in API calls or URLs". But it seems to be there's no good example of it on internet. Keep trying to search it but no luck. I also tried to access data directly in SQL Server in which kentico stores the data. But the table's name that Kentico uses in SQL Server to store the data is different from the ones in "Forms" or "Custom tables" in Kentico.
Hope someone can show me how to do it and I really appreciate it. Thanks in advance.
There is a very good example in the official documentation of Kentico.
Please note that Forms have been renamed a few times in the past (they were called BizForms and On-Line forms) that's the reason why the code below references CMS.OnlineForms and uses BizFormInfoProvider. It might also very well be the reason why you didn't find any good example :)
The example below shows how to retrieve Form's definition (metadata), get all the data and iterate through it.
using CMS.OnlineForms;
using CMS.DataEngine;
using CMS.SiteProvider;
using CMS.Helpers;
...
// Gets the form info object for the 'ContactUs' form
BizFormInfo formObject = BizFormInfoProvider.GetBizFormInfo("ContactUs", SiteContext.CurrentSiteID);
// Gets the class name of the 'ContactUs' form
DataClassInfo formClass = DataClassInfoProvider.GetDataClassInfo(formObject.FormClassID);
string className = formClass.ClassName;
// Loads the form's data
ObjectQuery<BizFormItem> data = BizFormItemProvider.GetItems(className);
// Checks whether the form contains any records
if (!DataHelper.DataSourceIsEmpty(data))
{
// Loops through the form's data records
foreach (BizFormItem item in data)
{
string firstNameFieldValue = item.GetStringValue("FirstName", "");
string lastNameFieldValue = item.GetStringValue("LastName", "");
// Perform any required logic with the form field values
// Variable representing a custom value that you want to save into the form data
object customFieldValue;
// Programatically assigns and saves a value for the form record's 'CustomField' field
item.SetValue("CustomField", customFieldValue);
item.SubmitChanges(false);
}
}
UPDATE:
The example above assumes that you're using the API from within the running Kentico instance. If you want to use Kentico API (DLLs) from an external application please follow the steps I described in another answer.
You also asked about the site identifier (siteId or siteName params of the BizFormInfoProvider.GetBizFormInfo() method). They refer to the SiteInfo object in Kentico (DB table CMS_Site). You can find site name if you navigate to Site->Edit site->General->Site code name.
If you don't want to use Kentico DLLs there is another option - using Kentico REST endpoint.

Using the Azure API, how do I list and add virtual directories to a website?

I am trying to add a Virtual Directory to an Azure Web Site from a WinForms Application using the Azure API. I can enumerate the WebSites on in my webspace, but I cannot find a method that allows me access to the Virtual Directories in the WebSite.
Here is my code:
string certPath = Properties.Settings.Default.AzureCertificatePath;
string certPassword = Properties.Settings.Default.AzureCertificatePassword;
string subscriptionId = Properties.Settings.Default.AzureSubscriptionId;
var cert = new X509Certificate2(certPath, certPassword, X509KeyStorageFlags.MachineKeySet);
var cred = new CertificateCloudCredentials(subscriptionId, cert);
using (var client = new WebSiteManagementClient(cred))
{
var spaces = client.WebSpaces.List();
foreach (var space in spaces)
{
Console.WriteLine("Space: {0}", space.Name);
var sites = client.WebSpaces.ListWebSites(space.Name, new WebSiteListParameters {PropertiesToInclude = { "Name" } }); ***// Where do I find out what properties can be included in this array?***
foreach (var site in sites)
{
***// What goes here to show the virtual directories in this specific website??????***
}
}
}
I found that the Azure web services API does not offer access to the virtual directories/applications on a web app, although the underlying REST API's that it uses does.
Luckily, the management API is open source (I wanted to get the v3.0.0.0 of the website management API, matching what I had NuGet'd, which I found here: https://github.com/Azure/azure-sdk-for-net/commits/master?page=79) so with a little perseverance and messing about with .targets files and NuGet references, you can get the source code of the WebSiteManagement project into your solution instead of the referenced DLL that you likely downloaded from NuGet.
From there, if you go into your client.WebSites.GetConfiguration method, stick a breakpoint in and capture the HTTP response returned - you'll see that in the JSON the VirtualApplications on your website are indeed there.
From there, you can edit your copy of the source code to expose those object structures out, much the same way that other object structures are mapped out of the JSON (e.g. HandlerMappings).
Likewise for updating them, you need to add the VirtualApplications (in the ewact same format) into the Microsoft.WindowsAzure.Management.WebSites.Models.WebSiteUpdateConfigurationParameters, and pass that into client.WebSites.UpdateConfiguration (which you will also need to amend to map your VirtualApplications object structure back into JSON in the same format).
Works great for me doing it this way.
Note/Disclaimer: The GitHub site documentation does mention that much of the source code was autogenerated, and that you shouldn't really go editing that code, instead raise an issue on the project about getting it sorted. I didn't have the time to do this and needed an immediate way of getting it working with my local copy of the code only, so my solution does, as you'll note when you look a the source, involve adding to that auto-gen'd code. It works great, but I should in good conscience point you to the project owner's warnings about tinkering with the auto-gen'd code.

Categories