2

I need to write a api restfull with asp.net that receive in the body a json like :

"{
    \"name\" : \"name of the file\",
    \"path\" : \"path of the file\",
    \"body\" : \"body of th file\"
}"

and write a file in the server with the data from this json.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;

namespace tool_put.Controllers
{

    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {      
        [HttpPost]
        public String Post([FromBody] string value)
        {
            dynamic obj = JsonConvert.DeserializeObject(value);
            String path = obj.path + obj.name + ".txt";
            //StreamWriter Data = new StreamWriter(MapPath("~/"+path), (System.Text.Encoding)true);
            // Data.WriteLine(obj.body);

            return "true";
        }
    }
}

I used visual studio on mac and when i run this on localhost and try to perform the http post from postman the file that wish didnt create. Note he comments because this solution with the StreamWriter object didnt work . How can solve this ? Is there any other method to write some text in a txt file on the server ?

haldo
  • 14,512
  • 5
  • 46
  • 52

2 Answers2

4

If you're using ASP.NET core then I would recommend the doing following.

Create a DTO (Data Transfer Object) and let framework model binding handle the serialization/deserialization for you.

public class FileDto
{
    public string Name { get; set; }
    public string Path { get; set; }
    public string Body { get; set; }
}

Asp.Net Core does not have an equivalent of Server.MapPath. To get the web root path you can implement IWebHostEnvironment as detailed here.

However, the example below simply uses a hard-coded value. I'd recommend returning IActionResult for your RESTful service. An HttpPost should return a Created 201 response on success. The below code will return the a 201 Created status and the file DTO in the body of the response.

[HttpPost]
public IActionResult Post([FromBody] FileDto model)
{
    string directory = System.IO.Path.Combine(@"C:\temp\myfiles", model.Path);
    
    // TODO verify directory exists, Name is not null, Path is not null, Body is not null

    string fileName = model.Name + ".txt";
    string fullPath = System.IO.Path.Combine(directory, fileName);

    // simplest way to write to file
    System.IO.File.WriteAllText(fullPath, model.Body);
    
    return Created("http://url/to/your/new/file", model);
}

If you want to append text to an existing file then you can use File.AppendAllText(path, text).

The path received by the API may not exist, you will need to handle the case when it doesn't exist and decide what to do. For example, you could create the directory, or return a 404 NotFound or 500 ServerError.

If you don't know where the data is coming from allowing API clients/users to select/create the file path is probably not a good idea (what if a user/client sent "path": "../.." for the path, for example).

haldo
  • 14,512
  • 5
  • 46
  • 52
1

You can use this code to create your file

 using(StreamWriter sw = File.AppendText("your path"))
 {

      sw.WriteLine("your text");                     

  }     
sayah imad
  • 1,507
  • 3
  • 16
  • 24