venerdì 17 novembre 2017

XE One Day - Performance & Optimization


XE.NET ha organizzato per sabato 18 novembre un’intera giornata dedicata a tecniche e tecnologie per spingere le performance delle nostre applicazioni over the top!

Per info ed iscrizioni: http://www.xedotnet.org/eventi/

martedì 18 aprile 2017

Angular Day 2017

L'evento italiano su Angular

Si parlerà di nuove metodologie di sviluppo, best practice, casi di successo, qualità del codice, modularizzazione, form, direttive custom, typescript.

Per maggiori info http://2017.angularday.it/

venerdì 10 febbraio 2017

Web API - POST Content and Data with a MultipartFormDataStreamProvider

C# .NET Framework 4.0, Web API, Newtonsoft.Json.dll

I want to send content file and data to a Web API service, in this case a pdf document and some metadata about it.
In first time, I have developed a custom MultipartFormDataStreamProvider

// We implement MultipartFormDataStreamProvider to override the filename of File which
// will be stored on server, or else the default name will be of the format like Body-
// Part_{GUID}. In the following implementation we simply get the FileName from
// ContentDisposition Header of the Request Body.
public class CustomMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
{
    public CustomMultipartFormDataStreamProvider(string path) : base(path)
    {}

    public override string GetLocalFileName(HttpContentHeaders headers)
   {
        return headers.ContentDisposition.FileName.Replace("\"", string.Empty);
   }             

   /// <summary>
   /// Gets the attachment.
   /// </summary>
   /// <returns></returns>
   public AttachmentModel GetAttachment()
   {
       try
       {
                // This is a custom object.
                AttachmentModel attachment = null;

                var key = FormData.AllKeys[0];

                var strings = FormData.GetValues(key);
                if (strings != null)
                {
                    attachment = JsonConvert.DeserializeObject<AttachmentModel>(strings[0]);
                }

                return attachment;
        }
        catch (Exception ex)
        {
            return null;
         }
    }

Then I ‘ve developed this ApiController:

public class AttachmentController : ApiController
{
[HttpPost]
[Authorize]
public async Task<HttpResponseMessage> Post()
{
    string imageFile = null;
    FileStream fileStream = null;
    try
    {
        #region Check validity

        // Check whether the POST operation is MultiPart?
        if (!Request.Content.IsMimeMultipartContent())
        {                                                                            
            return Request.CreateResponse(HttpStatusCode.OK, "File format not valid.");
        }

        // This is a folder where we save the attachment temporarily.
        string documentUploadPath = System.Configuration.ConfigurationManager.AppSettings["DocumentUploadPath"];
        string root = string.Concat(HostingEnvironment.MapPath("~/"), documentUploadPath);

        CustomMultipartFormDataStreamProvider provider = new CustomMultipartFormDataStreamProvider(root);
        
        // Read all contents of multipart message into CustomMultipartFormDataStreamProvider.
        await Request.Content.ReadAsMultipartAsync(provider);

        imageFile = provider.FileData[0].LocalFileName;

        if (string.IsNullOrEmpty(imageFile))
        {                                                                            
            return Request.CreateResponse(HttpStatusCode.OK, "File not found.");
        }

        try
        {
            fileStream = new FileStream(imageFile, FileMode.Open);
        }
        catch
        {                                                                            
            return Request.CreateResponse(HttpStatusCode.OK, "Attachment not recognized.");
        }
       
        // This is a custom object.
         AttachmentModel Attachment = provider.GetAttachment();

        if (Attachment == null)
        {                                                                            
            return Request.CreateResponse(HttpStatusCode.OK, "Attachment not recognized.");
        }

        MemoryStream memoryStream = new MemoryStream();
        fileStream.CopyTo(memoryStream);
        Attachment.Content = memoryStream.ToArray();

        #endregion

        // Other internal consideration and operations.
        // ...
        
        var response = Request.CreateResponse(HttpStatusCode.OK, “OK”;

        return response;
    }
    catch (Exception ex)
    {                                                             
        HttpError httpError = new HttpError {Message = "Internal error."};
        return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, httpError);
    }
    finally
    {
        if (imageFile != null && File.Exists(imageFile))
        {
            if (fileStream != null)
            {
                fileStream.Close();
                fileStream.Dispose();
            }
            File.Delete(imageFile);
        }
    }
 }
  
Ok. For testing I have used fiddler with a script like this:


Content-Type: multipart/form-data; boundary=-------------------------acebdf13572468
Host: localhost
Connection: keep-alive
Cache-Control: max-age=0
Accept: application/json, text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: it-IT,en;q=0.8
Content-Length: 225317

Request body:

---------------------------acebdf13572468
Content-Disposition: form-data; name="fieldNameHere"; filename="test.pdf"
Content-Type: application/pdf

<@INCLUDE *C:\temp\test.pdf*@>
---------------------------acebdf13572468
Content-Disposition: form-data; name="attachment"

{
  "IdProtocol": "1",
  "application": "TEST",
  "filename": "test.pdf"
}
---------------------------acebdf13572468--

It is very important to close the request with these two minus signs!



Finally a C# function for calling this web service:

private bool SendAttachment(AttachmentModel attachment)
{
     // This is a custom object.
     // AttachmentModel attachment

     HttpClient client = new HttpClient();
                                              
     using (var content = new MultipartFormDataContent())
     {
         var values = new[]
         {
             new KeyValuePair<string, string>("attachment", JsonConvert.SerializeObject(attachment))
         };

         foreach (var keyValuePair in values)
         {
             content.Add(new StringContent(keyValuePair.Value), keyValuePair.Key);
         }

         var fileContent = new ByteArrayContent(attachment.Content);
         fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
         {
             FileName = attachment.NomeFile
         };
         content.Add(fileContent);

         var requestUri = "http://localhost/AttachmentManagerService/api/attachment";
         var result = client.PostAsync(requestUri, content);
         result.Wait();

         if (result.Result.IsSuccessStatusCode)
         {
             // check json format
             string responseContent = result.Result.Content.ReadAsStringAsync().Result;

             // if parse not throw exceptions, deserialize string...
                                                                             
             return true;
         }
         else
         {
             return false;
         }
     }
 }

I hope it is clear, otherwise if you want to also send me an email.


Kind regards!

mercoledì 7 settembre 2016

How to create a subfolder in a SQL Server FileTable


SQL Server 2012

The scope of this post is that to explain how to create a subfolder in a SQL Server FileTable (Documents). I suppose that the FileTable already exists.

I want to create a subfolder like this:

{root}\{folder1}\{folder2}\{filename}

and to get the new hierarchyID for the path, I use this formula:

parentpath.ToString()

 + CONVERT(VARCHAR(20), CONVERT(BIGINT, SUBSTRING(CONVERT(BINARY(16), NEWID()),

                                                  1, 6))) + '.'

 + CONVERT(VARCHAR(20), CONVERT(BIGINT, SUBSTRING(CONVERT(BINARY(16), NEWID()),

                                                  7, 6))) + '.'

 + CONVERT(VARCHAR(20), CONVERT(BIGINT, SUBSTRING(CONVERT(BINARY(16), NEWID()),

                                                  13, 4))) + '/'

This is the T-SQL code:

CREATE PROCEDURE [dbo].[SetDocumentContent]
                @IdFileData bigint,
                @file_stream image
AS
BEGIN
                DECLARE @FileName varchar(255)
                DECLARE @DocumentClassification varchar(50)
                DECLARE @ETSIdImpianto int

                DECLARE @DocumentClassification_path_locator hierarchyid
                DECLARE @ETSIdImpianto_path_locator hierarchyid
                DECLARE @FileName_path_locator hierarchyid

                -- Metadata to identify the correct document. The FileData is my internal table.            
SELECT @FileName = Name, @DocumentClassification = DCT.Description, @ETSIdImpianto=ETSIdImpianto
                               FROM FileData FD INNER JOIN DocumentClassificationType DCT
                               ON FD.IdDocumentClassificationType = DCT.Id  WHERE FD.Id = @IdFileData

                -- 1. If folder1 exists      
                SELECT @DocumentClassification_path_locator = path_locator FROM Documents
                WHERE name = @DocumentClassification AND is_directory = 1

                IF (@DocumentClassification_path_locator IS NULL)
                BEGIN
                               INSERT INTO Documents
        ( name
        , is_directory)
    VALUES
        ( @DocumentClassification
        , 1)

                               -- Get the folder1
                               SELECT @DocumentClassification_path_locator = path_locator FROM Documents
                               WHERE name = @DocumentClassification AND is_directory = 1
                END

                -- 2. If folder2 exists      
                SELECT @ETSIdImpianto_path_locator = path_locator FROM Documents
                WHERE name = CAST(@ETSIdImpianto as varchar) AND is_directory = 1

                IF (@ETSIdImpianto_path_locator IS NULL)
                BEGIN
                               INSERT INTO Documents
        ( name                                                       
        , is_directory
                                                               , path_locator)
    VALUES
        ( CAST(@ETSIdImpianto as varchar)
        , 1
                                                               , @DocumentClassification_path_locator.ToString()
        + CONVERT(VARCHAR(20), CONVERT(BIGINT, SUBSTRING(CONVERT(BINARY(16), NEWID()),
                                                         1, 6))) + '.'
        + CONVERT(VARCHAR(20), CONVERT(BIGINT, SUBSTRING(CONVERT(BINARY(16), NEWID()),
                                                         7, 6))) + '.'
        + CONVERT(VARCHAR(20), CONVERT(BIGINT, SUBSTRING(CONVERT(BINARY(16), NEWID()),
                                                         13, 4))) + '/')

                               -- Get the folder2
                               SELECT @ETSIdImpianto_path_locator = path_locator FROM Documents
                               WHERE name = CAST(@ETSIdImpianto as varchar) AND is_directory = 1
                END

                -- 3. The FileName
                SELECT @FileName_path_locator = path_locator FROM Documents
                WHERE name = @FileName AND is_directory = 0 AND parent_path_locator = @ETSIdImpianto_path_locator

                IF (@FileName_path_locator IS NULL)
                BEGIN
                               INSERT INTO Documents
        ( name                                                       
                                                               , file_stream       
                                                               , path_locator)
    VALUES
        ( @FileName
                                                               , @file_stream
                                                               , @ETSIdImpianto_path_locator.ToString()
        + CONVERT(VARCHAR(20), CONVERT(BIGINT, SUBSTRING(CONVERT(BINARY(16), NEWID()),
                                                         1, 6))) + '.'
        + CONVERT(VARCHAR(20), CONVERT(BIGINT, SUBSTRING(CONVERT(BINARY(16), NEWID()),
                                                         7, 6))) + '.'
        + CONVERT(VARCHAR(20), CONVERT(BIGINT, SUBSTRING(CONVERT(BINARY(16), NEWID()),
                                                         13, 4))) + '/')                           

                               SELECT @FileName_path_locator = path_locator FROM Documents
                               WHERE name = @FileName AND is_directory = 0 AND parent_path_locator = @ETSIdImpianto_path_locator
                END

Bye!

martedì 31 maggio 2016

Angular Connect 2016

Europe’s Largest Angular Conference

AngularConnect is a 2-day, multi-track conference featuring the world’s leading Angular experts, including the core Angular team at Google.

lunedì 9 maggio 2016

jsDay 2016


THE MOST USED LANGUAGE
THE MOST NEEDED CONFERENCE

May 11th-12th 2016 — Verona, Italy

From the organizers of the phpDay, the first international conference on JavaScript in Italy.

http://2016.jsday.it/  #jsDay

mercoledì 27 gennaio 2016

Using HTTP POST method with Postman

I tried the POSTMAN (https://www.getpostman.com/) for testing my REST web services. It is a good tool and when I used it with the GET method all was ok but with the POST method (I had to upload a photo), some problems occurred because I did not understand how to use the Content-Type parameter. I tried to insert it in the “Headers” tab with other parameters but it did not work.

The solution is to select the form-data option in the “Body” tab, enter a type “File” parameter and then you have to select the file for uploading.



Then if you select the “Generate code snippet” you will see the Content-Type parameter like this:

Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW


Regards!