How to make swagger client executable

Mantra 1 Reputation point
2022-03-03T07:50:27.313+00:00

I've been having some problems with this Application I've created (code below):

First I installed the NuGet Packages:

Microsoft.EntityFrameworkCore.Relational
Microsoft.EntityFrameworkCore.Tools
Microsoft.EntityFrameworkCore.SQLServer

all in Version 5.0.12.

Then I typed the following command into the PM Console:

Scaffold-DbContext "Data Source=(local);Initial Catalog=BikeStores;Integrated Security=True" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models

which created all the Models.

To prevent JSON-Errors I added DTOs for the Objects like this:

namespace NETCoreUebung.DTO
{
public class StoreDTO
{
public StoreDTO()
{
Stocks = new HashSet<StockDTO>();
}

     public int StoreId { get; set; }
     public string City { get; set; }
     public string Email { get; set; }
     public string Phone { get; set; }
     public string State { get; set; }
     public string StoreName { get; set; }
     public string Street { get; set; }
     public string ZipCode { get; set; }
     public ICollection<StockDTO> Stocks { get; set; }
 }

}

After that I created these two Methods in the ModelClass, for Converting the DTOs:

public StoreDTO ToDTO()
{
return new StoreDTO { StoreId = StoreId, City = City, Email = Email, Phone = Phone, State = State, StoreName = StoreName, Street = Street, ZipCode = ZipCode, Stocks = (from s in Stocks select s.ToDTO()).ToList() };
}

     public void FromDTO(StoreDTO dto)
     {
         StoreId = dto.StoreId;
         City = dto.City;
         Email = dto.Email;
         Phone = dto.Phone;
         State = dto.State;
         StoreName = dto.StoreName;
         Street = dto.Street;
         ZipCode = dto.ZipCode;
     }

After that I let Visual Studio create an API-Controller for me which I modified to look like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NETCoreUebung.DTO;
using NETCoreUebung.Models;

namespace NETCoreUebung.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class StoresController : ControllerBase
{
private readonly BikeStoresContext _context;

     public StoresController()
     {
         _context = new BikeStoresContext();
     }

     // GET: api/Stores
     [HttpGet(Name ="GetStores")]
     public async Task<ActionResult<IEnumerable<StoreDTO>>> GetStores()
     {
         return await (from s in _context.Stores.Include("Stocks").Include("Stocks.Product").Include("Stocks.Store") select s.ToDTO()).ToListAsync();
     }

     // GET: api/Stores/5
     [HttpGet("{id}", Name = "GetStore")]
     public async Task<ActionResult<StoreDTO>> GetStore(int id)
     {
         var store = await (from s in _context.Stores.Include("Stocks").Include("Stocks.Product").Include("Stocks.Store") where s.StoreId == id select s.ToDTO()).FirstOrDefaultAsync();

         if (store == null)
         {
             return NotFound();
         }

         return store;
     }

     // PUT: api/Stores/5
     // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
     [HttpPut("{id}", Name = "PutStore")]
     public async Task<IActionResult> PutStore(int id, StoreDTO s)
     {
         Store store = new Store();
         store.FromDTO(s);
         if (id != store.StoreId)
         {
             return BadRequest();
         }

         _context.Entry(store).State = EntityState.Modified;

         try
         {
             await _context.SaveChangesAsync();
         }
         catch (DbUpdateConcurrencyException)
         {
             if (!StoreExists(id))
             {
                 return NotFound();
             }
             else
             {
                 throw;
             }
         }

         return NoContent();
     }

     // POST: api/Stores
     // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
     [HttpPost(Name = "PostStore")]
     public async Task<ActionResult<StoreDTO>> PostStore(StoreDTO s)
     {
         Store store = new Store();
         store.FromDTO(s);
         _context.Stores.Add(store);
         await _context.SaveChangesAsync();

         return store.ToDTO();
     }

     // DELETE: api/Stores/5
     [HttpDelete("{id}", Name = "DeleteStore")]
     public async Task<IActionResult> DeleteStore(int id)
     {
         var store = await _context.Stores.FindAsync(id);
         if (store == null)
         {
             return NotFound();
         }

         _context.Stores.Remove(store);
         await _context.SaveChangesAsync();

         return NoContent();
     }

     private bool StoreExists(int id)
     {
         return _context.Stores.Any(e => e.StoreId == id);
     }
 }

}

After all that I added a Service Reference to the OpenAPI to my second Project, and Changed ClassName="BikeStoreClient" OutputPath="..\Models\BikeStoreClient.cs".

How do I make this Project an EXE?

Developer technologies | ASP.NET | ASP.NET Core
Developer technologies | C#
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Yannik Ratzenböck 1 Reputation point
    2022-03-03T07:53:18.753+00:00

    Hi User, to change the Directory and Name of the SwaggerClient.cs you have to open the .csproj file and add the Arguments ClassName="BikeStoreClient" OutputPath="..\Models\BikeStoreClient.cs".

    For me it works better to Download the swagger.json file and add the Service Reference as a file.

    After this you should adjust your Controller a bit, because it might get generated wrong:

    here's mine:

    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net.Http;
    using System.Threading.Tasks;

    namespace WebApplication3.Controllers
    {
    public class StoreController : Controller
    {
    BikeStoreClient client;
    public StoreController()
    {
    client = new BikeStoreClient("http://localhost:35519", new HttpClient());
    }

        private T AwaitTask<T>(Task<T> t)  
        {  
            t.Wait();  
            return t.Result;  
        }  
    
        private void AwaitTask(Task t)  
        {  
            t.Wait();  
        }  
        // GET: StoreController  
        public ActionResult Index()  
        {  
            return View(AwaitTask(client.GetStoresAsync()));  
        }  
    
        // GET: StoreController/Details/5  
        public ActionResult Details(int id)  
        {  
            return View(AwaitTask(client.GetStoreFromIDAsync(id)));  
        }  
    
        // GET: StoreController/Create  
        public ActionResult Create()  
        {  
            return View();  
        }  
    
        // POST: StoreController/Create  
        [HttpPost]  
        [ValidateAntiForgeryToken]  
        public ActionResult Create([Bind("City,Email,Phone,State,StoreName,Street,ZipCode")]Store store)  
        {  
            try  
            {  
                if (ModelState.IsValid)  
                {  
                    AwaitTask(client.PostStoreAsync(store));  
                    return RedirectToAction(nameof(Index));  
                }  
    
            }  
            catch(Exception e)  
            {  
                ModelState.AddModelError("", e.Message);  
            }  
            return View(store);  
        }  
    
        // GET: StoreController/Edit/5  
        public ActionResult Edit(int id)  
        {  
            return View(AwaitTask(client.GetStoreFromIDAsync(id)));  
        }  
    
        // POST: StoreController/Edit/5  
        [HttpPost]  
        [ValidateAntiForgeryToken]  
        public ActionResult Edit(int id, [Bind("City,Email,Phone,State,StoreName,Street,ZipCode")] Store store)  
        {  
            if (id != store.StoreId)  
            {  
                return NotFound();  
            }  
            try  
            {  
                if (ModelState.IsValid)  
                {  
                    AwaitTask(client.PutStoreAsync(id, store));  
                    return RedirectToAction(nameof(Index));  
    
                }  
            }  
            catch(Exception e)  
            {  
                ModelState.AddModelError("", e.Message);  
            }  
            return View();  
        }  
    
        // GET: StoreController/Delete/5  
        public ActionResult Delete(int id)  
        {  
            return View(AwaitTask(client.GetStoreFromIDAsync(id)));  
        }  
    
        // POST: StoreController/Delete/5  
        [HttpPost]  
        [ValidateAntiForgeryToken]  
        public ActionResult Delete(int id, [Bind("City,Email,Phone,State,StoreName,Street,ZipCode")] Store store)  
        {  
            if(id != store.StoreId)  
            {  
                return NotFound();  
            }  
            try  
            {  
                if (ModelState.IsValid)  
                {  
                    AwaitTask(client.DeleteProductAsync(id));  
                    return RedirectToAction(nameof(Index));  
                }  
                }  
            catch(Exception e)  
            {  
                ModelState.AddModelError("", e.Message);  
            }  
            return View();  
        }  
    }  
    

    }

    After this you can just right-click on the methods (Index, Details, Delete, Edit, Create) and click AddView

    NOTE: in the Index Method you have to change the ActionLinks at the bottom to @azzedinehtmlsql .ActionLink("Edit", "Edit", new { id = item.StoreId}), else it wont work ;)

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.