locked
Why this GET action can't handle Fetch Data RRS feed

  • Question

  • User887623398 posted

    Hello,

    Why this get Action works? is it about URL?

    Here comes my code:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Http;
    using Microsoft.EntityFrameworkCore;
    //using Microsoft.EntityFrameworkCore;
    
    namespace imageEditor3
    {
    
        public class FileContext : DbContext
        {
            public DbSet<FileModel> FileModels { get; set; }
        }
        public class FileModel
        {
            [Key]
            [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
            public int FileId { get; set; }
            public string FileName { get; set; }
            public IFormFile FormFile { get; set; }
        }
    }
    

    Controller:

    namespace imageEditor3.Controllers
    {
        using Microsoft.AspNetCore.Http;
        using Microsoft.AspNetCore.Mvc;
        using Microsoft.Extensions.Logging;
        using System;
        using System.Collections.Generic;
        using System.IO;
        using System.Linq;
    
        
        [Route("[Controller]")]
    
        [ApiController]
    
        public class WeatherForecastController : ControllerBase
        {
            
            private static readonly string[] Summaries = new[]
            {
                "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
            };
    
           
            private readonly ILogger<WeatherForecastController> _logger;
    
           
            private IEnumerable<FileModel> myFile;
    
    
            public WeatherForecastController(ILogger<WeatherForecastController> logger)
            {
                _logger = logger;
            }
    
            
     
            [Route("WeatherForecast/Post")]
            [HttpPost]
            public IActionResult Post([FromForm] FileModel file)
            {
                try
                {
                    string path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", file.FileName);
    
                    using (Stream stream = new FileStream(path, FileMode.Create))
                    {
    
                        file.FormFile.CopyTo(stream);
    
                    }
    
                    return StatusCode(StatusCodes.Status201Created);
    
                }
    
                catch (Exception)
                {
                    return StatusCode(StatusCodes.Status500InternalServerError);
                }
            }
    
            
    
    
            
             [Route("WeatherForecast/Get")]
            [HttpGet]
            public IEnumerable<FileModel> Get()
            {
                using (var Context = new FileContext())
                {
                     myFile = Context.FileModels.ToArray();
                }
    
                return myFile;
            }
    
    
        }
    
    }

    FetchData:

    import React, { Component } from 'react';
    
    export class FetchData extends Component {
      static displayName = FetchData.name;
    
      constructor(props) {
        super(props);
        this.state = { forecasts: [], loading: true };
      }
    
      componentDidMount() {
        this.populateWeatherData();
      }
    
      static renderForecastsTable(forecasts) {
        return (
          <table className='table table-striped' aria-labelledby="tabelLabel">
            <thead>
              <tr>
                <th>FileId</th>
                <th>FileName (C)</th>
                <th>FormFile (F)</th>
                <th>Summary</th>
              </tr>
            </thead>
            <tbody>
              {forecasts.map(forecast =>
                <tr key={forecast.FileId}>
                  <td>{forecast.FileName}</td>
                  <td>{forecast.FormFile}</td>
                  //<td>{forecast.temperatureF}</td>
                  //<td>{forecast.summary}</td>
                </tr>
              )}
            </tbody>
          </table>
        );
      }
    
      render() {
        let contents = this.state.loading
          ? <p><em>Loading...</em></p>
          : FetchData.renderForecastsTable(this.state.forecasts);
    
        return (
          <div>
            <h1 id="tabelLabel" >Weather forecast</h1>
            <p>This component demonstrates fetching data from the server.</p>
            {contents}
          </div>
        );
      }
    
      async populateWeatherData() {
          const response = await fetch('weatherforecast/weatherforecast/Get');
        const data = await response.json();
        this.setState({ forecasts: data, loading: false });
      }
    }
    

    It seems the problem is related to the database and get action! not the Get URL. The Post Action works well. Should I add dbContext in the startup?

    Do you see any problem with it?

    thanks

    Friday, January 15, 2021 11:49 PM

Answers

  • User475983607 posted

    If you just took a few minutes to go through the tutorials suggested above you'd probably be done by now. anyway, below is a working example.

    Entity configuration, models, and view models.

        public class Image
        {
            public int ImageId { get; set; }
            public string FileName { get; set; }
            public string Description { get; set; }
            public string Path { get; set; }
            public string ContentType { get; set; }
            public DateTime DateModified { get; set; }
            
        }
        public class ReactDemoContext : DbContext
        {
            public ReactDemoContext(DbContextOptions<ReactDemoContext> options)
                : base(options)
            {
            }
            public DbSet<Image> Images { get; set; }
        }

    In-memory context.  I'm using an in-memory context because it makes testing easier.  

            public void ConfigureServices(IServiceCollection services)
            {
                services.AddDbContext<ReactDemoContext>(opt => opt.UseInMemoryDatabase("ReactDemoContext"));
                services.AddControllersWithViews();
    
                // In production, the React files will be served from this directory
                services.AddSpaStaticFiles(configuration =>
                {
                    configuration.RootPath = "ClientApp/build";
                });
            }

    View model

        public class ImageData
        {
            public string Description { get; set; }
            public IFormFile File { get; set; }
        }

    The rest is pretty simply. I just scaffolded a Web API action and made a change to the POST action to use a view model.  This is not production ready code and only meant to illustrate how create a basic Web API controller.  The business logic is sophomoric at best but I added an extra field "Description"  that's submitted along with the file to show you how to do that.  There's a simple exists check  meant to get you thinking how you plan to handle duplicate files.  The files are saved in a temp directory.  You'll need to figure out how to organize the files.

    FYI, the Put needs to be updated to use the view model like the Post.   The Get and Deletes work out-of-the-box with the code generated by the scaffolding wizard.  

    Also, I think it is important to mention this code came directly form tutorials I recommended above and in your other posts with the same subject.

        [Route("api/[controller]")]
        [ApiController]
        public class ImagesController : ControllerBase
        {
            private readonly ReactDemoContext _context;
    
            public ImagesController(ReactDemoContext context)
            {
                _context = context;
            }
    
            // GET: api/Images
            [HttpGet]
            public async Task<ActionResult<IEnumerable<Image>>> GetImages()
            {
                return await _context.Images.ToListAsync();
            }
    
            // GET: api/Images/5
            [HttpGet("{id}")]
            public async Task<ActionResult<Image>> GetImage(int id)
            {
                var image = await _context.Images.FindAsync(id);
    
                if (image == null)
                {
                    return NotFound();
                }
    
                return image;
            }
    
            // PUT: api/Images/5
            // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
            [HttpPut("{id}")]
            public async Task<IActionResult> PutImage(int id, Image image)
            {
                if (id != image.ImageId)
                {
                    return BadRequest();
                }
    
                _context.Entry(image).State = EntityState.Modified;
    
                try
                {
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!ImageExists(id))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
    
                return NoContent();
            }
    
            // POST: api/Images
            // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
            [HttpPost]
            public async Task<ActionResult<Image>> PostImage([FromForm] ImageData imageData)
            {
                if (imageData.File.Length > 0)
                {
                    var filePath = System.IO.Path.GetTempFileName();
                    using (var stream = System.IO.File.Create(filePath))
                    {
                        await imageData.File.CopyToAsync(stream);
                    }
    
                    Image file =  await _context.Images.FirstOrDefaultAsync(f => f.FileName == imageData.File.FileName);
                    if(file == null)
                    {
                        Image image = new Image()
                        {
                            ContentType = imageData.File.ContentType,
                            DateModified = DateTime.Now,
                            FileName = imageData.File.FileName,
                            Path = filePath,
                            Description = imageData.Description
                        };
                        _context.Images.Add(image);
                        await _context.SaveChangesAsync();
                        return CreatedAtAction(nameof(GetImage), new { id = image.ImageId }, image);
                    }
                    else
                    {
                        return BadRequest($"The path, {filePath}, already exists. Submit an HTTP PUT to update the image.");
                    }
                }
                return BadRequest($" {nameof(PostImage)} Error: The image file is {imageData.File.Length} bytes.");
            }
    
            // DELETE: api/Images/5
            [HttpDelete("{id}")]
            public async Task<IActionResult> DeleteImage(int id)
            {
                var image = await _context.Images.FindAsync(id);
                if (image == null)
                {
                    return NotFound();
                }
    
                _context.Images.Remove(image);
                await _context.SaveChangesAsync();
    
                return NoContent();
            }
    
            private bool ImageExists(int id)
            {
                return _context.Images.Any(e => e.ImageId == id);
            }
        }


     

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, January 20, 2021 12:49 AM

All replies

  • User-1545767719 posted

    SaeedP

    namespace imageEditor3
    {
    
        public class FileContext : DbContext
        {
            public DbSet<FileModel> FileModels { get; set; }
        }
        public class FileModel
        {
            [Key]
            [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
            public int FileId { get; set; }
            public string FileName { get; set; }
            public IFormFile FormFile { get; set; }
        }
    }

    I understand that you want to store the uploaded file to a databale and that is why you defined the context class FileContext and entity class FileModel as shown above.

    If my understanding is correct:

    (1) Change the type of FormFile property in the FileModel class from IFormFile to byte[].

    (2) Change the argument of Post([FromForm] FileModel file) method to Post(IFormFile file). Its name "file" must be the same as that of name attribute in multipart header like below:

    ------WebKitFormBoundaryBUDBREzc6SpFj442
    Content-Dis-data; name="file"; filename="sample3.jpg"
    Content-Type: image/jpeg

    (3) Use "FileContentResult Class" to download the byte array obtained from the database such like below:

    public IActionResult Get()
    {
        byte[] data = <Obtain byte array from database>;
    
        // for example if file is pdf and name is test.pdf
        // set Controller.File method as follows:
        return File(data, "application/pdf", "test.pdf");
    }

    Saturday, January 16, 2021 6:00 AM
  • User753101303 posted

    Hi,

    Also you usually don't try to fix a "doesn't work" problem by reading your code first.

    Instead you are using debugging tools to first see which errror you have so that you narrow down where to look for and what to look for. With a bit of experience it is much quicker. For example using https://developers.google.com/web/tools/chrome-devtools/network#load to check what happens for an htp query (this for Chrome but you have similar tools in most if not all browsers)

    When  reading code it is not uncommon to see multiple possible errors and then have to wonden which one actually happens and sometimes it just can't be seen by reading the code. Take maybe this as an occasion to lean about using this kind of tool ?

    Saturday, January 16, 2021 9:52 AM
  • User475983607 posted

    It's not possible to download multiple files.   

    Saturday, January 16, 2021 1:01 PM
  • User887623398 posted

    I don't want to download multiple files. I want to show data in a grid in view.

    When I run the program it shows:

     [Route("WeatherForecast/Get")]
            [HttpGet]
            public IEnumerable<FileModel> Get()
            {
                using (var Context = new FileContext())
                {
                     myFile = Context.FileModels.ToArray();
                }
    
                return myFile;
            }

    The debugger points to.ToArray() and says you didn't define the database for it!

    The Post action works well.

    Saturday, January 16, 2021 3:25 PM
  • User475983607 posted

    SaeedP

    I don't want to download multiple files. I want to show data in a grid in view.

    IFormFile is used to upload one or several file.  Since you are downloading an array, fileModel, and each array element has a IFormFile property, I assume your intent is to download multiple files.   Of course, that is just a guess becasue you have not explained the problem you are trying to solve.

    SaeedP

    The debugger points to.ToArray() and says you didn't define the database for it!

    The actual error would help but I assume your DbContext configuration is not designed correctly or missing.  Again, you have not provided sufficient information to understand what you are trying to do.  The code you have shown is questionable at best and I can only guess your intent.

    Saturday, January 16, 2021 3:47 PM
  • User887623398 posted

    Should I Configure dbContext at startup? But I didn't write it in a separate class.

    Saturday, January 16, 2021 5:20 PM
  • User475983607 posted

    It is impossible to provide assistance when you are unable to explain the programming problem you are trying to solve.  The code you shared does not make any logical sense so we need you to tell us your goals.

    Saturday, January 16, 2021 5:55 PM
  • User887623398 posted

    My goals are:

    by Post Action: I send a photo, photoID, Photo name to the database.

    And by Get Action show all this data to a grid. These are my goals. 

    Please let me to what should I explain any more?

    Also, I add the connection string to my startup:

     services.AddDbContext<FileContext>(options =>
                {
                    options.UseSqlServer("server=.;database=myDb;trusted_connection=true;");
                }
                    );

    Please guide me.

    Saturday, January 16, 2021 6:09 PM
  • User475983607 posted

    Saeed, as recommended in many of your recent post, you must take the time to read the reference documentation and learn how websites work. The code you've shared in the forum does not save an uploaded file or make any logical sense.  I think you'll be interested in reading the official file upload documentation.

    https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-5.0

    Once you are able to save an uploaded file then you can work on crafting a standard image tag and setting the src to an action that downloads the file.

    https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.fileresult?view=aspnetcore-5.0

    Anyway, this is all very basic website development found in any beginning level tutorial.  Please make an effort to learn the basics rather than making up your own constructs.

    Saturday, January 16, 2021 7:25 PM
  • User753101303 posted

    So from your last post it could be a db cnnection issue? I trying a simplified version I suspect maybe a camel casing issue ie what if you try:

            <tbody>
              {forecasts.map(forecast =>
                <tr key={forecast.fileId}>
                  <td>{forecast.fileName}</td>
                </tr>
              )}
            </tbody>
    

    Note I'm susing fileId  and fileName rather than FileId and FileName. Note that even if I try the same code than yours I don't know which connection string and if you changed serialization settings (or the default cooudl changed depending on your version). In short I have to read your code in case I would sport somethuing obvious, if not IK would have to reprio your code without even being sure to see any errorr and I could see an error you don"t have etc...

    For now I see "Warning: Each child in a list should have a unique "key" prop." in the "Consoe" tab of hte browser dev tools.

    So you should really lean to use those tools to find which error you have so that you can then move direcly to working on, solving your issue. You'll see that padt the learning curve you"ll save a HUGE amount of time compared with reading your code and trying to guess which problem happens.

    Saturday, January 16, 2021 10:50 PM
  • User-1545767719 posted

    My goals are:

    by Post Action: I send a photo, photoID, Photo name to the database.

    And by Get Action show all this data to a grid. These are my goals. 

    Please let me to what should I explain any more?

    You are doing too much things at one time. I am sure that is why you are having hard time to solve too many troubles which you cannot solve. It also make it very difficult to get the answer you need.

    I suggest that you will take a step-by-step approach to reach to your goal. For example:

    (1) Forget about database in the first step. Consider to save the uploaded file to a file system (not database).

    (2) Next, consider to download the uploaded file in the file system (not from a database).

    (3) After the above (1) and (2) are complete, consider to use a database instead of the file system.

    Sunday, January 17, 2021 3:12 AM
  • User887623398 posted

    SurferOnWww

    (1) Forget about database in the first step. Consider to save the uploaded file to a file system (not database).

    I'm correcting my words! I don't want to save images to the database.

    1. I want to save files in the wwwroot or a folder and successfully could do that (save data in wwwroot).
    2. I want to save the file(image) Id, file name, and file URL in the database.

    The second phase really confused me! can you please inform me? or give me a sample, while I dedicate many times to read documents

    Sunday, January 17, 2021 5:05 PM
  • User475983607 posted

    I'm correcting my words! I don't want to save images to the database.

    1. I want to save files in the wwwroot or a folder and successfully I could do that.
    2. I want to save the file(image) Id, file name, and file URL in the database.

    The second phase really confused me! can you please inform me? or give me a sample, while I dedicate many times to read documents

    You have not shared any code that saves a file in wwwroot or saves the file details in the a database.  I'm not sure what's happening on your side but it seems like you are not following any sample code from the links provided.  The code you have shared seems arbitrary like a hopeful guess. 

    If you have successfully saved a file in wwwroot then share the code.  The next step is building an entity model to save the wwwroot file details in your database.

    Sunday, January 17, 2021 5:31 PM
  • User887623398 posted

    The above code saves the file in wwwroot folder. But not database. I've tested it.

    Sunday, January 17, 2021 5:40 PM
  • User475983607 posted

    SaeedP

    The above code saves the file in wwwroot folder. But not database. I've tested it.

    You changed your original post! 

    You have not shown any code that tries to save anything to the database.  Use code first to create an entity model then update the database schema.  In the POST method, populate the entity model and save the data.  I recommend going through the following beginning level tutorial to learn how to work with data in .net5/Core.  These tutorials rather lengthy and should take a several days to properly learn the concepts.

    Razor Pages

    https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/intro?view=aspnetcore-5.0&tabs=visual-studio

    MVC

    https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/?view=aspnetcore-5.0

    These tutorials explain clearly and openly illustrate how to create and modify entity models in a web application using Entity framework Code First. There are a lot of optimizations and programming patterns presented in the material.  It is well worth the effort.

    Also, I think it is very important to mention that you've ignored REST design recommendation discussed in your other posts.  you have to understand, this is concerning because it feels like you are not making an effort.

    Sunday, January 17, 2021 6:00 PM
  • User887623398 posted

    You changed your original post! 

    What do you mean?

    No, I didn't change any code. I think you forgot this post:

    https://forums.asp.net/t/2173494.aspx?Problem+to+calling+the+controller+from+view

    You and Bruce helped me to achieve this!!

    Sunday, January 17, 2021 6:14 PM
  • User-1545767719 posted

    I'm correcting my words! I don't want to save images to the database.

    1. I want to save files in the wwwroot or a folder and successfully could do that (save data in wwwroot).
    2. I want to save the file(image) Id, file name, and file URL in the database.

    The second phase really confused me! can you please inform me? or give me a sample, while I dedicate many times to read documents

    You skip the phase as to how to download the uploaded file which should be the main issue of this thread as titled "Why this GET action can't handle Fetch Data".

    I suggest the following steps and discuss only (2) in this thread.

    (1) Upload and save a file to the folder in wwwroot. I understand that this step is complete (although there are items to improve).

    (2) Download the updated file from the folder in wwwroot.

    (3) Create the database to store id, file name and its url.

    (4) Modify the action method (1) to insert the record of id, file name and url to the database at the same time.

    If you agree I will write the answer to step (2) above.

    Monday, January 18, 2021 12:31 AM
  • User887623398 posted

    Thanks for such a complete answer. For this project, the user doesn't need to download the file or image.

    The Get Action will show all images in tile view or grid. After selecting the user the image will open in a graphic editor and the user can edit the image on there, change text or add some shapes. In the first phase, the user can download the image from the image editor!

    thanks

    Monday, January 18, 2021 1:32 AM
  • User-1545767719 posted

    SaeedP

    Thanks for such a complete answer. For this project, the user doesn't need to download the file or image.

    So, what does the title of this thread "Why this GET action can't handle Fetch Data" mean?

    Are you saying that you want to skip step (2) and go to step "(3) Create the database to store id, file name and its url."?

    Monday, January 18, 2021 2:44 AM
  • User475983607 posted

    SaeedP

    For this project, the user doesn't need to download the file or image.

    The user must download the image otherwise the user cannot see the image in the browser.

    The Get Action will show all images in tile view or grid. After selecting the user the image will open in a graphic editor and the user can edit the image on there, change text or add some shapes. In the first phase, the user can download the image from the image editor!

    You still misunderstand the website fundamentals. An HTTP GET, gets the file from the server.  If the file is on the client machine the user must select the file. 

    Just like you need to go through beginning level .net5.0/Core tutorials you also need to read the 3rd party image editor documentation to learn how to use the editor.  Keep in mind, passing the image reference in React was answered with source code in another one of your threads. 

    Monday, January 18, 2021 12:55 PM
  • User887623398 posted

    Are you saying that you want to skip step (2) and go to step "(3) Create the database to store id, file name and its url."?

    Yes, if it's possible.

    Tuesday, January 19, 2021 2:26 AM
  • User-1545767719 posted

    SaeedP

    SurferOnWww

    Are you saying that you want to skip step (2) and go to step "(3) Create the database to store id, file name and its url."?

    Yes, if it's possible.

    Try the followings:

    (1) Define the context class such like:

    using MvcIdCustom.Models;
    using Microsoft.EntityFrameworkCore;
     
    namespace MvcIdCustom.DAL
    {
        public class AvatarContext : DbContext
        {
            public AvatarContext(DbContextOptions<AvatarContext> options) : 
                base(options)
            {
            }
     
            public DbSet<Avatar> Avatars { get; set; }
        }
    }

    (2) Define the entity class such like:

    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
     
    namespace MvcIdCustom.Models
    {
        public class Avatar
        {
            [Key, Required]
            public int Id { get; set; }
     
            [Required, MaxLength(128)]
            public string Name { get; set; }
     
            [Required, MaxLength(256)]
            public string Url { get; set; }
        }
    }

    (3) Register the service below in the ConfigureServices method of Startup.cs:

    services.AddDbContext<AvatarContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("AvatarConnection")));

    (4) Set your connection string to the appsettings.json:

    "ConnectionStrings": {
        "AvatarConnection": "Server=xxxxx;Database=zzzzz ..."

    (5) Perform "Add-Migration AvatarData" command on the package manager console. Confirm that the xxxxx_AvatarData.cs file has been generated in the Migrations folder.

    (6) Perform "Update-Database" command on the package manager console. Confirm that the database table "Avatars" has been created in the database you specified in the connection string.

    Tuesday, January 19, 2021 3:39 AM
  • User887623398 posted

    Thank you surferon for your help. With your help, I added DbContext to the project.

    The post part of the code works well. You can see that on the first post. But when I write get Action to show the data in a grid I encounter an error that:

    No database provider has been configured for this DbContext!

    You can see the code here:

     public class FileModel
        {
            [Key]
            [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
            public int FileId { get; set; }
            public string FileName { get; set; }
            public IFormFile FormFile { get; set; }
        }
    
    private IEnumerable<FileModel> myFile;
    [Route("WeatherForecast/Get")]
            [HttpGet]
            public IEnumerable<FileModel> Get()
            {
                using (var Context = new FileDbContext())
                {
                    myFile = Context.FileModels.ToArray();
                }
    
                return myFile;
            }

    <div>

    public class FileDbContext: DbContext
        {
            
    
            public FileDbContext(DbContextOptions<FileDbContext> options) :
                base(options)
            {
            }
    
            public DbSet<FileModel> FileModels { get; set; }
        }
                services.AddDbContext<FileDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("FileContext")));
    "ConnectionStrings": {
        "FileContext": "Server=xxxxx;Database=zzzzz ..."
      }

    Also when I try to add-migration, it fails. what is wrong with my code?



    Tuesday, January 19, 2021 10:54 PM
  • User-1545767719 posted

    Also when I try to add-migration, it fails. what is wrong with my code?



    The definition of the entity class FileModel is wrong.

    Tuesday, January 19, 2021 11:39 PM
  • User475983607 posted

    If you just took a few minutes to go through the tutorials suggested above you'd probably be done by now. anyway, below is a working example.

    Entity configuration, models, and view models.

        public class Image
        {
            public int ImageId { get; set; }
            public string FileName { get; set; }
            public string Description { get; set; }
            public string Path { get; set; }
            public string ContentType { get; set; }
            public DateTime DateModified { get; set; }
            
        }
        public class ReactDemoContext : DbContext
        {
            public ReactDemoContext(DbContextOptions<ReactDemoContext> options)
                : base(options)
            {
            }
            public DbSet<Image> Images { get; set; }
        }

    In-memory context.  I'm using an in-memory context because it makes testing easier.  

            public void ConfigureServices(IServiceCollection services)
            {
                services.AddDbContext<ReactDemoContext>(opt => opt.UseInMemoryDatabase("ReactDemoContext"));
                services.AddControllersWithViews();
    
                // In production, the React files will be served from this directory
                services.AddSpaStaticFiles(configuration =>
                {
                    configuration.RootPath = "ClientApp/build";
                });
            }

    View model

        public class ImageData
        {
            public string Description { get; set; }
            public IFormFile File { get; set; }
        }

    The rest is pretty simply. I just scaffolded a Web API action and made a change to the POST action to use a view model.  This is not production ready code and only meant to illustrate how create a basic Web API controller.  The business logic is sophomoric at best but I added an extra field "Description"  that's submitted along with the file to show you how to do that.  There's a simple exists check  meant to get you thinking how you plan to handle duplicate files.  The files are saved in a temp directory.  You'll need to figure out how to organize the files.

    FYI, the Put needs to be updated to use the view model like the Post.   The Get and Deletes work out-of-the-box with the code generated by the scaffolding wizard.  

    Also, I think it is important to mention this code came directly form tutorials I recommended above and in your other posts with the same subject.

        [Route("api/[controller]")]
        [ApiController]
        public class ImagesController : ControllerBase
        {
            private readonly ReactDemoContext _context;
    
            public ImagesController(ReactDemoContext context)
            {
                _context = context;
            }
    
            // GET: api/Images
            [HttpGet]
            public async Task<ActionResult<IEnumerable<Image>>> GetImages()
            {
                return await _context.Images.ToListAsync();
            }
    
            // GET: api/Images/5
            [HttpGet("{id}")]
            public async Task<ActionResult<Image>> GetImage(int id)
            {
                var image = await _context.Images.FindAsync(id);
    
                if (image == null)
                {
                    return NotFound();
                }
    
                return image;
            }
    
            // PUT: api/Images/5
            // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
            [HttpPut("{id}")]
            public async Task<IActionResult> PutImage(int id, Image image)
            {
                if (id != image.ImageId)
                {
                    return BadRequest();
                }
    
                _context.Entry(image).State = EntityState.Modified;
    
                try
                {
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!ImageExists(id))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
    
                return NoContent();
            }
    
            // POST: api/Images
            // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
            [HttpPost]
            public async Task<ActionResult<Image>> PostImage([FromForm] ImageData imageData)
            {
                if (imageData.File.Length > 0)
                {
                    var filePath = System.IO.Path.GetTempFileName();
                    using (var stream = System.IO.File.Create(filePath))
                    {
                        await imageData.File.CopyToAsync(stream);
                    }
    
                    Image file =  await _context.Images.FirstOrDefaultAsync(f => f.FileName == imageData.File.FileName);
                    if(file == null)
                    {
                        Image image = new Image()
                        {
                            ContentType = imageData.File.ContentType,
                            DateModified = DateTime.Now,
                            FileName = imageData.File.FileName,
                            Path = filePath,
                            Description = imageData.Description
                        };
                        _context.Images.Add(image);
                        await _context.SaveChangesAsync();
                        return CreatedAtAction(nameof(GetImage), new { id = image.ImageId }, image);
                    }
                    else
                    {
                        return BadRequest($"The path, {filePath}, already exists. Submit an HTTP PUT to update the image.");
                    }
                }
                return BadRequest($" {nameof(PostImage)} Error: The image file is {imageData.File.Length} bytes.");
            }
    
            // DELETE: api/Images/5
            [HttpDelete("{id}")]
            public async Task<IActionResult> DeleteImage(int id)
            {
                var image = await _context.Images.FindAsync(id);
                if (image == null)
                {
                    return NotFound();
                }
    
                _context.Images.Remove(image);
                await _context.SaveChangesAsync();
    
                return NoContent();
            }
    
            private bool ImageExists(int id)
            {
                return _context.Images.Any(e => e.ImageId == id);
            }
        }


     

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, January 20, 2021 12:49 AM
  • User887623398 posted

    The definition of the entity class FileModel is wrong.

    Where is wrong?

    Wednesday, January 20, 2021 2:27 AM
  • User-1545767719 posted

    Where is wrong?

    public IFormFile FormFile { get; set; }

    Wednesday, January 20, 2021 3:00 AM
  • User887623398 posted

    When I add this line to start up a redline is appear under UseInMemory. Should I add any NuGet package?

    services.AddDbContext<ReactDemoContext>(opt => opt.UseInMemoryDatabase("ReactDemoContext"));

    Wednesday, January 20, 2021 3:18 AM
  • User-1545767719 posted

    services.AddDbContext<ReactDemoContext>(opt => opt.UseInMemoryDatabase("ReactDemoContext"));

    I understood you are using the SQL Server as you mentioned it in your post of 2021/01/17 03:09 AM. What are you doing?????????

    Wednesday, January 20, 2021 3:50 AM
  • User887623398 posted

    What you mean?

    I gave these nuget packages:

    Microsoft.entityframeworkcoe,

    Microsoft.entityframeworkcore.sqlserver,

    Microsoft.entityframework.tools

    Should I add a new one?

    Wednesday, January 20, 2021 3:59 AM
  • User-1545767719 posted

    I gave these nuget packages:

    Microsoft.entityframeworkcoe,

    Microsoft.entityframeworkcore.sqlserver,

    Microsoft.entityframework.tools

    It does not matter. What is the database server you are using in your development environment? That is question. If you do not understand the question and cannot answer to it probably we will not be able to communicate.

    Wednesday, January 20, 2021 4:18 AM
  • User887623398 posted

    SQL and entity framework

    Wednesday, January 20, 2021 4:30 AM
  • User-1545767719 posted

    SQL and entity framewor

    Sorry I can't help as I am sure that we will not be able to communicate. Please wait for someone else to get the answer you need.

    Wednesday, January 20, 2021 6:05 AM
  • User887623398 posted

    Thanks for all your help and supports.

    Wednesday, January 20, 2021 11:54 AM
  • User753101303 posted

    Beyond having a "redline" the Error window shouild show a message. With recent VS version it might even suggest a fix such as adding the needed package.

    More likely you need https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.inmemorydbcontextoptionsextensions.useinmemorydatabase?view=efcore-5.0 (not that it mentions this is part of the https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.InMemory/ package.

    IMO :
    - invest a bit time about learning how to narrow down issues. It will help you and other to fix issues (even before fixing a problem, the first part is to have the best understanding you can have about which problem you have)
    - I often avoid to provide ready to use code. I believe it's best to understand and do things yourself

    For example using an in memory database is a quick way to have a proof of concept up and running but you may want to use whatever ydb you are using. Avoid to copy/paste blindly but try to study and adapt code to your needs.

    Wednesday, January 20, 2021 12:46 PM
  • User475983607 posted

    When I add this line to start up a redline is appear under UseInMemory. Should I add any NuGet package?

    services.AddDbContext<ReactDemoContext>(opt => opt.UseInMemoryDatabase("ReactDemoContext"));

    The latest NuGet package for .net5.0 is...

    Install-Package Microsoft.EntityFrameworkCore.InMemory -Version 5.0.2

    Keep in mind, this information was provided in another one of your threads where we discussed REST services and Web API routing.  Given your sample code in this thread,  it is clear that you are not following the standard patterns.  This gives the impression that you are not taking the time to learn, follow the tutorials, or maybe you don't care about standards.  You have to understand that the reference documentation and tutorials are the best place to learn.   The documentation is well written and has far more in-depth information than forum members can provide.

    Wednesday, January 20, 2021 1:17 PM