I'm looking for the best approach for storing strings in kentico and accessing them programmatically similar to how you would access app.config settings.
Scenario:
I wish to create an ITask, which when executed will generate a number of HTML templates. I would allow entry of the text fields via Kentico. The templates are backbone templates.
My initial thought would be to store them in UI Culture and then access them via the task but I'm having some difficulty doing this as it's a scheduled task I don't have access to the HttpContext.
Potentially I should be storing these values in custom settings?
so i found the answer.
// ResHelper
using CMS.GlobalHelper;
using CMS.SiteProvider;
// Get culture ID from query string
var uiCultureID = QueryHelper.GetInteger("UIcultureID", 0);
// Get requested culture
var ui = UICultureInfoProvider.GetSafeUICulture(uiCultureID);
var dui = UICultureInfoProvider.GetUICultureInfo(CultureHelper.DefaultUICulture);
var s = ResHelper.GetString("myculturevalue.test", dui.UICultureCode);
for those interested in the task, take a look here http://devnet.kentico.com/Blogs/Martin-Hejtmanek/June-2010/New-in-5-5-Provide-your-classes-from-App_Code.aspx
thanks
Related
The following code is the only way I found so far to update an object using the Microsoft Graph Client Library
Scenario:
Load an exisiting object (an organization)
Modify a value (add entry in securityComplianceNotificationPhones)
Send the update
Code
var client = new GraphServiceClient(...);
var org = client.Organization["orgid"].Request().GetAsync().Result;
var secPhones = new List<string>(org.SecurityComplianceNotificationPhones);
secPhones.Add("12345");
var patchOrg = new Organization();
patchOrg.SecurityComplianceNotificationPhones = secPhones;
var orgReq = new OrganizationRequest(
client.Organization[org.Id].Request().RequestUrl,
client, new Option[] {});
orgReq.UpdateAsync(patchOrg).Wait();
I needed to use the patchOrg instance because of two things:
The Graph API documentation states
"In the request body, supply the values for relevant fields that
should be updated. Existing properties that are not included in the
request body will maintain their previous values or be recalculated
based on changes to other property values. For best performance you
shouldn't include existing values that haven't changed."
If you actually do include existing values that haven't changed
(i.e. assginedLicenses) the request fails, if those existing values
are readonly.
My question is: Is/will there be a more straightforward way of updating existing objects like for example in the Azure ActiveDirectory GraphClient? Just for comparison, the same scenario in Azure Active Directory Graph
var client = new ActiveDirectoryClient(...);
var org = client.TenantDetails.GetByObjectId("orgid").ExecuteAsync().Result;
org.SecurityComplianceNotificationPhones.Add("12345");
org.UpdateAsync().Wait();
The Graph client library model is slightly different from the older SDK model the AAD client library you linked. The older model passed around objects that tried to be a bit smarter and reason about which properties were changed, only sending those. One of the main drawbacks of this model was that the library made many more service calls in the background and had a much heavier payload in each call since ExecuteAsync() would often need to retrieve every object in the request builder chain. The newer library does require the developer to do more explicit reasoning about what data is being passed but also gives greater control over network calls and payload. Each model has its tradeoffs.
To accomplish what you want, here's the approach I would recommend instead of creating a second org object altogether:
var client = new GraphServiceClient(...);
var orgRequest = client.Organization["orgid"].Request();
var org = orgRequest.Select("securityComplianceNotificationPhones").GetAsync().Result;
var secPhones = new List<string>(org.SecurityComplianceNotificationPhones);
secPhones.Add("12345");
org.SecurityComplianceNotificationPhones = secPhones;
orgRequest.UpdateAsync(org).Wait();
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.
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();
}
}
I have a SPItemEventReceiver that does nothing else than notify another HTTP server at a given IP and Port abouth the events using POST requests.
The HTTP server runs on the same computer as sharepoint, so I used to send the notification at localhost and a fixed Port number. But since the eventreceiver can be called in other servers in the serverfarm, localhost:PORT will not be available then.
So, everytime my HTTP server starts, it needs to save its IP address and Port somewhere in SharePoint where all EventReceivers have access, no matter on what server they are called.
What would be a good place to store such globally available information?
I tought about SPWebService.ContentService.Properties , but I'm not really sure if that's a good idea. What do you think?
Well, if you are using Sharepoint 2010 I would consider store those values in the property bag. Using client object model or even Javascript/ECMAScript Client Object Model. These codes maybe help you.
using (var context = new ClientContext("http://localhost"))
{
var allProperties = context.Web.AllProperties;
allProperties["testing"] = "Hello there";
context.Web.Update();
context.ExecuteQuery();
}
Or using javascript:
function getWebProperty() {
var ctx = new SP.ClientContext.get_current();
var web = ctx.get_site().get_rootweb();
this.props = web.get_allProperties();
this.props.set_item(“aProperty”, “aValue”);
ctx.load(web);
ctx.executeQueryAsync(Function.createDelegate(this, gotProperty), Function.createDelegate(this, failedGettingProperty));
}
function gotProperty() {
alert(this.props.get_item(“aProperty”));
}
function failedGettingProperty() {
alert("failed");
}
Sources:
https://sharepoint.stackexchange.com/questions/49299/sharepoint-2010-net-client-object-model-add-item-to-web-property-bag
https://www.nothingbutsharepoint.com/sites/devwiki/articles/Pages/Making-use-of-the-Property-Bag-in-the-ECMAScript-Client-Object-Model.aspx
There are actually several ways of saving configuration values in SharePoint:
Property Bags of SharePoint objects SPWebApplication, SPFarm,SPSite, SPWeb, SPList, SPListItem`
A "configuration" list in SharePoint - just a regular list you might set to Hidden = TRUE
The web.config file - specifically the <AppSettings>
Wictor Wilen actually explains the 6 ways to store settings in SharePoint.
As you are talking about an external process trying to save its settings somewhere, generally I would recommend the web.config, but each change in the web.config would lead to an IISRESET making it not a good option. I would strongly advise to use either a property bag (e.g. the SPWebApplication.Properties bag) or a hidden list in your favorite web site. You would set the property bag like so:
SPWebApplication webApplication = ...
object customObject = ...
// set value in hashtable
webApp.Add("MySetting", customObject);
// persist the hashtable
webApp.Update();
See what is cool about this? You can actually store an object with the web application which could contain multiple settings as long as you keep your object serializable.
I am working on a web application that will be going live soon, and I am now trying to figure out the best way for handling sending email from the application. I understand completely HOW to send email from the application using the MailMessage and SmtpClient classes, however my question is from a different angle. My main purpose at my job before this project was support of old applications that had been developed before my time. In these applications, when they needed to send email, they hard coded any of the messages into the actual message with all of the HTML tags embeded directly into the C# code.
The application that I am working on will have a template for the emails to be sent in, as a sort of styling container, and the different messages will be embeded into the main content div's of the template. I would like to avoid hardcoding these templates in this application, so I have been trying to figure out the best way to layout my project. I have thought of using a t4 template, and reading the different t4's into the application and applying a String.Format with the specified parameters to add names/emails to the messages to be sent. However, I am not sure this is the best way to do it.
My other idea was to define a class for each type of message, however this would end up hardcoding messages again, which as I said I don't want to do.
My question is, how have you approached this in the past? What worked, and what didn't and for what reasons? I have looked all over online, but either the only content out there is on HOW to send the message, or I have not used the right Google power words.
I do it this way:
Code it the usual way with ViewModel and Razor Template
By creating the e-mail, use http://razorengine.codeplex.com/ to load and parse the template
Be aware to not use Html and Url helper if you want to send e-mails in a thread, because they rely on HttpContext which you don't have in that case. Build your own helpers if needed.
For example, if you have a ViewModel Car in your application which is displayed somewhere, you could also use this ViewModel as #model in a Razor Template for e-mail.
I've had to do this on a couple of occasions. I originally used the ASP.Net template engine based on I think a Rick Strahl blog post. It worked but there was always some issue I was banging my head against.
I switched to using the NVelocity template engine and found it a really simple way to create and maintain email templates. There are a number of other template engines and I suspect next time I might have a serious look at the Razor engine.
The code for merging values into the template:
private string Merge(ManualTypeEnum manualType, Object mergeValues)
{
var body = "";
var templateFile = string.Format("{0}MailTemplate.vm", manualType);
var velocity = new VelocityEngine();
var props = new ExtendedProperties();
props.AddProperty("file.resource.loader.path", Config.EmailTemplatePath);
velocity.Init(props);
var template = velocity.GetTemplate(templateFile);
var context = new VelocityContext();
context.Put("Change", mergeValues);
using (var writer = new StringWriter())
{
template.Merge(context, writer);
body = writer.ToString();
}
return body;
}
The values to merge are passed as an anonymous object, and can include various types including lists etc e.g.
var emailBody = Merge(newDocument.ManualType, new
{
ManualType = newDocument.ManualType.ToString(),
Message = change.Message,
NewTitle = newDocument.Title ?? "",
NewVersion = newDocument.Version ?? "",
Contact = From,
Changes = change.ToList(),
});