I need a C# code that will trigger a nprinting task. On our server we are not allowed to evoke html file, hence I can't use javascript attached.
The attached works just need to translate it to .net as I can't use html on our server
Javascripts below works just fine
<html>
<head>
</head>
<body>
<h1>NPrinting API task starter</h1>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script type="text/javascript">
(function(){
console.log("started")
var taskIDs=[
"f3ebd873-b310-4a22-a269-24ce81b8ce74"
]
$.ajax({
url: 'URL:4993/api/v1/login/ntlm',
xhrFields: {
withCredentials: true
}
}).done(function(data) {
console.log(data);
for(var i=0;i<taskIDs.length;i++){
$.ajax({
type: "POST",
url: 'URL:4993/api/v1/tasks/'+taskIDs[i]+'/executions',
xhrFields: {
withCredentials: true
}
}).done(function(data) {
console.log("task "+i);
console.log(data);
if(i==taskIDs.length)
open(location, '_self').close();
});
}
});
})();
<!-- open(location, '_self').close(); -->
</script>
</body>
</html>
C# code which I can't complete all the below works but doesn't start the task.
//Create the HTTP Request (authenticate) and add required headers
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL:4993/api/v1/login/ntlm");
CookieContainer cookies = new CookieContainer();
request.CookieContainer = cookies;
request.Method = "GET";
request.UserAgent = "Windows";
request.Accept = "application/json";
// specify to run as the current Microsoft Windows user
request.UseDefaultCredentials = true;
try
{
// make the web request and return the content
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader responseReader = new StreamReader(response.GetResponseStream());
string sResponseHTML = responseReader.ReadToEnd();
Console.WriteLine(sResponseHTML);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
//Create second HTTP request (get list of apps) and add required headers
HttpWebRequest secondRequest = (HttpWebRequest)WebRequest.Create(#"URL:4993/api/v1/tasks/f3ebd873-b310-4a22-a269-24ce81b8ce74/executions");
//assign cookie to request to maintain session
secondRequest.CookieContainer = cookies;
secondRequest.Method = "POST";
secondRequest.UserAgent = "Windows";
secondRequest.Accept = "application/json";
// specify to run as the current Microsoft Windows user
secondRequest.UseDefaultCredentials = true;
Thanks
I found a solution to the above, request.
Nprinting API task to run from C#
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Post_Request_API
{
class Program
{
static void Main(string[] args)
{
//Create the HTTP Request (authenticate) and add required headers
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(#"URL:4993/api/v1/login/ntlm");
//Assign custom SSL certificate validation method if certificate is untrusted
//request.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
CookieContainer cookies = new CookieContainer();
request.CookieContainer = cookies;
request.Method = "GET";
request.UserAgent = "Windows";
request.Accept = "application/json";
//Specify to run as the current Microsoft Windows user
request.UseDefaultCredentials = true;
try
{
// make the web request and return the content
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader responseReader = new StreamReader(response.GetResponseStream());
string sResponseHTML = responseReader.ReadToEnd();
Console.WriteLine(sResponseHTML);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
//Create second HTTP request to add a new user and required headers
HttpWebRequest secondRequest = (HttpWebRequest)WebRequest.Create(#"URL:4993/api/v1/tasks/f3ebd873-b310-4a22-a269-24ce81b8ce74/executions");
//Assign custom SSL certificate validation method if certificate is untrusted
//secondRequest.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
//Add the XSRF token
secondRequest.Headers.Add("X-XSRF-TOKEN", cookies.GetCookies(request.RequestUri)["NPWEBCONSOLE_XSRF-TOKEN"].Value);
secondRequest.CookieContainer = cookies;
secondRequest.Method = "POST";
secondRequest.UserAgent = "Windows";
secondRequest.Accept = "application/json";
secondRequest.ContentType = "application/json";
//Specify to run as the current Microsoft Windows user
secondRequest.UseDefaultCredentials = true;
//Prepare JSON object to send to the remote server
JsonUser user = new JsonUser();
user.ID = "";
user.type = "";
user.task = "";
user.created = "";
user.lastUpdate = "";
user.completed = "";
user.progress = "";
user.status = "Enqueued";
user.result = "";
user.priority = "";
string jUserString = JsonConvert.SerializeObject(user);
using (var streamWriter = new StreamWriter(secondRequest.GetRequestStream()))
{
streamWriter.Write(jUserString);
streamWriter.Flush();
streamWriter.Close();
}
try
{
HttpWebResponse response2 = (HttpWebResponse)secondRequest.GetResponse();
StreamReader responseReader2 = new StreamReader(response2.GetResponseStream());
string sResponseHTML2 = responseReader2.ReadToEnd();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public class JsonUser
{
public string ID { get; set; }
public string type { get; set; }
public string task { get; set; }
public string created { get; set; }
public string lastUpdate { get; set; }
public string completed { get; set; }
public string progress { get; set; }
public string status { get; set; }
public string result { get; set; }
public string priority { get; set; }
}
}
}
Related
I recently converted one of my controllers to a background Task, which returns an HTTPResponseMessage once the thread is completed. The issue i am facing is to get the download to pop up after the task is done. I have implemented SignalR as well for tracking the progress. Here is my controller code:
public async Task<IHttpActionResult> GetReportaync([FromUri] ReportRequestViewModel request)
{
var token = UnitOfWork.Start();
HostingEnvironment.QueueBackgroundWorkItem(CancellationToken =>
{
using (token)
{
try
{
HubFunctions.UpdateReportProgress(username, status);
var parameters = request.ToReportParams();
var report = ReportFactory.CreateReport(request.ReportExportType, IsVA());
var docStream = report.BuildReport(parameters);
if (request.SaveReport)
{
SaveDocumentToAmazon(request, report.FileName, docStream);
}
var GeneratedReport = GetFileAsResponseMessage(docStream.ToArray(), report.FileName, true);
ReportCacheDto generateReportDto1 = new ReportCacheDto()
{
Report = GeneratedReport,
Status = CacheConstants.Progress.Completed.ToString()
};
bool completed = SaveCacheReportProgress(key, generateReportDto1);
Request.CreateResponse(GeneratedReport);
HubFunctions.UpdateReportResult(new GenerateReportDto() { Message = "Import Completed", Success = true, Report = GeneratedReport }, username);
}
catch(Exception e)
{
LogHandler.LogError("An error occured", e);
Request.CreateResponse(HttpStatusCode.InternalServerError, e);
HubFunctions.UpdateReportResult(new GenerateReportDto() { Message = "Import Failed", Success = false, Report = Report }, username);
}
}
});
return Ok(new GenerateReportDto
{
Message = "Generate Started",
Success = true
});
}
Next is the return method called GetFileasResponse:
protected HttpResponseMessage GetFileAsResponseMessage(byte[] fileData, string filename, bool download = false)
{
var response = new HttpResponseMessage(HttpStatusCode.OK);
fileContent = fileData;
string fileType = string.Empty;
string extension = Path.GetExtension(filename.ToLower());
if(mediaTypeHeaderValueTypes.ContainsKey(extension))
{
fileType = mediaTypeHeaderValueTypes[extension].ToString();
}
else
{
fileType = "application/octet-stream";
}
Action<Stream, HttpContent, TransportContext> writeToStream = WriteToStream;
response.Content = new PushStreamContent(writeToStream, new MediaTypeHeaderValue(fileType));
var dispositionHeader = download ? "attachment" : "inline";
response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue(dispositionHeader)
{
/*
* See here:
* https://stackoverflow.com/questions/93551/how-to-encode-the-filename-parameter-of-content-disposition-header-in-http
* and here:
* https://msdn.microsoft.com/en-us/library/4fkewx0t(v=vs.110).aspx
*/
FileName = HttpUtility.UrlPathEncode(filename) // encodes " " as %20 which is what we want.
};
return response;
}
The issue really stems from the front end, because i can return the response file in my console log but i dont know how to have it to pop up as a download. Here is what i have attempted
ScorecardReportVM.prototype.ConnectToSignalRHub_ReportResult = function () {
var self = this;
var hub = $.connection.ReportResult;
hub.client.UpdateStatus = function (response) {
self.SetImportRunning(false);
var link = document.createElement('a');
link.href = response.Report;
document.body.appendChild(link);
link.click();
console.log(response);
};
};
Essentially signalR once completed returns:
public bool Success { get; set; }
public string Message { get; set; }
public HttpResponseMessage Report { get; set; }
Now my issue is how do i get the Report parameter to pop up as a download?
I have a problem with returning an error to html. So, I have web-app with "sql interpreter".
HTML
<button type="submit" onclick="executeSQL('interpreterSQL')">
<i class="fas fa-bolt"></i>
</button>
<textarea id="interpreterSQL" placeholder="❔❔❔"></textarea>
After entering a query into the interpreter, I run POST in javascript and shoot to spring:
POST in JavaScript
function executeSQL(interpreterSQL) {
var tmp = document.getElementById(interpreterSQL).value;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// Typical action to be performed when the document is ready:
var response = xhttp.responseText;
console.log("ok"+response);
}
};
xhttp.open("POST", "/user/executeSQL", true);
xhttp.send(tmp);
}
After that I handle the query in my service and return message to POST in my Controller:
Controller (POST in Spring)
#PostMapping(path = { "/user/executeSQL" })
public ModelAndView executeSQL(#RequestBody String tmp) {
String[] split = tmp.replace("\n", "").replace("\t", "").split(";");
String feedback = databaseTableService.executeSQL(split);
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("successMessage", feedback);
modelAndView.setViewName("/user/interpreterSQL");
return modelAndView;
}
Service which is used to execute native query
public String executeSQL(String[] split){
SessionFactory hibernateFactory = someService.getHibernateFactory();
Session session = hibernateFactory.openSession();
String message = null;
for (int i = 0; i < split.length; i++) {
try{
String query = split[i];
session.doWork(connection -> connection.prepareStatement(query).execute());
message = "Success";
}
catch(Exception e){
message = ((SQLGrammarException) e).getSQLException().getMessage();
}
}
session.close();
return message;
}
So finally we are in my controller which is ready to return value and we have message which is have information about sql exceptions. We are there:
And here is my question: How to get variable "feedback" in response?
I need to handle that value there i think:
but that "var response = xhttp.responseText" is returning all my HTML code. I need only parametr "feedback" from my controller.
Guys can someone help? :( I don't know how to send that parametr in return and handle it in javascript...
Maybe you can change your Controler method to return JSON response instead on ModelAndView
#PostMapping(path = { "/user/executeSQL" })
public ResponseEntity<Object> executeSQL(#RequestBody String tmp) {
String[] split = tmp.replace("\n", "").replace("\t", "").split(";");
Map<String,String> response = new HashMap<String, String>();
response.put("feedback", databaseTableService.executeSQL(split));
return new ResponseEntity<>( response , HttpStatus.OK);
}
Now you should be able to see the status
var response = xhttp.responseText;
console.log("ok"+response);
My web app currently allows users to upload media one-at-a-time using the following:
var fd = new FormData(document.forms[0]);
fd.append("media", blob); // blob is the image/video
$.ajax({
type: "POST",
url: '/api/media',
data: fd
})
The media then gets posted to a WebApi controller:
[HttpPost, Route("api/media")]
public async Task<IHttpActionResult> UploadFile()
{
if (!Request.Content.IsMimeMultipartContent("form-data"))
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string mediaPath = await _mediaService.UploadFile(User.Identity.Name, Request.Content);
return Ok(mediaPath);
}
Which then does something along the lines of:
public async Task<string> UploadFile(string username, HttpContent content)
{
var storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer imagesContainer = blobClient.GetContainerReference("container-" + user.UserId);
var provider = new AzureStorageMultipartFormDataStreamProvider(imagesContainer);
await content.ReadAsMultipartAsync(provider);
var filename = provider.FileData.FirstOrDefault()?.LocalFileName;
// etc
}
This is working great for individual uploads, but how do I go about modifying this to support batched uploads of multiple files through a single streaming operation that returns an array of uploaded filenames? Documentation/examples on this seem sparse.
public class AzureStorageMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
{
private readonly CloudBlobContainer _blobContainer;
private readonly string[] _supportedMimeTypes = { "images/png", "images/jpeg", "images/jpg", "image/png", "image/jpeg", "image/jpg", "video/webm" };
public AzureStorageMultipartFormDataStreamProvider(CloudBlobContainer blobContainer) : base("azure")
{
_blobContainer = blobContainer;
}
public override Stream GetStream(HttpContent parent, HttpContentHeaders headers)
{
if (parent == null) throw new ArgumentNullException(nameof(parent));
if (headers == null) throw new ArgumentNullException(nameof(headers));
if (!_supportedMimeTypes.Contains(headers.ContentType.ToString().ToLower()))
{
throw new NotSupportedException("Only jpeg and png are supported");
}
// Generate a new filename for every new blob
var fileName = Guid.NewGuid().ToString();
CloudBlockBlob blob = _blobContainer.GetBlockBlobReference(fileName);
if (headers.ContentType != null)
{
// Set appropriate content type for your uploaded file
blob.Properties.ContentType = headers.ContentType.MediaType;
}
this.FileData.Add(new MultipartFileData(headers, blob.Name));
return blob.OpenWrite();
}
}
Assuming your AzureStorageMultipartFormDataStreamProvider is similar to the same class mentioned on this blog, that is actually already processing multiple files if there are multiple files in the request.
So all you need to do is change your UploadFile to return a IEnumerable<string> and change your controller to have mediaPath as such.
So your MediaService would have:
var filenames = provider.FileData.Select(x => x.LocalFileName).ToList(); ;
return filenames;
And your controller would have:
var mediaPaths = await _mediaService.UploadFile(User.Identity.Name, Request.Content);
return Ok(mediaPaths);
Since you don't post the related codes with the AzureStorageMultipartFormDataStreamProvider class.
So I create a custom AzureStorageMultipartFormDataStreamProvider which inherits from the MultipartFileStreamProvider to enable the web api upload batched uploads of multiple files.
In the AzureStorageMultipartFormDataStreamProvider we could override the ExecutePostProcessingAsync method.
In this method, we could get the upload file data, then we could upload these data to the azure storage.
More details, you could refer to below codes. The total Controller.
public class UploadingController : ApiController
{
public Task<List<FileItem>> PostFile()
{
if (!Request.Content.IsMimeMultipartContent("form-data"))
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
var multipartStreamProvider = new AzureStorageMultipartFormDataStreamProvider(GetWebApiContainer());
return Request.Content.ReadAsMultipartAsync<AzureStorageMultipartFormDataStreamProvider>(multipartStreamProvider).ContinueWith<List<FileItem>>(t =>
{
if (t.IsFaulted)
{
throw t.Exception;
}
AzureStorageMultipartFormDataStreamProvider provider = t.Result;
return provider.Files;
});
}
public static CloudBlobContainer GetWebApiContainer(string containerName = "webapi-file-container")
{
// Retrieve storage account from connection-string
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
"your connection string");
// Create the blob client
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference(containerName);
// Create the container if it doesn't already exist
container.CreateIfNotExists();
// Enable public access to blob
var permissions = container.GetPermissions();
if (permissions.PublicAccess == BlobContainerPublicAccessType.Off)
{
permissions.PublicAccess = BlobContainerPublicAccessType.Blob;
container.SetPermissions(permissions);
}
return container;
}
}
public class FileItem
{
/// <summary>
/// file name
/// </summary>
public string Name { get; set; }
/// <summary>
/// size in bytes
/// </summary>
public string SizeInMB { get; set; }
public string ContentType { get; set; }
public string Path { get; set; }
public string BlobUploadCostInSeconds { get; set; }
}
public class AzureStorageMultipartFormDataStreamProvider : MultipartFileStreamProvider
{
private CloudBlobContainer _container;
public AzureStorageMultipartFormDataStreamProvider(CloudBlobContainer container)
: base(Path.GetTempPath())
{
_container = container;
Files = new List<FileItem>();
}
public List<FileItem> Files { get; set; }
public override Task ExecutePostProcessingAsync()
{
// Upload the files to azure blob storage and remove them from local disk
foreach (var fileData in this.FileData)
{
var sp = new Stopwatch();
sp.Start();
string fileName = Path.GetFileName(fileData.Headers.ContentDisposition.FileName.Trim('"'));
CloudBlockBlob blob = _container.GetBlockBlobReference(fileName);
blob.Properties.ContentType = fileData.Headers.ContentType.MediaType;
//set the number of blocks that may be simultaneously uploaded
var requestOption = new BlobRequestOptions()
{
ParallelOperationThreadCount = 5,
SingleBlobUploadThresholdInBytes = 10 * 1024 * 1024 ////maximum for 64MB,32MB by default
};
//upload a file to blob
blob.UploadFromFile(fileData.LocalFileName, options: requestOption);
blob.FetchAttributes();
File.Delete(fileData.LocalFileName);
sp.Stop();
Files.Add(new FileItem
{
ContentType = blob.Properties.ContentType,
Name = blob.Name,
SizeInMB = string.Format("{0:f2}MB", blob.Properties.Length / (1024.0 * 1024.0)),
Path = blob.Uri.AbsoluteUri,
BlobUploadCostInSeconds = string.Format("{0:f2}s", sp.ElapsedMilliseconds / 1000.0)
});
}
return base.ExecutePostProcessingAsync();
}
}
The result like this:
I would checkout uploading the media directly to the blob storage after getting the SAS token for all your files from the Web API in one request. Upload the files using a promise and http get from your client, which will parallelize the upload.
Which will be your right design and approach. Which will also increase your upload speed and reduce the latency.
I need to Purge all my Images in my Website which is using AKAMAI CDN.
I have written the code for purging one file.
PFB the code for single file purging.
But my requirement is to purge all files in the website.
Can anyone suggest how to achieve this.
Thanks
//
// © 2016 WorldVentures. All rights reserved.
//
using Akamai.EdgeGrid.Auth;
using Akamai.Utils;
using CMS;
using CMS.DataEngine;
using CMS.DocumentEngine;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
// Registers the custom module into the system
[assembly: RegisterModule(typeof(AkamaiPurge))]
public class AkamaiPurge : Module
{
// Module class constructor, the system registers the module under the name "CustomInit"
public AkamaiPurge()
: base("CustomInit")
{
}
// Contains initialization code that is executed when the application starts
protected override void OnInit()
{
base.OnInit();
// Assigns custom handlers to events
DocumentEvents.Insert.After += Document_Insert_After;
DocumentEvents.Update.After += Document_Update_After;
DocumentEvents.Delete.After += Document_Delete_After;
}
/// <summary>
/// Will be triggered when any document is added
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Document_Insert_After(object sender, DocumentEventArgs e)
{
// PurgeCache();
PurgeCacheAkamai();
}
/// <summary>
/// Will be triggered when any document is Updated
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Document_Update_After(object sender, DocumentEventArgs e)
{
//PurgeCache();
PurgeCacheAkamai();
}
/// <summary>
/// Will be triggered when any document is Deleted
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Document_Delete_After(object sender, DocumentEventArgs e)
{
//PurgeCache();
PurgeCacheAkamai();
}
/// <summary>
/// Following function will invalidate cache from Akamai server
/// </summary>
public void PurgeCache()
{
string secret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
string clientToken = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
string accessToken = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
string apiurl = "https://akab-7t5mh54r7lq3a7d7-js5q6mdtx42qimcn.purge.akamaiapis.net/ccu/v3/invalidate/url/production";
List<string> headers = new List<string>();
string httpMethod = "POST";
string data = "{\"hostname\": \"www.qa.worldventures.com\",\"objects\": [\"www.qa.worldventures.com/getmedia/9931b92a-c7f3-4a71-ab27-37e2b13572c0/should-be-here.jpg?width=2541&height=1811&ext=.jpg\"]}";
Stream uploadStream = null;
uploadStream = new MemoryStream(data.ToByteArray());
var uri = new Uri(apiurl);
var request = WebRequest.Create(uri);
request.Method = httpMethod;
var signer = new EdgeGridV1Signer();
var credential = new ClientCredential(clientToken, accessToken, secret);
signer.Sign(request, credential);
using (var result = signer.Execute(request, credential))
{
using (result)
{
using (var reader = new StreamReader(result))
{
string value = reader.ReadToEnd();
}
}
}
}
/// <summary>
/// Following function will invalidate cache from Akamai server
/// </summary>
public void PurgeCacheAkamai()
{
string secret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
string clientToken = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
string accessToken = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
string apiurl = "https://akab-7t5mh54r7lq3a7d7-js5q6mdtx42qimcn.purge.akamaiapis.net/ccu/v3/invalidate/url/production";
List<string> headers = new List<string>();
string httpMethod = "POST";
string outputfile = null;
string data = "{\"hostname\": \"www.qa.worldventures.com\",\"objects\": [\"www.qa.worldventures.com/getmedia/9931b92a-c7f3-4a71-ab27-37e2b13572c0/should-be-here.jpg?width=2541&height=1811&ext=.jpg\"]}";
int maxBodySize = 2048;
EdgeGridV1Signer signer = new EdgeGridV1Signer(null, maxBodySize);
ClientCredential credential = new ClientCredential(clientToken, accessToken, secret);
Stream uploadStream = null;
uploadStream = new MemoryStream(data.ToByteArray());
var uri = new Uri(apiurl);
var request = WebRequest.Create(uri);
foreach (string header in headers) request.Headers.Add(header);
request.Method = httpMethod;
Stream output = Console.OpenStandardOutput();
if (outputfile != null)
output = new FileInfo(outputfile).OpenWrite();
signer.Sign(request, credential, uploadStream);
using (var result = signer.Execute(request, credential, uploadStream))
{
using (output)
{
using (result)
{
using (var reader = new StreamReader(result))
{
string value = reader.ReadToEnd();
}
}
}
}
//using (var result = signer.Execute(request, credential))
//{
// using (result)
// {
// using (var reader = new StreamReader(result))
// {
// string value = reader.ReadToEnd();
// }
// }
//}
}
public void PurgeCacheAkamai2()
{
// Create a request using a URL that can receive a post.
WebRequest request = WebRequest.Create("https://akab-7t5mh54r7lq3a7d7-js5q6mdtx42qimcn.purge.akamaiapis.net/ccu/v3/invalidate/url/production");
// Set the Method property of the request to POST.
request.Method = "POST";
// Create POST data and convert it to a byte array.
string postData = "This is a test that posts this string to a Web server.";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-www-form-urlencoded";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
// Get the response.
WebResponse response = request.GetResponse();
// Display the status.
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
// Display the content.
Console.WriteLine(responseFromServer);
// Clean up the streams.
reader.Close();
dataStream.Close();
response.Close();
}
}
It depends on how you want to do it.
For example if you are still using CCU or Fast purge feature of akamai.
If you are using CCU or fast purge then best thing to do is, tag all your images to a dedicated CP Code.
Once done you can purge the CP Code which will intern purge all the images.
Few useful documents that you can refer for CCU:
https://developer.akamai.com/api/purge/ccu-v2/overview.html
For Fast Purge:
https://control.akamai.com/dl/customers/FIMA/Fast-Purge-QuickRef.pdf
https://github.com/akamai-open/api-kickstart/tree/master/examples
Thank,
Vinod
For introduction, I have problem with communication between servicestack and application written in ember.js via REST, I am using ember-uploader component to upload a file to service stack.
View hbs:
<table class="table table-bordered table-hover">
{{file-upload}}
</table>
component in coffee script
ABC.FileUploadComponent = Ember.FileField.extend(
url: "/api/upload"
filesDidChange: (->
uploadUrl = #get("url")
console.log uploadUrl
files = #get("files")
test = { fileName: "test" }
uploader = Ember.Uploader.create(
url: uploadUrl
)
uploader.upload(files[0],test) unless Ember.isEmpty(files)
console.log files
return
).observes("files")
)
component in javascript
ABC.FileUploadComponent = Ember.FileField.extend({
url: "/api/upload",
filesDidChange: (function() {
var files, test, uploadUrl, uploader;
uploadUrl = this.get("url");
console.log(uploadUrl);
files = this.get("files");
test = {
fileName: "test"
};
uploader = Ember.Uploader.create({
url: uploadUrl,
data: test
});
if (!Ember.isEmpty(files)) {
uploader.upload(files[0], test);
}
console.log(files);
}).observes("files")
});
My service model:
namespace ABC.Service.ServiceModel
{
public class Upload
{
[Route("/upload")]
public class UploadRequest : IRequiresRequestStream
{
public System.IO.Stream RequestStream { set; get; }
public object FileName { set; get; }
}
public class UploadResponse
{
public int Successed { set; get; }
}
}
}
My Service Method
namespace ABC.Service.Service
{
public class UploadService : ServiceBase // Service base inherites from ServiceStack.Service
{
public Upload.UploadResponse Post(Upload.UploadRequest request)
{
var req = base.Request;
var reqThatIwant = request.FileName;
return new Upload.UploadResponse() { Successed = 1 };
}
}
}
and here is screen from watch :
So my question is, how I have to change the code to get data marked as "2" into Request object marked as "1" (marked on the screen)?
Handling Raw Request Stream
When you use IRequiresRequestStream you're saying you want to take over deserializing the Request and access the raw input HTTP Request Body as a Stream. As a result ServiceStack wont attempt to read from the Request body and instead inject the HTTP Request stream - in this case the only Request DTO parameters it will be able to populate are those on the /pathinfo or ?QueryString, e.g:
[Route("/upload/{FileName}")]
public class Upload : IRequiresRequestStream
{
public Stream RequestStream { set; get; }
public string FileName { set; get; }
}
Accessing FormData HTTP POSTs
But if the JavaScript component is sending you HTTP POST FormData (i.e. application/x-www-form-urlencoded or multipart/form-data) than it's very unlikely you want to treat it like a raw Request Stream but instead access the Request.FormData or Request.Files that were posted.
Handling File Upload examples
Based on your screenshot, the HTTP Request Content-Type is multipart/form-data which case you will most likely be able to access any uploaded files using Request.Files.
Some examples of accessing HTTP Uploaded Files are available in the Live Demos:
Imgur - Save uploaded files to a MemoryStream
public object Post(Upload request)
{
foreach (var uploadedFile in Request.Files
.Where(uploadedFile => uploadedFile.ContentLength > 0))
{
using (var ms = new MemoryStream())
{
uploadedFile.WriteTo(ms);
WriteImage(ms);
}
}
return HttpResult.Redirect("/");
}
Rest Files - Save to FileSystem
public void Post(Files request)
{
var targetDir = GetPath(request);
var isExistingFile = targetDir.Exists
&& (targetDir.Attributes & FileAttributes.Directory) != FileAttributes.Directory;
if (isExistingFile)
throw new NotSupportedException(
"POST only supports uploading new files. Use PUT to replace contents of an existing file");
if (!Directory.Exists(targetDir.FullName))
Directory.CreateDirectory(targetDir.FullName);
foreach (var uploadedFile in base.Request.Files)
{
var newFilePath = Path.Combine(targetDir.FullName, uploadedFile.FileName);
uploadedFile.SaveTo(newFilePath);
}
}
HTTP Benchmarks - Handle multiple and .zip uploaded files
public object Post(UploadTestResults request)
{
//...
foreach (var httpFile in base.Request.Files)
{
if (httpFile.FileName.ToLower().EndsWith(".zip"))
{
using (var zip = ZipFile.Read(httpFile.InputStream))
{
var zipResults = new List<TestResult>();
foreach (var zipEntry in zip)
{
using (var ms = new MemoryStream())
{
zipEntry.Extract(ms);
var bytes = ms.ToArray();
var result = new MemoryStream(bytes).ToTestResult();
zipResults.Add(result);
}
}
newResults.AddRange(zipResults);
}
}
else
{
var result = httpFile.InputStream.ToTestResult();
newResults.Add(result);
}
}
}