Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/buttercms/buttercms-csharp
.NET API client for ButterCMS (https://buttercms.com)
https://github.com/buttercms/buttercms-csharp
api-client asp-net asp-net-mvc cms csharp dotnet
Last synced: 6 days ago
JSON representation
.NET API client for ButterCMS (https://buttercms.com)
- Host: GitHub
- URL: https://github.com/buttercms/buttercms-csharp
- Owner: ButterCMS
- License: mit
- Created: 2016-10-06T16:33:18.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2024-10-28T13:07:26.000Z (19 days ago)
- Last Synced: 2024-10-28T15:57:35.852Z (19 days ago)
- Topics: api-client, asp-net, asp-net-mvc, cms, csharp, dotnet
- Language: C#
- Homepage:
- Size: 184 KB
- Stars: 40
- Watchers: 15
- Forks: 16
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# buttercms-csharp
.NET Standard (2.1) Library for ButterCMS API.
## Documentation
For a comprehensive list of examples, check out the [API documentation](https://buttercms.com/docs/api/).
## Installation
To install ButterCMS, run the following command in the [Package Manager Console](https://docs.nuget.org/ndocs/tools/package-manager-console)
```PowerShell
PM> Install-Package ButterCMS
```The library can also be installed to the project via .NET CLI
```bash
dotnet add package ButterCMS
```Or by adding the package manually to the project file
```xml
```
## Usage
To get started with the Butter API, instantiate the ButterCMSClient with the API key found in the [Butter Admin Settings](https://buttercms.com/settings/). An optional timeout parameter can be passed as a [TimeSpan](https://msdn.microsoft.com/en-us/library/system.timespan%28v=vs.110%29.aspx); the default is 10 seconds.
```C#
using ButterCMS;
...
var butterClient = new ButterCMSClient("API KEY");
```If the application will be making many Butter API calls, it is recommended to store and re-use the client object.
Each Butter client method has a synchronous version and an asynchronous version. Asynchronous methods are appended with the word "Async".
### Preview mode
Preview mode can be used to setup a staging website for previewing content fields or for testing content during local development. To fetch content from preview mode add an additional argument, `true`, to the package initialization:
```C#
using ButterCMS;
...
bool previewMode = true;var butterClient = new ButterCMSClient("API KEY", null, 3, null, previewMode);
```## Sections
* [Posts](#posts)
* [Authors](#authors)
* [Categories](#categories)
* [Feeds](#feeds)
* [Collections](#collections)
* [Pages](#pages)
* [Class Definitions](#class-definitions)
* [Exceptions](#exceptions)## Posts
### List Posts
Listing posts returns a [PostsResponse](#postsresponse-class) object. This object consists of a [metadata](#postsmeta-class) object and IEnumerable<[Post](#post-class)>
#### ListPosts() Parameters
| Parameter|Default|Description|
| ---|---|---|
| page(optional) | 1 | Used to paginate through older posts. |
| pageSize(optional) | 10 | Used to set the number of blog posts shown per page. |
| excludeBody(optional) | false | When true, does not return the full post body. Useful for keeping response size down when showing a list of blog posts. |
|authorSlug(optional) | |Filter posts by an author’s slug.|
|categorySlug(optional) | | Filter posts by a category’s slug.#### Examples
```C#
PostsResponse posts = butterClient.ListPosts();PostsResponse filteredPosts = await butterClient.ListPostsAsync(page: 2, pageSize: 5, excludeBody: true, authorSlug: "alice", categorySlug: "dot-net");
```### Retrieving a Single Post
Retrieving a single Post will return a PostResponse object. This object consists of a single [Post](#post-class) and Post [Metadata](#postmeta-class). Post Metadata offers hints about the Previous and Next posts.
#### RetrievePost() Parameters
| Parameter|Description|
| ---|---|
| slug|The slug of the post to be retrieved.|#### Examples
```C#
PostResponse controversialPost = butterClient.RetrievePost("tabs-vs-spaces-throwdown");PostResponse safePost = await butterClient.RetrievePostAsync("puppies-and-kittens");
```
### Searching Posts
Searching posts will return the same object as listing posts, [PostsResponse](#postsresponse-class)
#### SearchPosts() Parameters
| Parameter|Default|Description|
| ---|---|---|
| query | | Search query |
| page(optional) | 1 | Used to paginate through older posts. |
| pageSize(optional) | 10 | Used to set the number of blog posts shown per page. |#### Examples
```C#
PostsResponse posts = butterClient.SearchPosts("spaceships");PostsResponse caffeinePosts = await butterClient.SearchPostsAsync(query: "coffee", page: 3, pageSize: 5);
```
## Authors
### List Authors
Listing Authors returns IEnumerable<[Author](#author-class)>
#### ListAuthors() Parameters
| Parameter|Description|
| ---|---|
| includeRecentPosts(optional)|If true, will return the author's recent posts in the response|#### Examples
```C#
IEnumerable authors = butterClient.ListAuthors();IEnumerable authorsWithPosts = await butterClient.ListAuthorsAsync(includeRecentPosts: true);
```
### Retrieve a Single Author
Retrieving an author returns an [Author](#author-class) object
#### RetrieveAuthor() Parameters
| Parameter|Description|
| ---|---|
|authorSlug|The slug of the author to be retrieved.|
| includeRecentPosts(optional)|If true, will return the author's recent posts in the response|#### Examples
```C#
Author sally = butterClient.RetrieveAuthor("sally");Author tylerAndPosts = await butterClient.RetrieveAuthorAsync(authorSlug: "tyler", includeRecentPosts: true);
```
## Categories
### List Categories
Listing Categories returns IEnumerable<[Category](#category-class)>
#### ListCategories() Parameters
| Parameter|Description|
| ---|---|
| includeRecentPosts(optional)|If true, will return recent posts along with categories|#### Examples
```C#
IEnumerable categories = butterClient.ListCategories();IEnumerable categoriesWithPosts = await butterClient.ListCategoriesAsync(includeRecentPosts: true);
```
### Retrieve a Single Category
Retrieving a single category returns [Category](#category-class)
#### RetrieveCategory() Parameters
| Parameter|Description|
| ---|---|
|categorySlug|The slug of the category to be retrieved.|
| includeRecentPosts(optional)|If true, will return recent posts along with category|#### Examples
```C#
Category dotnetCategory = butterClient.RetrieveCategory("dotnet");Category fsharpCategoryWithPosts = await butterClient.RetrieveCategoryAsync(categorySlug: "fsharp", includeRecentPosts: true);
```
## Feeds
Each of the feeds methods returns an [XmlDocument](https://msdn.microsoft.com/en-us/library/system.xml.xmldocument%28v=vs.110%29.aspx).
### RSS Feed
Retrieve a fully generated RSS feed for your blog.
#### Examples
```C#
XmlDocument rssFeed = butterClient.GetRSSFeed();XmlDocument rssFeed = await butterClient.GetRSSFeedAsync();
```
### Atom Feed
Retrieve a fully generated Atom feed for your blog.
#### Examples
```C#
XmlDocument atomFeed = butterClient.GetAtomFeed();XmlDocument atomFeed = await butterClient.GetAtomFeedAsync();
```
### Sitemap
Retrieve a fully generated sitemap for your blog.
#### Examples
```C#
XmlDocument siteMap = butterClient.GetSitemap();XmlDocument siteMap = await butterClient.GetSitemapAsync();
```
## Collections
**New in version 1.3.0**
By the power of .NET generics, Collections can now be deserialized by the library! The former method that would defer deserialization is still available to ease transition.
#### RetrieveContentFields() Parameters
| Parameter|Description|
| ---|---|
|key|String array of the Collection key|
|parameterDictionary(optional)|Dictionary of additional parameters, such as "locale" or "preview"|#### RetrieveContentFields() Exceptions:
| Exception|Description|
| ---|---|
|[ContentFieldObjectMismatchException](#contentfieldobjectmismatchexception)|This exception will be thrown when the library can't fit the returned data into the passed object class. |#### Examples
```C#
var key = new string[1] { "collection_key" };
var dict = new Dictionary()
{
{ "locale", "de" }
};
var teamMembersAndHeadline = butterClient.RetrieveContentFields(key, dict);```
** Collection JSON documentation** :
As demonstrated in the [Collection documentation](https://buttercms.com/docs/api/?csharp#collections), any number of user-defined Collections can be retrieved from the API, these can get complicated in C# and you may choose to handle the response yourself. The RetrieveContentFieldsJSON() method will return the raw JSON response from the Butter API.
#### RetrieveContentFieldsJSON() Parameters
| Parameter|Description|
| ---|---|
|key|String array of the Collection key|
|parameterDictionary(optional)|Dictionary of additional parameters, such as "locale" or "preview"|#### Examples
```C#
var key = new string[1] { "collection_key" };
var dict = new Dictionary()
{
{ "locale", "de" }
};
var contentFields = await butterClient.RetrieveContentFieldsJSONAsync(key, dict);```
## Pages
[ButterCMS Pages](https://buttercms.com/blog/page-types-cms-powered-pages-for-any-tech-stack) can be retrieved by first defining the custom Page Type as a class. These custom Page Types are defined in the [Butter admin](https://buttercms.com/pages/).
### List Pages
Listing Pages returns a [PagesResponse<T>](#pagesresponse-class) object. Full API documentation can be found at [https://buttercms.com/docs/api/#list-pages-for-a-page-type](https://buttercms.com/docs/api/#list-pages-for-a-page-type).
#### ListPages() Parameters
| Parameter|Description|
| ---|---|
|pageType| Desired page type|
|parameterDictionary| Dictionary of additional parameters. These options are described in greater detail in the [full API documentation](https://buttercms.com/docs/api/#get-multiple-pages-(page-type)). |#### ListPages() Exceptions
| Exception|Description|
| ---|---|
|[PagesObjectMismatchException](#pagesobjectmismatchexception)|This exception will be thrown when the library can't fit the returned data into the passed object class. |### Retrieve a Single Page
Retrieving a single page returns a [PageResponse<T>](#page-response-class) object
#### RetrievePage() Parameters
| Parameter|Description|
| ---|---|
|pageType| Desired page type|
|pageSlug| Slug of the desired page|
|parameterDictionary| Dictionary of additional parameters|#### RetrievePage() Exceptions:
| Exception|Description|
| ---|---|
|[PagesObjectMismatchException](#pagesobjectmismatchexception)|This exception will be thrown when the library can't fit the returned data into the passed object class. |#### Examples
##### Page Type Definition in the Butter Admin
![alt text](/Examples/RecipePageType.png "Page Type Definition")
##### Controller and ViewModel examples
```C#
public namespace HungryDevApp
{
public class RecipePage
{
public string category { get; set; }
public string recipe_name { get; set; }
public string main_ingredient { get; set; }
public double estimated_cooking_time_in_minutes { get; set; }
public string ingredient_list { get; set; }
public string instructions { get; set; }
}public class RecipesController : Controller
{
[Route(recipes/)]
public virtual ActionResult Index(int page = 1, int pageSize = 10)
{
var butterClient = new ButterCMSClient("API KEY");var parameterDict = new Dictionary()
{
{"page", page.ToString()},
{"page_size", pageSize.ToString()}
};PagesResponse recipePages = butterClient.ListPages("recipe", parameterDict);
var viewModel = new RecipesViewModel();
viewModel.PreviousPageNumber = recipePages.Meta.PreviousPage;
viewModel.NextPageNumber = recipePages.Meta.NextPage;
viewModel.PagesCount = recipePages.Meta.Count;viewModel.Recipes = new List();
foreach (Page recipe in recipePages.Data)
{
RecipeViewModel recipeViewModel = new RecipeViewModel();
recipeViewModel.Category = recipe.Fields.category;
recipeViewModel.RecipeName = recipe.Fields.recipe_name;
recipeViewModel.MainIngredient = recipe.Fields.main_ingredient;
recipeViewModel.EstimatedCookingTimeInMinutes = recipe.Fields.estimated_cooking_time_in_minutes;
recipeViewModel.IngredientList = recipe.Fields.ingredient_list;
recipeViewModel.Instructions = recipe.Fields.instructions;viewModel.Recipes.Add(recipeViewModel);
}return View(viewModel);
}[Route(recipe/{slug})]
public virtual ActionResult Recipe(string slug)
{
var butterClient = new ButterCMSClient("API KEY");PageResponse recipe = butterClient.RetrievePage("recipe", slug);
var viewModel = new RecipeViewModel();
viewModel.Category = recipe.Data.Fields.category;
viewModel.RecipeName = recipe.Data.Fields.recipe_name;
viewModel.MainIngredient = recipe.Data.Fields.main_ingredient;
viewModel.EstimatedCookingTimeInMinutes = recipe.Data.Fields.estimated_cooking_time_in_minutes;
viewModel.IngredientList = recipe.Data.Fields.ingredient_list;
viewModel.Instructions = recipe.Data.Fields.instructions;return View(viewModel);
}
}public class RecipesViewModel
{
public List Recipes { get; set; }
public int? PreviousPageNumber { get; set; }
public int? NextPageNumber { get; set; }
public int PagesCount { get; set; }
}public class RecipeViewModel
{
public string Category { get; set; }
public string RecipeName { get; set; }
public string MainIngredient { get; set; }
public double EstimatedCookingTimeInMinutes { get; set; }
public string IngredientList { get; set; }
public string Instructions { get; set; }
}}
```
##### Example View usage for ListPages
```HTML
@using HungryDevApp
@{
Layout = "~/Views/Shared/Layouts/_Layout.cshtml";
}
@model RecipesViewModel
@{Model.PagesCount} recipes total
```
##### Example View usage for RetrievePage
```HTML
@using HungryDevApp
@{
Layout = "~/Views/Shared/Layouts/_Layout.cshtml";
}
@model RecipeViewModel
@{Model.RecipeName}
Estimated cooking time: @{Model.EstimatedCookingTimeInMinutes} minutes
Ingredients:
@{Model.IngredientList}
Instructions:
@{Model.Instructions}
```
## Class Definitions
### PostsResponse Class
| Property | Type|
|----|---|
|Meta| [PostsMeta](#postsmeta-class)|
|Data| IEnumerable<[Post](#post-class)>|### PostsMeta Class
| Property | Type|
|----|---|
|Count| int|
|NextPage| int?|
|PreviousPage| int?|### Post Class
| Property | Type|
|----|---|
|Url|string|
|Created|DateTime|
|Published|DateTime|
|Author|[Author](#author-class)|
|Categories|IEnumerable<[Category](#category-class)>
|FeaturedImage| string|
|FeaturedImageAlt| string|
|Slug|string|
|Title|string|
|Body|string|
|Summary|string|
|SeoTitle|string|
|MetaDescription|string|
|Status|[PostStatusEnum](#poststatusenum)|### PostStatusEnum
|Constant|Value|
|---|---|
|Unknown|0|
|Draft|1|
|Published|2|### PostResponse Class
| Property | Type|
|----|---|
|Meta|[PostMeta](#postmeta-class)|
|Data|[Post](#post-class)|### PostMeta Class
| Property | Type|
|----|---|
|NextPost|[PostLight](#postlight-class)|
|PreviousPost|[PostLight](#postlight-class)|### PostLight Class
| Property | Type|
|----|---|
|Slug|string|
|Title|string|
|FeaturedImage|string|### Author Class
| Property | Type|
|----|---|
|FirstName| string|
|LastName| string|
|Email| string|
|Slug| string|
|Bio| string|
|Title| string|
|LinkedinUrl| string|
|FacebookUrl| string|
|InstagramUrl| string|
|PinterestUrl| string|
|TwitterHandle| string|
|ProfileImage| string|
|RecentPosts| IEnumerable<[Post](#post-class)>|### Category Class
| Property | Type|
|----|---|
|Name| string|
|Slug| string|
|RecentPosts| IEnumerable<[Post](#post-class)>|### PagesResponse Class
| Property | Type|
|----|---|
|Meta| [PageMeta](#pagemeta-class)|
|Data| IEnumerable<[Page](#page-class)<T>>|### PageMeta Class
| Property | Type|
|----|---|
|Count| int|
|PreviousPage| int?|
|NextPage| int?|### PageResponse Class
| Property | Type|
|----|---|
|Data| [Page](#page-class)<T>|### Page Class
| Property | Type|
|----|---|
|Slug| string|
|Updated| DateTime|
|Published| DateTime?|
|PageType| string|
|Fields|T|## Exceptions
## Testing
To run SDK test just simply:
```
PM> dotnet test
```Or use Visual Studio Test Explorer.
### InvalidKeyException
The library throws this exception when the Butter API key used to instatiate the client was not valid.
### ContentFieldObjectMismatchException
This exception will be thrown when the library can't fit the returned data from a Content Field request into the passed object class.
### PagesObjectMismatchException
This exception will be thrown when the library can't fit the returned data from a Pages request into the passed object class.