Adding blog post by API and sort by category is not working in Sitefinity backend.
Hi,
I'm using Sitefinity API to add Blog post and also assigning this blog post to Category & Tags programmatically, after import when I check he post added to the system, everything looks fine but sort by Category is not working and sort by Tags are working fine.
Here is my sample code:
private void CreateBlogPost(Guid blogPostId, Blog parentBlog, Lstring blogPostTitle, Lstring blogPostContent, string postDate, string authorName, List<string> tagNames, List<string> categories)
var blogManager = new BlogsManager();
//The Blogs item is created as a master. The masterBlogPostId is assigned to the master.
var blogPost = blogManager.CreateBlogPost(blogPostId);
//Set the properties of the blog post.
blogPost.Parent = parentBlog;
blogPost.Title = blogPostTitle;
blogPost.Content = blogPostContent;
//custom field
blogPost.SetValue("AuthorName", authorName);
blogPost.DateCreated = DateTime.Parse(postDate);
blogPost.PublicationDate = DateTime.Parse(postDate);
blogPost.ExpirationDate = null;
//blogPost.LastModified = DateTime.Parse(postDate);
blogPost.UrlName = Regex.Replace(blogPostTitle.ToLower(), @"[^\w\-\!\$\'\(\)\=\@\d_]+", "-");
//Recompiles and validates the url of the blog.
blogManager.RecompileAndValidateUrls(blogPost);
//Assign category & tags
AssignContentToTaxonomy(tagNames, categories, blogPost, blogManager);
DateTime postPublishDate = DateTime.MinValue;
if (DateTime.TryParse(postDate, out postPublishDate))
blogManager.Lifecycle.PublishWithSpecificDate(blogPost, postPublishDate);
blogManager.SaveChanges();
else
//Publish the Blogs item. The published version acquires new ID.
var bag = new Dictionary<string, string>();
bag.Add("ContentType", typeof(BlogPost).FullName);
WorkflowManager.MessageWorkflow(blogPostId, typeof(BlogPost), null, "Publish", false, bag);
private void AssignContentToTaxonomy(List<string> tagNames, List<string> categories, BlogPost blogPost, BlogsManager blogsManager)
if (blogPost != null)
//assign blog post to taxonomy category
if (categories != null && categories.Any())
foreach (var category in categories)
if (!string.IsNullOrEmpty(category))
var categoryId = GetCategoryId(category);
blogPost.Organizer.AddTaxa("Category", categoryId);
//assign blog post to taxons
if (tagNames != null && tagNames.Any())
foreach (var tagName in tagNames)
var categoryId = GetTaxonId(tagName);
blogPost.Organizer.AddTaxa("Tags", categoryId);
blogsManager.SaveChanges();
private Guid GetCategoryId(string name)
var taxonomyManager = TaxonomyManager.GetManager();
//Get the Categories taxonomy
var categoryTaxonomy = taxonomyManager.GetTaxonomies<HierarchicalTaxonomy>().SingleOrDefault(s => s.Name == _thfBlogMainCategory);
if (categoryTaxonomy == null)
categoryTaxonomy = taxonomyManager.CreateTaxonomy<HierarchicalTaxonomy>();
categoryTaxonomy.Title = _thfBlogMainCategory;
categoryTaxonomy.Name = _thfBlogMainCategory;
categoryTaxonomy.TaxonName = _thfBlogMainCategory;
else
//check if taxon already exist
var categoryTaxa = categoryTaxonomy.Taxa.Where(t => t.Title.ToString().ToLower() == name.ToLower()).FirstOrDefault();
if (categoryTaxa != null)
return categoryTaxa.Id;
//Create a new HierarchicalTaxon if not found
var taxon = taxonomyManager.CreateTaxon<HierarchicalTaxon>();
//Associate the item with the hierarchical taxonomy
taxon.Taxonomy = categoryTaxonomy;
taxon.Name = Regex.Replace(name.ToLower(), @"[^\w\-\!\$\'\(\)\=\@\d_]+", "-");
taxon.Title = name;
taxon.UrlName = Regex.Replace(name.ToLower(), @"[^\w\-\!\$\'\(\)\=\@\d_]+", "-");
//Add it to the list
categoryTaxonomy.Taxa.Add(taxon);
taxonomyManager.SaveChanges();
return taxon.Id;
private Guid GetTaxonId(string name)
var taxonomyManager = TaxonomyManager.GetManager();
//Get the flat taxonomy
var flatTaxonomy = taxonomyManager.GetTaxonomies<FlatTaxonomy>().SingleOrDefault(s => s.Name.ToLower() == _thfBlogMainFlatTaxonomy.ToLower());
if (flatTaxonomy == null)
flatTaxonomy = taxonomyManager.CreateTaxonomy<FlatTaxonomy>();
flatTaxonomy.Title = _thfBlogMainFlatTaxonomy;
flatTaxonomy.Description = _thfBlogMainFlatTaxonomy;
flatTaxonomy.Name = _thfBlogMainFlatTaxonomy;
flatTaxonomy.TaxonName = _thfBlogMainFlatTaxonomy;
else
//check if taxon already exist
var taxonItem = taxonomyManager.GetTaxa<FlatTaxon>().Where(t => t.Title.ToString().ToLower() == name.ToLower()).FirstOrDefault();
if (taxonItem != null)
return taxonItem.Id;
//Create a new flat Taxon if not found
var taxon = taxonomyManager.CreateTaxon<FlatTaxon>(Guid.NewGuid());
taxon.Title = name;
taxon.Name = Regex.Replace(name.ToLower(), @"[^\w\-\!\$\'\(\)\=\@\d_]+", "-");
taxon.Description = name;
taxon.UrlName = Regex.Replace(name.ToLower(), @"[^\w\-\!\$\'\(\)\=\@\d_]+", "-");
//Associate the taxon item with the flat taxonomy
flatTaxonomy.Taxa.Add(taxon);
taxonomyManager.SaveChanges();
return taxon.Id;
Any input is very helpful.
Thanks!!!
Here is an exception I'm seeing in the error.log while trying to see all blog post content items assigned to Taxonomy:
----------------------------------------
Timestamp: 8/24/2015 3:42:44 PM
Message: HandlingInstanceID: f5da94b7-82a7-4983-a7fd-4243cd328d2f
An exception of type 'System.NullReferenceException' occurred and was caught.
-----------------------------------------------------------------------------
08/24/2015 11:42:44
Type : System.NullReferenceException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : Object reference not set to an instance of an object.
Source : Telerik.Sitefinity
Help link :
Data : System.Collections.ListDictionaryInternal
TargetSite : System.Collections.IEnumerable GetItems(Telerik.Sitefinity.Taxonomies.Model.ITaxon, Telerik.Sitefinity.Modules.GenericContent.IOrganizableProvider, System.Type, System.String, Int32, Int32, System.String, System.Nullable`1[System.Int32] ByRef)
HResult : -2147467261
Stack Trace : at Telerik.Sitefinity.Taxonomies.Web.Services.MarkedItemsService.GetItems(ITaxon taxon, IOrganizableProvider contentProvider, Type itemType, String sortExpression, Int32 skip, Int32 take, String filter, Nullable`1& totalCount)
at Telerik.Sitefinity.Taxonomies.Web.Services.MarkedItemsService.GetItemsInternal(String taxonId, String itemTypeName, String provider, String itemProvider, String sortExpression, Int32 skip, Int32 take, String filter)
at Telerik.Sitefinity.Taxonomies.Web.Services.MarkedItemsService.GetItems(String taxonId, String itemType, String provider, String itemProvider, String sortExpression, Int32 skip, Int32 take, String filter)
at SyncInvokeGetItems(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
Additional Info:
MachineName : UKUMAR
TimeStamp : 8/24/2015 3:42:44 PM
FullName : Telerik.Sitefinity.Utilities, Version=8.0.5700.0, Culture=neutral, PublicKeyToken=b28c218413bdf563
AppDomainName : /LM/W3SVC/24/ROOT-1-130849013618250786
ThreadIdentity :
WindowsIdentity : ukumar
Requested URL : localhost:60876/.../ DESC&skip=0&take=50
Category: ErrorLog
Priority: 0
EventId: 90000
Severity: Error
Title:Enterprise Library Exception Handling
Machine: UKUMAR
App Domain: /LM/W3SVC/24/ROOT-1-130849013618250786
ProcessId: 3200
Process Name: C:\Program Files (x86)\IIS Express\iisexpress.exe
Thread Name:
Win32 ThreadId:7344
Extended Properties:
----------------------------------------
Thanks.
Hi,
I believe that the problem is coming from when you are checking if the tag/category exists and creating it if it doesn't. Please look at the following code which is working as expected:
private
void
CreateBlogPost(Guid blogPostId, Blog parentBlog, Lstring blogPostTitle, Lstring blogPostContent, List<
string
> tagNames, List<
string
> categories)
BlogsManager blogsManager = BlogsManager.GetManager();
BlogPost blogPost = blogsManager.GetBlogPosts().Where(item => item.Id == blogPostId).FirstOrDefault();
if
(blogPost ==
null
)
//The Blogs item is created as a master. The masterBlogPostId is assigned to the master.
blogPost = blogsManager.CreateBlogPost(blogPostId);
//Set the parent blog.
Blog blog = blogsManager.GetBlogs().Where(b => b.Id == parentBlog.Id).SingleOrDefault();
blogPost.Parent = blog;
//Set the properties of the blog post.
blogPost.Title = blogPostTitle;
blogPost.Content = blogPostContent;
blogPost.DateCreated = DateTime.UtcNow;
blogPost.PublicationDate = DateTime.UtcNow;
blogPost.LastModified = DateTime.UtcNow;
blogPost.UrlName = Regex.Replace(blogPostTitle.ToLower(), @
"[^\w\-\!\$\'\(\)\=\@\d_]+"
,
"-"
);
//Recompiles and validates the url of the blog.
blogsManager.RecompileAndValidateUrls(blog);
foreach
(var tagName
in
tagNames)
this
.AssociateBlogPostWithTag(blogPost, tagName);
foreach
(var category
in
categories)
this
.AssociateBlogPostWithCategory(blogPost, category);
//Save the changes.
blogsManager.SaveChanges();
//Publish the Blogs item. The published version acquires new ID.
var bag =
new
Dictionary<
string
,
string
>();
bag.Add(
"ContentType"
,
typeof
(BlogPost).FullName);
WorkflowManager.MessageWorkflow(blogPostId,
typeof
(BlogPost),
null
,
"Publish"
,
false
, bag);
public
void
AssociateBlogPostWithTag(BlogPost blogPost,
string
tagName)
var taxManager = TaxonomyManager.GetManager();
var taxon = taxManager.GetTaxa<Telerik.Sitefinity.Taxonomies.Model.FlatTaxon>().SingleOrDefault(t => t.Name == tagName);
// Check if a tag with the same name is already added
var tagExists = blogPost.Organizer.TaxonExists(
"Tags"
, taxon.Id);
if
(!tagExists)
// Add the tag, publish the news item and save the changes
blogPost.Organizer.AddTaxa(
"Tags"
, taxon.Id);
public
void
AssociateBlogPostWithCategory(BlogPost blogPost,
string
categoryName)
var taxManager = TaxonomyManager.GetManager();
var taxon = taxManager.GetTaxa<Telerik.Sitefinity.Taxonomies.Model.HierarchicalTaxon>().SingleOrDefault(t => t.Name == categoryName);
// Check if a tag with the same name is already added
var tagExists = blogPost.Organizer.TaxonExists(
"Category"
, taxon.Id);
if
(!tagExists)
// Add the tag, publish the news item and save the changes
blogPost.Organizer.AddTaxa(
"Category"
, taxon.Id);
Thanks Velizar for the input.
I tried your code and getting an exception in the following line because taxon object is coming as null.
var tagExists = blogPost.Organizer.TaxonExists("Category", taxon.Id);
In my code which I posted earlier, I was using TaxonomyManager and checking if taxon exist and if not, creating a new one. Code seems to work fine and all blog post were migrated but in the backend I was seeing the exception while trying to sort to category.
Thanks,
Uttam
I manually added all the required Categories & Tags in the Sitefinity backend before running the import and then run the import and everything seems to work and no errors.
Now, when I go to the Sitefinity backend to see how data looks and verify sort by category, I see the attached exception "Object reference not set to an instance of an object. ". This is the same error which I got with my code I provided initially in this post.
(Attached errors were generated after importing the blogs post with the sample code you provided.)
Any insight ?
Thanks.
Hi Telerik team, did you guys had a chance to look into my issue.
Thanks.
Hello,
In order to continue investigating this I would kindly ask you to open a support ticket so that we can provide you with a way to get your project to us locally so that we can investigate the issue in detail.
Regards,
Velizar Bishurov
Telerik