.NET image upload

Overview

Cloudinary is a cloud-based service that provides an end-to-end image and video management solution including uploads, storage, administration, manipulation, and delivery.

As part of its service, Cloudinary provides an API for uploading images, videos, and any other kind of file to the cloud. Images uploaded to Cloudinary are stored safely in the cloud with secure backups and revision history, utilizing Amazon's S3 service.

After you upload your media assets to Cloudinary, you can browse them using an API or an interactive web interface and manipulate them to reach the size and look & feel that best matches your graphic design. All uploaded media resources as well as dynamically transformed resources are optimized and delivered by Cloudinary through a fast CDN with advanced caching for optimal user experience.

Cloudinary's APIs allow secure uploading from your servers, directly from your visitors browsers or mobile applications, or fetched via remote public URLs. Comprehensive transformations can be applied on uploaded resources and you can extract image and video metadata and semantic information once their upload completes.

Cloudinary's .NET library wraps Cloudinary's upload API and simplifies the integration. .NET methods are available for easily uploading resources to the cloud. .NET view helper methods are available for uploading directly from a browser to Cloudinary.

This page covers common usage patterns for .NET image upload with Cloudinary.

Server side upload

You can upload images (or any other raw file) to Cloudinary from your .NET code. Uploading is done over HTTPS using a secure protocol based on your account's API Key and API Secret parameters.

The following C# method uploads an image to the cloud:

public ImageUploadResult Upload(ImageUploadParams parameters);

The ImageUploadParms class sets an image to upload with additional parameters and ImageUploadResults class provides the deserialized server response.

For example, uploading a local image file named my_image.jpg:

var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"c:\my_image.jpg")
};
var uploadResult = cloudinary.Upload(uploadParams);

For a full list of the upload method parameters, see the Upload method in the Upload API Reference.

By default, uploading is performed synchronously. Once finished, the uploaded image is immediately available for manipulation and delivery.

An upload API call returns a JSON object with content similar to that shown in the following example:

 RESPONSE (ImageUploadResult):
 {
  "public_id":"tquyfignx5bxcbsupr6a",
  "version":1375302801,
  "signature":"52ecf23eeb987b3b5a72fa4ade51b1c7a1426a97",
  "width":1920,
  "height":1200,
  "format":"jpg",
  "resource_type":"image",
  "created_at":"2017-07-31T20:33:21Z",
  "bytes":737633,
  "type":"upload",
  "url":
   "https://res.cloudinary.com/demo/image/upload/v1375302801/tquyfignx5bxcbsupr6a.jpg",
  "secure_url":
   "https://res.cloudinary.com/demo/image/upload/v1375302801/tquyfignx5bxcbsupr6a.jpg"
 }

The response is automatically parsed and converted into an object model.

The response includes HTTP and HTTPS URLs for accessing the uploaded image as well as additional information regarding the uploaded file: The Public ID of the image (used for building viewing URLs), resource type, width and height, image format, file size in bytes, a signature for verifying the response and more.

Public ID

Each uploaded image is assigned with a unique identifier called Public ID. It is a URL-safe string that is used to reference the uploaded resource as well as building dynamic delivery and transformation URLs.

By default, Cloudinary generates a unique, random Public ID for each uploaded image. This identifier is returned in the public_id response parameter and can be accessed via PublicId property of the ImageUploadResults class. In the example above, the assigned Public ID is 'c87hg9xfxrd4itiim3t0'. As a result, the URL for accessing this image via our 'demo' account is the following:

https://res.cloudinary.com/demo/image/upload/c87hg9xfxrd4itiim3t0.jpg

You can specify your own custom public ID instead of using the randomly generated one. The following example specifies 'sample_id' as the public ID:

var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"c:\my_image.jpg"),
  PublicId = "sample_id"
};
var uploadResult = cloudinary.Upload(uploadParams);

Using a custom public ID is useful when you want your delivery URLs to be readable and refer to the associated entity. For example, setting the public ID to a normalized user name and identifier in your local system:

var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"c:\my_image.jpg"),
  PublicId = "john_doe_1001"
};
var uploadResult = cloudinary.Upload(uploadParams);

Public IDs can be organized in folders for more structured delivery URLs. To use folders, simply separate elements in your public ID string with slashes ('/'). Here's an example:

var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"c:\my_image.jpg"),
  PublicId = "my_folder/my_name"
};
var uploadResult = cloudinary.Upload(uploadParams);

As the example below shows, your public IDs can include multiple folders:

var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"c:\my_image.jpg"),
  PublicId = "my_folder/my_sub_folder/my_name"
};
var uploadResult = cloudinary.Upload(uploadParams);

Set the UseFilename property of the ImageUploadParms class to true to tell Cloudinary to use the original name of the uploaded image file as its Public ID. Notice that the file name will be normalized and a set of random characters will be appended to it to ensure uniqueness. This is quite useful if you want to safely reuse the filenames of files uploaded directly by your users.

var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"c:\sample.jpg"),
  UseFilename = true
};
var uploadResult = cloudinary.Upload(uploadParams);
// Generated public ID for example: "sample_ddzpj3"

Data uploading options

Cloudinary's .NET library supports uploading files from various sources.

You can upload an image by specifying a local path of an image file. For example:

var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"c:\sample.jpg")
};
var uploadResult = cloudinary.Upload(uploadParams);

If your images are already publicly available online, you can specify their remote HTTP URLs instead of uploading the actual data. In this case, Cloudinary will fetch the image from its remote URL for you. This option allows for a much faster migration of your existing images. Here's an example:

var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"http://www.example.com/image.jpg")
};
var uploadResult = cloudinary.Upload(uploadParams);

If you have existing images in an Amazon S3 bucket, you can point Cloudinary to their S3 URLs. Note - this option requires a quick manual setup. Contact us and we'll guide you on how to allow Cloudinary access to your relevant S3 buckets.

var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"s3://my-bucket/my-path/my-file.jpg")
};
var uploadResult = cloudinary.Upload(uploadParams);

Direct uploading from the browser

The upload samples mentioned above allows your server-side .NET code to upload images to Cloudinary. In this flow, if you have a web form that allows your users to upload images, the image data is first sent to your server and only then uploaded to Cloudinary.

A more efficient and powerful option is to allow your users to upload images directly from the browser to Cloudinary instead of going through your servers. This method allows for faster uploading and better user experience. It also reduces load from your servers and reduces the complexity of your .NET applications.

Uploading directly from the browser is done using Cloudinary's jQuery plugin. To ensure that all uploads were authorized by your application, a secure signature must first be generated in your server-side .NET code.

Direct uploading environment setup

Start by including the required Javascript files - jQuery, Cloudinary's plugin and the jQuery-File-Upload plugin it depends on. These are available in the js folder of Cloudinary's Javascript library.

For your convenience we have prepared a powershell script that can download necessary files for you. Windows PowerShell is shipped with all Microsoft Windows operation systems since Windows 7, but could be installed on earlier systems as well. By default, the feature of script execution is disabled in the Windows PowerShell. To enable it, execute the following command (you should have administrator rights):

set-executionpolicy remotesigned

Then you can execute the script (assuming you are in the script directory):

.\get_cloudinary_js.ps1

This command downloads all necessary files to two sub-directories of the current directory - Scripts and Content. If you want to override the destination directory (for example, if you already have a project of a ASP.NET web site), you could pass the destination directory as an argument:

.\get_cloudinary_js.ps1 c:\my_site

Then you can directly include the Javascript files:

<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jquery.ui.widget.js"></script>
<script type="text/javascript" src="jquery.iframe-transport.js"></script>
<script type="text/javascript" src="jquery.fileupload.js"></script>
<script type="text/javascript" src="jquery.cloudinary.js"></script>

Cloudinary's jQuery plugin requires your Cloud Name and additional configuration parameters to be available. Note: never expose your API Secret in public client side code.

To set-up Cloudinary's configuration, include the following line in your scripts section of a view:

<script>
  $.cloudinary.config("cloud_name", "your_cloud_name");
</script>

Alternatively, you can use the GetCloudinaryJsConfig method of the Cloudinary class from your view code to add necessary JS code. All necessary configuration options will be taken from your instance of Cloudinary class. For example:

@Model.Cloudinary.GetCloudinaryJsConfig()

Note: For .NET version v3.5 and earlier, the result should be wrapped with '@Html.Raw' for embedding HTML code in your view. For example:

@Html.Raw(Model.Cloudinary.GetCloudinaryJsConfig())

This is equivalent to:

<script src="~/Scripts/jquery.ui.widget.js"></script>
<script src="~/Scripts/jquery.iframe-transport.js"></script>
<script src="~/Scripts/jquery.fileupload.js"></script>
<script src="~/Scripts/jquery.cloudinary.js"></script>
<script type='text/javascript'>
  $.cloudinary.config({
    "cloud_name": "your_cloud_name",
    "api_key": "your_api_key",
    "private_cdn": false,
    "cdn_subdomain": false
  });
</script>

You can override the location of JS files and include additional jQuery files that are required for more advanced uploading options:

@Model.Cloudinary.GetCloudinaryJsConfig(
  true, @"http://your-local-host.domain/cloudinary_js/")

This is equivalent to:

<script src="http://your-local-host.domain/cloudinary_js/jquery.ui.widget.js"></script>
<script src="http://your-local-host.domain/cloudinary_js/jquery.iframe-transport.js"></script>
<script src="http://your-local-host.domain/cloudinary_js/jquery.fileupload.js"></script>
<script src="http://your-local-host.domain/cloudinary_js/jquery.cloudinary.js"></script>
<script src="http://your-local-host.domain/cloudinary_js/canvas-to-blob.min.js"></script>
<script src="http://your-local-host.domain/cloudinary_js/jquery.fileupload-image.js"></script>
<script src="http://your-local-host.domain/cloudinary_js/jquery.fileupload-process.js"></script>
<script src="http://your-local-host.domain/cloudinary_js/jquery.fileupload-validate.js"></script>
<script src="http://your-local-host.domain/cloudinary_js/load-image.all.min.js"></script>
<script type='text/javascript'>
  $.cloudinary.config({
    "cloud_name": "your_cloud_name",
    "api_key": "your_api_key",
    "private_cdn": false,
    "cdn_subdomain": false
  );
</script>

The Cloudinary JavaScript library utilizes the Blueimp File Upload library to support uploading media directly from the browser. You must explicitly initialize this library:

$(function() {
  if($.fn.cloudinary_fileupload !== undefined) {
    $("input.cloudinary-fileupload[type=file]").cloudinary_fileupload();
  }
});

Direct uploading from the browser is performed using XHR (Ajax XMLHttpRequest) CORS (Cross Origin Resource Sharing) requests. In order to support older browsers that do not support CORS, the jQuery plugin will gracefully degrade to an iframe based solution.

This solution assumes placing cloudinary_cors.html in the public folder of your .NET application, for example ~/Content. This file is required for iframe fallback upload and is available in the html folder of Cloudinary's Javascript library.

This file can be downloaded using the powershell script of get_cloudinary_js.ps1.

The following code builds a URL of the local cloudinary_cors.html file:

string cors_location = (new UriBuilder(Request.Url.AbsoluteUri)
  { Path = Url.Content("~/Content/cloudinary_cors.html") }).ToString();

Direct upload file tag

Embed a file input tag in your HTML pages using the BuildUploadForm method of the Api class.

The following example adds a file input field to your form. Selecting or dragging a file to this input field will automatically initiate uploading from the browser to Cloudinary.

<form>
  @Model.Cloudinary.Api.BuildUploadForm("image_id", "auto",
    new SortedDictionary<string, object>() { { "callback", cors_location } },
    null)
</form>

When uploading is completed, the identifier of the uploaded image is set as the value of a hidden input field of your selected name (e.g., image_id in the example above).

You can then process the identifier received by your .NET controller and store it in your model for future use, exactly as if you're using a standard server side uploading.

The following .NET controller code shows how to process the received response:

[HttpPost]
[AcceptVerbs(HttpVerbs.Post)]
public void UploadDirect()
{
  var headers = HttpContext.Request.Headers;
  string content = null;
  using (StreamReader reader = new StreamReader(HttpContext.Request.InputStream))
  {
    content = reader.ReadToEnd();
  }
  if (String.IsNullOrEmpty(content)) return;
  
  Dictionary<string, string> results = new Dictionary<string, string>();
  string[] pairs = content.Split(new char[] { '&' }, 
    StringSplitOptions.RemoveEmptyEntries);
    
  foreach (var pair in pairs)
  {
    string[] splittedPair = pair.Split('=');
    results.Add(splittedPair[0], splittedPair[1]);
  }
  
  Photo photo = new Photo()
  {
    Bytes = Int32.Parse(results["bytes"]),
    CreatedAt = DateTime.ParseExact(HttpUtility.UrlDecode(results["created_at"]), 
      "yyyy-MM-ddTHH:mm:ssZ", CultureInfo.InvariantCulture),
    Format = results["format"],
    Height = Int32.Parse(results["height"]),
    Path = results["path"],
    PublicId = results["public_id"],
    ResourceType = results["resource_type"],
    SecureUrl = results["secure_url"],
    Signature = results["signature"],
    Type = results["type"],
    Url = results["url"],
    Version = Int32.Parse(results["version"]),
    Width = Int32.Parse(results["width"]),
  };

Having stored the image_id, you can now display a directly uploaded image in the same way you would display any other Cloudinary hosted image:

@Model.Cloudinary.Api.UrlImgUp.Format("jpg").Transform(
  new Transformation().Width(120).Height(80).Crop("fill")).BuildUrl(Model.Photo.PublicId)

Additional direct uploading options

When uploading directly from the browser, you can still specify all the upload options available to server-side uploading.

For example, the following call performs direct uploading that will also tag the uploaded image, limit its size to given dimensions and generate a thumbnail eagerly. Also notice the custom HTML attributes.

<form>
  @Model.Cloudinary.Api.BuildUploadForm("image_id", "auto",
    new SortedDictionary<string, object>()
    {
      { "callback", cors_location },
      { "tags", "directly_uploaded" },
      { "crop", "limit" },
      { "width", 1000 },
      { "height", 1000 },
      { "eager", new Dictionary<string,object>() 
        {{ "crop","fill" }, { "width",150 }, { "height", 100 } }}
    },
    new Dictionary<string, string>() { { "style", "margin-top: 30px" } })
</form>

For the full list of parameters available for signed uploads, see the Upload method in the Upload API Reference.

Note: For security reasons, only this limited set of parameters can be used in an unsigned upload request.

Preview thumbnail, progress indication, multiple images

Cloudinary's jQuery library also enables an enhanced uploading experience - show a progress bar, display a thumbnail of the uploaded image, drag & drop support, upload multiple files and more.

Bind to Cloudinary's cloudinarydone event if you want to be notified when an upload to Cloudinary has completed. You will have access to the full details of the uploaded image and you can display a cloud-generated thumbnail of the uploaded images using Cloudinary's jQuery plugin.

The following sample code creates a 150x100 thumbnail of an uploaded image and updates an input field with the public ID of this image.

$('.cloudinary-fileupload').bind('cloudinarydone', function(e, data) {  
  $('.preview').html(
    $.cloudinary.image(data.result.public_id, 
      { format: data.result.format, version: data.result.version, 
        crop: 'fill', width: 150, height: 100 })
  );    
  $('.image_public_id').val(data.result.public_id);    
  return true;
});

You can track the upload progress by binding to the following events: fileuploadsend, fileuploadprogress, fileuploaddone and fileuploadfail. You can find more details and options in the documention of jQuery-File-Upload.

The following Javascript code updates a progress bar according to the data of the fileuploadprogress event:

$('.cloudinary-fileupload').bind('fileuploadprogress', function(e, data) { 
  $('.progress_bar').css('width', Math.round((data.loaded * 100.0) / data.total) + '%'); 
});

You can find some more examples in our Photo Album sample project.

The file input field can be configured to support simultaneous multiple file uploading. Setting the multiple HTML parameter to TRUE allows uploading multiple files. Note - currently, only a single input field is updated with the identifier of the uploaded image. You should manually bind to the cloudinarydone event to handle results of multiple uploads. Here's an example:

<form>
  @Model.Cloudinary.Api.BuildUploadForm("image_id", "auto",
    null,
    new Dictionary<string, string>() { { "multiple", "true" } })
</form>

For more details about direct uploading, see this blog post: Direct image uploads from the browser to the cloud with jQuery.

Incoming transformations

By default, images uploaded to Cloudinary are stored in the cloud as-is. Once safely stored in the cloud, you can generate derived images from these originals by asking Cloudinary to apply transformations and manipulations.

Sometimes you may want to normalize and transform the original images before storing them in the cloud. You can do that by applying an incoming transformation as part of the upload request.

Any image transformation parameter can be specified as options passed to the upload call. A common incoming transformation use-case is shown in the following example, namely, limit the dimensions of user uploaded images to 1000x1000:

var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"c:\my_image.jpg"),
  Transformation = new Transformation().Width(1000).Height(1000).Crop("limit")
};
var uploadResult = cloudinary.Upload(uploadParams);

Another example, this time performing custom coordinates cropping and forcing format conversion to PNG:

var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"c:\my_image.jpg"),
  Transformation = 
    new Transformation().Width(400).Height(300).X(50).Y(80).Crop("crop").FetchFormat("png")
};
var uploadResult = cloudinary.Upload(uploadParams);

Named transformations as well as multiple chained transformations can be applied using the Transformation property. The following example first limits the dimensions of an uploaded image and then adds a watermark as an overlay.

var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"c:\my_image.jpg"),
  Transformation = new Transformation()
    .Width(400).Height(300).X(50).Y(80).Crop("crop").FetchFormat("png")
    .Chain().Overlay("my_watermark").Flags("relative").Width(0.5)
};
var uploadResult = cloudinary.Upload(uploadParams);

Eager transformations

Cloudinary can dynamically transform images using specially crafted transformation URLs. By default, the first time a user accesses a transformation URL, the transformed images is created on-the-fly, stored persistently in the cloud and delivered through a fast CDN with advanced caching. All subsequent accesses to the same transformation would quickly deliver a cached copy of the previously generated image via the CDN.

You can tell Cloudinary to eagerly generate one or more derived images while uploading. This approach is useful when you know in advance that certain transformed versions of your uploaded images will be required. Eagerly generated derived images are available for fast access immediately when the upload call returns.

Generating transformed images eagerly is done by specifying the 'eager' upload option. This option accepts either a hash of transformation parameters or an array of transformations.

The following example eagerly generates a 150x100 face detection based thumbnail:

var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"c:\my_image.jpg"),
  PublicId = "eager_sample",
  EagerTransforms = new List<Transformation>()
  {
    new Transformation().Width(150).Height(100).Crop("thumb").Gravity("face")
  }
};
var uploadResult = cloudinary.Upload(uploadParams);

Now, if you embed the same transformed image in your web view, it will already be available for fast delivery. The following tag embeds the derived image from the example above:

@Model.Cloudinary.Api.UrlImgUp.Transform(
  new Transformation().Width(150).Height(100).Crop("thumb").Gravity("face"))
.BuildUrl("eager_sample.jpg");

The following example generates two transformed versions eagerly, one fitting image into a 100x150 PNG and another applies a named transformation.

var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"c:\my_image.jpg"),
  EagerTransforms = new List<Transformation>()
  {
    new Transformation().Width(100).Height(150).Crop("fit").FetchFormat("png"),
    new Transformation().Named("jpg_with_quality_30")
  }
};
var uploadResult = cloudinary.Upload(uploadParams);

You can apply an incoming transformation and generate derived images eagerly using the same upload call. The following example does that while also applying a chained transformation:

var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"c:\sample.jpg"),
  Transformation = new Transformation()
    .Width(100).Height(120).Crop("limit")
    .Chain().Crop("crop").X(5).Y(10).Width(40).Height(10),
  EagerTransforms = new List<Transformation>()
  {
    new Transformation().Width(0.2).Crop("scale"),
    new Transformation().Effect("hue:30")
  }
};
var uploadResult = cloudinary.Upload(uploadParams);

For more image transformation options in .NET, see .NET image manipulation.

Semantic data extraction

When you upload a resource to Cloudinary, the API call will report information about the uploaded asset: width, height, number of bytes and image format. Cloudinary supports extracting additional information from the uploaded image: Exif and IPTC camera metadata, color histogram, predominant colors and coordinates of automatically detected faces. You can ask Cloudinary for this semantic data either during the upload API call for newly uploaded images, or using our Admin API for previously uploaded images.

See Cloudinary's Admin API documentation for more details: Details of a single resource.

You can tell Cloudinary to include relevant metadata in its upload API response by setting the Faces, Exif, Colors and Metadata boolean parameters to true while calling the upload API.

The following example uploads an image via a remote URL, and requests the coordinates of all detected faces in the image:

var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"https://res.cloudinary.com/demo/image/upload/couple.jpg"),
  Faces = true
};
var uploadResult = cloudinary.Upload(uploadParams);

Below you can see the faces coordinates that were included in the upload response:

 RESPONSE (ImageUploadResult):
 {
  "public_id":"egwcvxk8idvump0jauv7",
  ...,
  "faces":
  [
      [98,74,61,83],
      [139,130,52,71]
  ]
 }

Another example, this time requesting details about the main colors of the uploaded image. Each pair in the returned colors array includes the color name or its RGB representation and the percentage of the image comprising it.

var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"https://res.cloudinary.com/demo/image/upload/couple.jpg"),
  Colors = true
};
var uploadResult = cloudinary.Upload(uploadParams);

/*
 * RESPONSE (ImageUploadResult):
 * {
 *  "public_id":"ekr5yblwesovtuf2lwgv",
 *  ...,
 *  "colors":
 *  [
 *      ["#152E02",7.9],
 *      ["#2E4F06",6.3],
 *      ["#3A6604",5.6],
 *      ...
 *  ],
 *  "predominant":
 *  {
 *      "google":
 *      [
 *          ["yellow",40.1],
 *          ["green",24.6],
 *          ["brown",13.4],
 *          ["black",12.5],
 *          ["teal",9.4]
 *      ]
 *  }
 * }
 */

You can also request Exif, IPTC, colors and faces data in a single upload call:

var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"https://res.cloudinary.com/demo/image/upload/couple.jpg"),
  Faces = true,
  Colors = true,
  Exif = true,
  Metadata = true
};
var uploadResult = cloudinary.Upload(uploadParams);

See the following blog post for more details: API for extracting semantic image data - colors, faces, Exif data and more

Raw file uploading

Cloudinary's main strength is in managing images. However, you can still use Cloudinary to manage any other file format using the same simple APIs. You'll get your files stored in a highly available storage with automatic backups and revision control, and when accessed, have them delivered through a fast CDN.

You can upload a raw file to Cloudinary using the RawUploadParams class.

var uploadParams = new RawUploadParams()
{
  File = new FileDescription(@"c:\sample_spreadsheet.xls"),
  PublicId = "sample_spreadsheet"
};
var uploadResult = cloudinary.Upload(uploadParams);

Non-image raw files are stored in the cloud as-is. Note that while public IDs of image files do not include the file's extension, public IDs of raw files does include the original file's extension.

Here's a sample response of a raw upload call, which is slightly different from an image upload response:

 RESPONSE (ImageUploadResult):
 {
  "public_id":"sample_spreadsheet.xls",
  "version":1375302583,
  "signature":"1bf940a92ff0bcbde2eeab6455f7b9c0c3158baa",
  "resource_type":"raw",
  "created_at":"2017-07-31T20:29:43Z",
  "bytes":44912,
  "type":"upload",
  "url":
    "https://res.cloudinary.com/demo/raw/upload/v1375302583/sample_spreadsheet.xls",
  "secure_url":
    "https://res.cloudinary.com/demo/raw/upload/v1375302583/sample_spreadsheet.xls"
 }

Sometimes you don't know whether your users would upload image files or raw files. It is supported automatically when you use RawUploadParams, however you can turn off the automatic mode by passing the second parameter to the Upload function.

var uploadParams = new RawUploadParams()
{
  File = new FileDescription(@"c:\sample_spreadsheet.xls"),
  PublicId = "sample_spreadsheet"
};
var uploadResult = cloudinary.Upload(uploadParams, "raw");

Delivery URLs of raw files are built quite similarly to those of images. Just make sure to set ResourceType to raw. Here's an example:

@Model.Cloudinary.Api.UrlImgUp.ResourceType("raw").BuildUrl("sample_spreadsheet.xls");

Update and delete images

Image uploaded to Cloudinary are stored persistently in the cloud. You can programatically delete an uploaded image using following methods:

public DelResResult DeleteResources(DelResParams parameters);
public DelResResult DeleteResources(params string[] publicIds);

For example, the following code would delete the uploaded image assigned with the public ID 'zombie':

cloudinary.DeleteResources("zombie");

See our Admin API documentation for more options of listing and deleting images and files.

When you delete an uploaded image, all its derived images are deleted as well. However, images and derived images that were already delivered to your users might have cached copies at the CDN layer. If you now upload a new image with the same public ID, the cached copy might be returned instead. To avoid that, use different randomly generated public IDs for each upload or alternatively, add the Version component to the delivery URLs. If none of these solutions work, you might want to force cache invalidation for each deleted image.

Forcing cache invalidation is done by setting the Invalidate parameter to true either when deleting an image or uploading a new one. Note that it usually takes up to one hour for the CDN invalidation to take effect. Here's are two examples:

var delParams = new DelResParams()
{
  PublicIds = new List<string>() { "zombie" },
  Invalidate = true
};
var delResult = cloudinary.DeleteResources(delParams);
var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"c:\new_zombie.jpg"),
  PublicId = "zombie",
  Invalidate = true
};
var uploadResult = cloudinary.Upload(uploadParams);

Refresh images

Cloudinary supports forcing the refresh of Facebook & Twitter profile pictures, using the explicit API method. The response of this method includes the image's version. Use this version to bypass previously cached CDN copies. For Facebook pictures, use the application-specific numeric ID only.

var exp = new ExplicitParams("4")
{
  Type = "facebook"
};
var expResult = cloudinary.Explicit(exp);

You can also use the Explicit method to generate transformed versions of an uploaded image. This is useful when Strict Transformations are allowed for your account and you wish to create custom derived images for already uploaded images.

var exp = new ExplicitParams("sample_id")
{
  Type = "upload",
  EagerTransforms = 
    new List<Transformation>() { new Transformation().Width(150).Height(230).Crop("fill") }
};
var expResult = cloudinary.Explicit(exp);

Rename images

You can rename images uploaded to Cloudinary. Renaming means changing the public ID of already uploaded images. The following methods allows renaming a public ID:

public RenameResult Rename(string fromPublicId, string toPublicId, bool overwrite = false);
public RenameResult Rename(RenameParams parameters);

For example, renaming an image with the public ID 'old_name' ro 'new_name':

cloudinary.Rename("old_name", "new_name");

By default, Cloudinary prevents renaming to an already taken public ID. You can set the overwrite parameter to true to delete the image that has the target public ID and replace it with the image being renamed:

cloudinary.Rename("old_name", "new_name", true);

Manage tags

Cloudinary supports assigning one or more tags to uploaded images. Tags allow you to better organize your media library.

You can use our Admin API and media library web interface for searching, listing and deleting images by tags. In addition, you can merge multiple images that share the same tag into a sprite, a multi-page PDF or an animated GIF.

See our Admin API documentation for more details regarding managing images by tags.

The following example assigned two tags while uploading.

var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"c:\my_image.jpg"),
  PublicId = "sample_id",
  Tags = "special, for_homepage"
};
var uploadResult = cloudinary.Upload(uploadParams);

You can modify the assigned tags of an already uploaded image. The following example assigns a tag to a list of images:

var tagParams = new TagParams()
{
  Command = TagCommand.Add,
  Tag = "another_tag"
};
tagParams.PublicIds.Add("sample_id");
tagParams.PublicIds.Add("de9wjix4hhnqpxixq6cw");
var tagResult = cloudinary.Tag(tagParams);

The following example clears the given tag from a list of images:

var tagParams = new TagParams()
{
  Command = TagCommand.Remove,
  Tag = "another_tag"
};
tagParams.PublicIds.Add("sample_id");
tagParams.PublicIds.Add("de9wjix4hhnqpxixq6cw");
var tagResult = cloudinary.Tag(tagParams);

This example clears all tags from a given list of images:

var tagParams = new TagParams()
{
  Command = TagCommand.Replace,
  Tag = "another_tag"
};
tagParams.PublicIds.Add("sample_id");
var tagResult = cloudinary.Tag(tagParams);

Text creation

Cloudinary allows generating dynamic text overlays with your custom text. First you need to create a text style - font family, size, color, etc. The name of the text style is its public ID and it behaves like an image of the text type.

The following command creates a text style named dark_name of a certain font, color and style:

var textParams = new TextParams("Sample Name")
{
  PublicId = "dark_name",
  FontFamily = "Arial",
  FontSize = 12,
  FontColor = "black",
  Opacity = "90"
};
var textResult = cloudinary.Text(textParams);

The following image tag adds a text overlay using the created dark_name text style.

@Model.Cloudinary.Api.UrlImgUp.Transform(
  new CloudinaryDotNet.Transformation()
    .X(5)
    .Y(5)
    .Gravity("south_east")
    .Overlay("text:dark_name:Hello+World"))
  .BuildImageTag("sample.jpg")

For more text style options, see Text layers creation.

More information about text overlays is available in our adding text overlays in .NET documentation.

Notifications and async transformations

By default, Cloudinary's upload API works synchronously. Uploaded images processed and eager transformations are generated synchronously during the upload API call.

You can tell Cloudinary to generate eager transformations in the background and send you an HTTP notification callback when the transformations are ready. You can do that by setting the EagerAsync property to true and optionally setting EagerNotificationUrl to the URL Cloudinary should send the callback to. Here's an example:

var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"c:\my_image.jpg"),
  EagerTransforms = new List<Transformation>() {
    new Transformation().Width(150).Height(100).Crop("thumb").Gravity("face")
  },
  EagerAsync = true,
  EagerNotificationUrl = "http://mysite/my_notification_endpoint"
};
cloudinary.Upload(uploadParams);

Cloudinary also supports webhooks. With webhooks enabled, you can get a notification to your server when an upload is completed. This is useful when you use direct image uploading from the browser and you want to be informed whenever an image is uploaded by your users. Setting the NotificationUrl parameter tells Cloudinary to perform an asynchronous HTTP GET request to your server when the upload is complete. For example:

var uploadParams = new ImageUploadParams()
{
  File = new FileDescription(@"c:\my_image.jpg"),
  NotificationUrl = "http://mysite/my_notification_endpoint"
};
var uploadResult = cloudinary.Upload(uploadParams);

See the following blog post for more details: Webhooks, upload notifications and background image processing.

Upload method parameters

public ImageUploadResult Upload(ImageUploadParams parameters)

For a full list of the upload method parameters, see the Upload method in the Upload API Reference.