Implementando o protocolo tus em uma aplicação ASP.NET Core \| TreinaWeb               Promoção no ar   Matricule-se agora e garanta **54% de desconto**  

  Termina em   Tempo restante da oferta: 01 Horas 

 44 Min 

 31 Seg 

   Tempo restante da oferta: 01 44 31 

  [Assinar →](https://www.treinaweb.com.br/checkout/pagamento/plano/anual?cupom=TW-SCLIENTE26) 

   [                ](https://www.treinaweb.com.br)  Explorar  

 [ Quanto custa? ](#assinatura) [ FAQ ](https://www.treinaweb.com.br#faq) [Matricule-se](#assinatura) [ Entrar ](https://www.treinaweb.com.br/login) 

     [ Início ](https://www.treinaweb.com.br) [ Artigos ](https://www.treinaweb.com.br/blog) Implementando o protocolo tus em uma aplicação ASP.NET Core  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) [ ASP .NET ](https://www.treinaweb.com.br/blog/categoria/asp-net) [ .NET Core ](https://www.treinaweb.com.br/blog/categoria/net-core) 

# Implementando o protocolo tus em uma aplicação ASP.NET Core

 Realizar o upload de grandes arquivos pode ser uma dor de cabeça, mas o protocolo tus foi criado para facilitar este processo.

 [ Wladimilson M. Nascimento ](https://www.treinaweb.com.br/blog/autor/wladimilson-m-nascimento) 8 anos atrás

  ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/03/29132239/PROTOCOLO-TUS.png)  

Upload de arquivo é uma tarefa recorrente de qualquer aplicação web. Não importando a linguagem, é simples a implementação deste recurso na aplicação. Mas quando se trata de grandes arquivos, nos deparamos com algumas situações pouco agradáveis.

Por exemplo, você precisa upar um arquivo grande, de 10GB para mais. Espera por horas pelo seu upload. Quando está quase acabando, a conexão cai, por algo no servidor, falta de internet, energia, etc. O upload será abortado e você terá que iniciá-lo do zero. Só quem já passou por isso, sabe o quanto é frustrante.

Caso não tenha uma boa conexão, mesmo com arquivos pequenos, o upload pode ser frustrante. Já que geralmente neste tipo de situação, o usuário envia apenas o início do arquivo várias vezes.

Para tentar resolver este tipo de problema foi criado o protocolo **tus**.

## O que é o protocolo tus?

[tus](https://tus.io) é um protocolo aberto para “recuperação” de upload de arquivo em HTTP. Isso significa que o usuário não precisa reiniciar o upload sempre que ocorre um erro no processo ou mesmo enviar todo o arquivo em apenas uma conexão. Permitindo que o usuário pause o processo ou mesmo o envie em uma conexão instável.

Eles possuem uma comunidade bem ativa no [Github](https://github.com/tus) e grandes empresas que o implementam, como o Cloudflare e o Vimeo.

## Funcionamento do protocolo

Na [documentação](https://tus.io/protocols/resumable-upload.html) do protocolo é possível ver como ele funciona em detalhes, mas o processo é simples. O servidor recebe solicitações `POST`, sem conteúdo, que contenha no seu header, os atributos abaixo:

- **Upload-Length**: O tamanho, em bytes, do arquivo que será enviado;
- **Upload-Metadata**: Atributo opcional, que pode ser utilizado para enviar informações do arquivo para o servidor, como nome, extensão, etc. Essas informações devem ser organizadas em pares de chave-valor, separados por vírgula. A chave e valor devem ser separados por espaço. Assim, os pares de chave-valor não podem conter espaço ou vírgula;
- **Tus-Resumable**: Versão do protocolo.

Ele irá responder, com o código 201 (Created) e com os atributos abaixo no header:

- **Location**: URL que deve ser utilizada para o upload do arquivo;
- **Tus-Resumable**: Versão do protocolo.

Com isso, o usuário poderá utilizar a URL retornada na solicitação POST para efetuar o upload do arquivo. Este upload deve ser feito em solicitações `PATCH` e que contenha os atributos abaixo:

- **Upload-Offset**: Indica em qual ponto do arquivo (baseado em um array de bytes) o conteúdo enviado deve ser adicionado;
- **Content-Length**: Tamanho do conteúdo enviado;
- **Content-Type**: Tipo do conteúdo, que sempre deve ser `application/offset+octet-stream`;
- **Tus-Resumable**: Versão do protocolo.

Essas solicitações são respondidas com o código 204 (No Content) e com os atributos abaixo no header:

- **Upload-Offset**: Valor atual do upload-offset;
- **Tus-Resumable**: Versão do protocolo.

O servidor também pode aceitar solicitações `DELETE`, que permite excluir um upload não finalizado e `OPTIONS`, que retorna informações do uso do protocolo, como versão (`Tus-Version`), recursos implementados (`Tus-Extension`) e tamanho máximo de arquivo aceito (`Tus-Max-Size`).

[  ![C# (C Sharp) - Introdução ao ASP.NET Core](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/csharp.svg)   Curso C# (C Sharp) - Introdução ao ASP.NET Core Conhecer o curso ](https://www.treinaweb.com.br/curso/csharp-avancado-introducao-ao-aspnet-core)

## Implementando em uma aplicação ASP.NET Core

Pelo funcionamento, notamos que a sua implementação não é complexa, mas requer um pouco de trabalho. Felizmente há bibliotecas que facilitam a implementação deste protocolo em uma aplicação ASP.NET Core.

Para mostrá-lo na prática, vamos criar uma aplicação de exemplo:

```dos
dotnet new web -n ExemploTus

```

Na página do protocolo são [listadas](https://tus.io/implementations.html) algumas implementações dele, tanto para o lado do client quanto para o server. No caso do .NET, a implementação é recomentada para o servidor é a do Stefan Matsson, o [`tusdotnet`](https://github.com/tusdotnet/tusdotnet). Assim, a adicione no projeto:

```dos
dotnet add package tusdotnet

```

Para configurá-lo, na classe `Startup`, no método `Configure` adicione o código abaixo:

```csharp
app.UseTus(context => new DefaultTusConfiguration
{
    //Local onde os arquivos temporários serão salvos
    Store = new TusDiskStore(tempPath),
    // URL onde os uploads devem ser realizados.
    UrlPath = "/upload",
    Events = new Events
    {
        //O que fazer quando o upload for finalizado
        OnFileCompleteAsync = async ctx =>
        {
            var file = await ((ITusReadableStore)ctx.Store).GetFileAsync(ctx.FileId, ctx.CancellationToken);
            await ProcessFile.SaveFileAsync(file, env);
        }
    }
});

```

[  ![C# (C Sharp) - Introdução ao ASP.NET Core](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/csharp.svg)   Curso C# (C Sharp) - Introdução ao ASP.NET Core Conhecer o curso ](https://www.treinaweb.com.br/curso/csharp-avancado-introducao-ao-aspnet-core)

A biblioteca possui vários eventos, na [documentação](https://github.com/tusdotnet/tusdotnet/wiki) dela você pode conhecer quais são gerados.

No nosso caso, estamos apenas definindo a URL que será utilizada para o upload, o local onde os arquivos temporários serão salvos e estamos salvando em outro ponto do disco o arquivo quando seu upload for finalizado.

Não se esqueça de alterar o tamanho limite de arquivos aceitos pela aplicação. Isso pode ser feito no método `CreateWebHostBuilder` da classe `Program`:

```csharp
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup()
        .ConfigureKestrel(options =>
        {
            options.Limits.MaxRequestBodySize = null;
            options.Limits.MaxRequestBufferSize = null;
        });

```

Acima está sendo definido um limite “infinito”, mas você pode informar qualquer valor em bytes.

Para testar isso, vamos utilizar a biblioteca JS disponibilizada pelo tus, que pode ser baixada [aqui](https://github.com/tus/tus-js-client).

Com isso, poderemos definir um arquivo HTML, onde o upload será testado:

```html

    Upload de arquivo

            Upload de arquivo

                Para testar o protocolo, selecione um arquivo e clique em "Upload". Aguarde um pouco cancele, feche o navegador ou atualizado a página e inicie novamente :)

                Clique aqui para limpar o cache do navegador!

                    Selecione o arquivo

        var uploadProgress = document.getElementById('uploadProgress');
        var info = document.getElementById('info');
        var cancelUploadButton = document.getElementById('cancelUploadButton');
        var uploadButton = document.getElementById('uploadButton');
        var fileUpload = document.getElementById('fileUpload');
        var fileUploadLabel = document.getElementById('fileUploadLabel');
        var upload;

        function uploadFile() {
            var file = fileUpload.files[0];

            uploadProgress.value = 0;
            uploadProgress.removeAttribute('data');
            uploadProgress.style.display = 'block';

            disableUpload();

            info.innerHTML = '';

            upload = new tus.Upload(file,
                {
                    endpoint: 'upload/',
                    onError: onTusError,
                    onProgress: onTusProgress,
                    onSuccess: onTusSuccess,
                    metadata: {
                        filename: file.name,
                        contentType: file.type || 'application/octet-stream'
                    }
                });

            setProgressTest('Upload iniciado...');
            upload.start();
        }

        function cancelUpload() {
            upload && upload.abort();
            setProgressTest('Upload abortado');
            uploadProgress.value = 0;
            enableUpload();
        }

        function resetLocalCache(e) {
            e.preventDefault();
            localStorage.clear();
            alert('Cache limpo');
        }

        function onTusError(error) {
            alert(error);
            enableUpload();
        }

        function onTusProgress(bytesUploaded, bytesTotal) {
            var percentage = (bytesUploaded / bytesTotal * 100).toFixed(2);

            uploadProgress.value = percentage;
            setProgressTest(bytesUploaded + '/' + bytesTotal + ' bytes uploado');
        }

        function onTusSuccess() {
            setProgressTest('Upload finalizado!');
            enableUpload();
        }

        function setProgressTest(text) {
            info.innerHTML = text;
        }

        function enableUpload() {
            uploadButton.removeAttribute('disabled');
            cancelUploadButton.setAttribute('disabled', 'disabled');
        }

        function disableUpload() {
            uploadButton.setAttribute('disabled', 'disabled');
            cancelUploadButton.removeAttribute('disabled');
        }

        function alterarNome(){
            var fileName = fileUpload.files[0].name;
            fileUploadLabel.innerHTML = fileName;
        }

```

Ao executar a aplicação, poderemos testar o upload de um arquivo grande e ver o resultado:

![](https://dkrn4sk0rn31v.cloudfront.net/2019/03/29115144/upload.gif)

Você pode ver o código desta aplicação de exemplo no meu Github, [aqui](https://github.com/wladimilson/exemplotus).

## Conclusão

Caso a sua aplicação necessite efetuar o upload de arquivos grandes, devido ao seu poder, adicione o suporte ao protocolo tus. Isso irá facilitar muito o envio de arquivos para os usuários.

E como vimos, é muito simples implementar este suporte em uma aplicação ASP.NET Core. Assim, não há desculpa para não utilizar este protocolo.

- [ #.NET Core ](https://www.treinaweb.com.br/blog/tag/net-core)
- [ #ASP .NET Core ](https://www.treinaweb.com.br/blog/tag/asp-net-core)
- [ #protocolo tus ](https://www.treinaweb.com.br/blog/tag/protocolo-tus)

Autor

 ![Wladimilson M. Nascimento](//secure.gravatar.com/avatar/f0dd442f156a3eacd2880e9cd0eafbd1?d=mm)

## Wladimilson M. Nascimento

 Instrutor, nerd, cinéfilo e desenvolvedor nas horas vagas. Graduado em Ciências da Computação pela Universidade Metodista de São Paulo. 

 [Todos os artigos](https://www.treinaweb.com.br/blog/autor/wladimilson-m-nascimento)  

## Continue estudando

 Transforme leitura em prática com os cursos e formações da TreinaWeb.

 [Ver cursos](https://www.treinaweb.com.br/cursos)   

  Continue lendo

## Artigos relacionados

- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/01/28160855/websockts-php-400x280.png)  [ PHP ](https://www.treinaweb.com.br/blog/categoria/php) 

     7 anos atrás

    ##  [ Aplicações em tempo real com PHP usando WebSockets ](https://www.treinaweb.com.br/blog/aplicacoes-em-tempo-real-com-php-usando-websockets) 

     Neste artigo veremos uma introdução a WebSockets com a criação de um servidor em PHP e usando o navegador do usuário como cliente.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/04/16095041/OCELOT-400x280.png)  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

     8 anos atrás

    ##  [ Criando um API Gateway com ASP.NET Core e Ocelot ](https://www.treinaweb.com.br/blog/criando-um-api-gateway-com-asp-net-core-e-ocelot) 

     Conheça o conceito de API Gateway e veja como criá-lo em uma aplicação ASP.NET utilizando a biblioteca Ocelot.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2018/05/03175136/NET-CORE-2.1-400x280.png)  [ Desenvolvimento Back-end ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento-back-end) 

     8 anos atrás

    ##  [ Novos recursos do ASP.NET Core 2.1 ](https://www.treinaweb.com.br/blog/novos-recursos-do-asp-net-core-2-1) 

     Conheça os novos recursos do ASP.NET Core 2.1.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2022/03/o-que-e-fastapi-400x280.png)  [ Desenvolvimento Back-end ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento-back-end) 

     4 anos atrás

    ##  [ Criando o primeiro CRUD com FastAPI ](https://www.treinaweb.com.br/blog/criando-o-primeiro-crud-com-fastapi) 

     Neste artigo nós iremos aprender um pouco mais sobre o FastAPI durante o desenvolvimento de uma API com todas as operações de CRUD.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2023/05/NEST-JS-UPLOAD-ARQUIVOS-400x280.png)  [ Desenvolvimento Back-end ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento-back-end) 

     3 anos atrás

    ##  [ Guia do framework NestJS ](https://www.treinaweb.com.br/blog/guia-do-framework-nestjs) 

     Neste guia do framework NestJS vamos fazer um compilado de tópicos úteis sobre o framework, desde criar um projeto básico até autenticação.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/05/01125223/react-php-imagem-400x280.png)  [ PHP ](https://www.treinaweb.com.br/blog/categoria/php) 

     8 anos atrás

    ##  [ Introdução à programação assíncrona em PHP usando o ReactPHP ](https://www.treinaweb.com.br/blog/introducao-a-programacao-assincrona-em-php-usando-o-reactphp) 

     Uma introdução à programação assíncrona com PHP e uso básico dos componentes do ReactPHP.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/08/24120107/streams-400x280.jpg)  [ PHP ](https://www.treinaweb.com.br/blog/categoria/php) 

     7 anos atrás

    ##  [ Stream Wrappers personalizados no PHP ](https://www.treinaweb.com.br/blog/stream-wrappers-personalizados-no-php) 

     Veja como Stream Wrappers personalizados podem ser criados em PHP para se trabalhar com streams usando as funções nativas da linguagem. A SDK para PHP da AWS e do Google Cloud utilizam, bem como outros serviços.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/01/05103838/SIGNALR-400x280.png)  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

     7 anos atrás

    ##  [ Aplicações em tempo real com ASP.NET Core SignalR ](https://www.treinaweb.com.br/blog/aplicacoes-em-tempo-real-com-asp-net-core-signalr) 

     Aprenda como criar uma streaming api utilizando a biblioteca de aplicações em templo real, SignalR.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/08/01225056/CERTIFICADO-SSL-400x280.png)  [ Tecnologia ](https://www.treinaweb.com.br/blog/categoria/tecnologia) 

     7 anos atrás

    ##  [ Para que serve o certificado SSL? ](https://www.treinaweb.com.br/blog/para-que-serve-o-certificado-ssl) 

     Confira neste artigo o que é um certificado SSL e como ele funciona.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/07/AWS-VPC-400x280.png)  [ Amazon ](https://www.treinaweb.com.br/blog/categoria/amazon) 

     6 anos atrás

    ##  [ O que é VPC e como ela funciona? ](https://www.treinaweb.com.br/blog/o-que-e-vpc-e-como-ela-funciona) 

     A VPC é o principal serviço de rede privada na AWS e ela tem uma íntima ligação em como suas aplicações estarão distribuídas dentro dos servidores da AWS. Vamos entender qual é a sua importância e o que podemos fazer com uma VPC na AWS.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/12/19182504/slim-framework-400x280.png)  [ Desenvolvimento Back-end ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento-back-end) 

     7 anos atrás

    ##  [ O que é o Slim Framework? ](https://www.treinaweb.com.br/blog/o-que-e-o-slim-framework) 

     Veja neste artigo o que é e as principais características do Slim Framework.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/10/18095832/capa-elton-symfony-400x280.png)  [ PHP ](https://www.treinaweb.com.br/blog/categoria/php) 

     7 anos atrás

    ##  [ Symfony Componentes: o que são e qual sua importância para o ecossistema PHP ](https://www.treinaweb.com.br/blog/symfony-componentes-o-que-sao-e-qual-sua-importancia-para-o-ecossistema-php) 

     Entenda o que são os componentes do Symfony, o que eles fazem, quais as vantagens e desvantagens de utilizá-los. Além disso falaremos da importância deles para o ecossistema PHP.

     Ler artigo

## Um ano de acesso total para você viver de programação.

 Todos os cursos e formações da TreinaWeb numa única assinatura, com professores que atuam no mercado, suporte direto e certificados. Do primeiro `console.log` ao mercado de trabalho.

- **1 ano** de acesso a **todos os cursos**
- Cursos novos **toda semana**
- Suporte **direto com professores**
- Plano de carreira **personalizado**
- **Certificados digitais** inclusos
- **Aplicativos** para Android e iOS, com **acesso offline**

    **Garantia incondicional de satisfação** 

 Teste por 7 dias e, se não fizer sentido para você, devolvemos seu dinheiro.

### Acesso completo a todos os cursos e dezenas de Formações.

 12 meses 

  Economize R$ 840,00  54% OFF 

 de 12x R$ 129,00 por apenas

 12x  R$ 59,00

 sem juros no cartão de crédito ou R$ 599,00 à vista

  Oferta termina em  **01h 44min 31s**

- Acesso imediato e ilimitado durante 1 ano.
- Plano de carreira personalizado.
- Suporte direto com professores.
- E muito mais!

 [Matricule-se agora](https://www.treinaweb.com.br/checkout/pagamento/plano/anual?cupom=TW-SCLIENTE26)

     [                ](https://www.treinaweb.com.br)

 Escola online de programação, tecnologia e IA.

- [  ](https://www.facebook.com/TreinaWeb/)
- [  ](https://www.instagram.com/treinaweb/)
- [  ](https://www.youtube.com/user/TreinaWeb)
- [  ](https://twitter.com/treinaweb)
- [  ](https://www.linkedin.com/company/treinaweb)
- [  ](https://github.com/treinaweb)

## Inscreva-se em nossa newsletter

Receba lançamentos, promoções e novidades.

   Seu nome     Seu WhatsApp     Seu melhor e-mail   Inscrever-se 

## Cursos

- [ Base para Devs ](https://www.treinaweb.com.br/categoria/base-para-devs)
- [ Front-end ](https://www.treinaweb.com.br/categoria/desenvolvimento-front-end)
- [ Back-end ](https://www.treinaweb.com.br/categoria/desenvolvimento-back-end)
- [ Mobile ](https://www.treinaweb.com.br/categoria/desenvolvimento-mobile)
- [ Bancos de Dados ](https://www.treinaweb.com.br/categoria/bancos-de-dados)
- [ Cloud ](https://www.treinaweb.com.br/categoria/cloud-computing)
- [ IA ](https://www.treinaweb.com.br/categoria/ia)
- [ E mais ](https://www.treinaweb.com.br/categoria/e-mais)
- [ Ver todos os cursos ](https://www.treinaweb.com.br/cursos)

## Conteúdo

- [ Formações ](https://www.treinaweb.com.br/formacoes)
- [ Projetos práticos ](https://www.treinaweb.com.br/projetos-praticos)
- [ Direto ao ponto ](https://www.treinaweb.com.br/direto-ao-ponto)
- [ Planos ](https://www.treinaweb.com.br#assinatura)
- [ Depoimentos ](https://www.treinaweb.com.br#depoimentos)
- [ Comunidade ](https://www.treinaweb.com.br#comunidade)
- [ Corpo docente ](https://www.treinaweb.com.br#docente)

## A empresa

- [ Sobre a TreinaWeb ](https://www.treinaweb.com.br#sobre)
- [ Perguntas frequentes ](https://www.treinaweb.com.br#faq)
- [ Vantagens de estudar na TreinaWeb ](https://www.treinaweb.com.br/vantagens-de-estudar-na-treinaweb)
- [ Cursos para empresas ](https://www.treinaweb.com.br/empresas)
- [ Sugira um novo curso ](https://www.treinaweb.com.br/sugerir-curso)
- [ Trabalhe conosco ](https://www.treinaweb.com.br/trabalhe-conosco)
- [ Artigos ](https://www.treinaweb.com.br/blog)
- [ Desenvolvedores e agentes ](https://www.treinaweb.com.br/developers)
- [ Contato ](https://www.treinaweb.com.br/contato)
- [ Política de privacidade ](https://www.treinaweb.com.br/politica-de-privacidade)
- [ Termos de uso ](https://www.treinaweb.com.br/termos-de-uso)

## Baixe nosso aplicativo

 [   Disponível na **App Store**  ](https://apps.apple.com/us/app/treinaweb/id1322729447) [   Disponível no **Google Play**  ](https://play.google.com/store/apps/details?id=br.com.treinaweb.mobile) 

  Av. Paulista, 1765, Conj 71 e 72 · Bela Vista · São Paulo · SP · 01311-200   © 2004 – 2026 TreinaWeb Tecnologia LTDA · CNPJ 06.156.637/0001-58
