Web API loading related data - c#

I am using ASP CORE 2.1 and EF CORE to create Web API with 2 data table with 1 ForeignKey
Model:
public partial class AuditInfo
{
public int Id { get; set; }
public string Level { get; set; }
public string Period { get; set; }
public string Auditor { get; set; }
public virtual ICollection<Item> Items { get; set; }
}
public partial class Item
{
public int Id { get; set; }
public string Ponumber { get; set; }
public bool IsComplete { get; set; }
public AuditInfo AuditInfo { get; set; }
}
public partial class VEDHOMEContext : DbContext
{
public VEDHOMEContext()
{
}
public VEDHOMEContext(DbContextOptions<VEDHOMEContext> options)
: base(options)
{
}
public virtual DbSet<AuditInfo> AuditInfo { get; set; }
public virtual DbSet<Item> Item { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.HasAnnotation("ProductVersion", "2.1.1-rtm-30846")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("auditAPI.Models.AuditInfo", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Auditor");
b.Property<string>("Level");
b.Property<string>("Period");
b.HasKey("Id");
b.ToTable("AuditInfo");
});
modelBuilder.Entity("auditAPI.Models.Item", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<int?>("AuditInfoId");
b.Property<bool>("IsComplete");
b.Property<string>("Ponumber");
b.HasKey("Id");
b.HasIndex("AuditInfoId");
b.ToTable("Item");
});
modelBuilder.Entity("auditAPI.Models.Item", b =>
{
b.HasOne("auditAPI.Models.AuditInfo", "AuditInfo")
.WithMany("Items")
.HasForeignKey("AuditInfoId");
});
}
}
Controller:
[Route("api/[controller]")]
[ApiController]
public class AuditInfoesController : ControllerBase
{
private readonly VEDHOMEContext _context;
public AuditInfoesController(VEDHOMEContext context)
{
_context = context;
}
// GET: api/AuditInfoes
[HttpGet]
public IEnumerable<AuditInfo> GetAuditInfo()
{
return _context.AuditInfo;
}
// GET: api/AuditInfoes/5
[HttpGet("{id}")]
public async Task<IActionResult> GetAuditInfo([FromRoute] int id)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var auditInfo = await _context.AuditInfo.FindAsync(id);
if (auditInfo == null)
{
return NotFound();
}
return Ok(auditInfo);
}
// PUT: api/AuditInfoes/5
[HttpPut("{id}")]
public async Task<IActionResult> PutAuditInfo([FromRoute] int id, [FromBody] AuditInfo auditInfo)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != auditInfo.Id)
{
return BadRequest();
}
_context.Entry(auditInfo).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!AuditInfoExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
// POST: api/AuditInfoes
[HttpPost]
public async Task<IActionResult> PostAuditInfo([FromBody] AuditInfo auditInfo)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
_context.AuditInfo.Add(auditInfo);
await _context.SaveChangesAsync();
return CreatedAtAction("GetAuditInfo", new { id = auditInfo.Id }, auditInfo);
}
// DELETE: api/AuditInfoes/5
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteAuditInfo([FromRoute] int id)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var auditInfo = await _context.AuditInfo.FindAsync(id);
if (auditInfo == null)
{
return NotFound();
}
_context.AuditInfo.Remove(auditInfo);
await _context.SaveChangesAsync();
return Ok(auditInfo);
}
private bool AuditInfoExists(int id)
{
return _context.AuditInfo.Any(e => e.Id == id);
}
}
However i got return null for the item related data, how can i fix it?
i am new to this framework, any help would appreciate, thanks.
[{"id":1,"level":"level1","period":"jan","auditor":"A","items":null},{"id":2,"level":"level2","period":"feb","auditor":"B","items":null}]
expected output:
[{"id":1,"level":"level1","period":"jan","auditor":"A","items":{"Id":1,"Ponumber":"0001","IsComplete":"True","AuditInfoId":1},{"id":2,"Ponumber":"0002","IsComplete":"True","AuditInfoId":1}}]
To who have similar problem, I solve it by adding
services.AddMvc()
.AddJsonOptions(options => {
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
and edit controller
public async Task<List<AuditInfo>> GetAuditInfo()
{
//return _context.AuditInfo;
var infoes = await _context.AuditInfo.Include(a => a.Items).ToListAsync();
return infoes;
}

I'm not sure if you've seen the accepted answer to this question, but the problem is to do with how the JSON Serializer deals with circular references. Full details and links to more references can be found at the above link, and I'd suggest digging into those, but in short, adding the following to startup.cs will configure the serializer to ignore circular references:
services.AddMvc()
.AddJsonOptions(options => {
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});

Related

Why is my form body always null in Web API?

I'm new in .NET and Web API; I create a signup user API with .NET 5.
This is my controller:
namespace SignupUsers.Controllers
{
[Route("api/signup")]
[ApiController]
public class MySignupController : ControllerBase
{
private readonly IDataRepository<UserSignup> _dataRepository;
public MySignupController(IDataRepository<UserSignup> dataRepository)
{
_dataRepository = dataRepository;
}
[HttpGet]
public IActionResult Get()
{
IEnumerable<UserSignup> userSignups = _dataRepository.GetAll();
return Ok(userSignups);
}
[HttpGet("{id}", Name = "Get")]
public IActionResult Get(int id)
{
UserSignup userSignup = _dataRepository.Get(id);
if (userSignup == null)
{
return NotFound("User Not Found!!!");
}
return Ok(userSignup);
}
[HttpPost]
public IActionResult Post([FromBody] UserSignup userSignup)
{
if (userSignup == null)
{
return BadRequest("User is null!!!");
}
_dataRepository.Add(userSignup);
return CreatedAtRoute(
"Get",
new { Id = userSignup.Id },
userSignup);
}
[HttpPut("{id}")]
public IActionResult Put(int id, [FromBody] UserSignup userSignup)
{
if (userSignup == null)
{
return BadRequest("User is null!!!");
}
UserSignup userSignupToUpdate = _dataRepository.Get(id);
if (userSignupToUpdate == null)
{
return NotFound("The User record couldn't be found");
}
_dataRepository.Update(userSignupToUpdate, userSignup);
return NoContent();
}
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
UserSignup userSignup = _dataRepository.Get(id);
if (userSignup == null)
return NotFound("The User record couldn't be found");
_dataRepository.Delete(userSignup);
return NoContent();
}
}
}
I added the DbContext to another folder:
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using SignupUsers.Models;
namespace SignupUsers.Data
{
public class UserSignupDbContext : DbContext
{
public UserSignupDbContext(DbContextOptions<UserSignupDbContext> options)
: base(options)
{
}
public DbSet<Models.UserSignup> SignupUsers { get; set; }
}
}
For using code first I use EF Core.
UserSignup model class:
namespace SignupUsers.Models
{
public class UserSignup
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public int Password { get; set; }
}
}
For managing input and output, I use an interface and implemented that in datamanager.cs:
namespace SignupUsers.Models
{
public class DataManager : IDataRepository<UserSignup>
{
readonly UserSignupDbContext _userSignupDbContext;
public DataManager(UserSignupDbContext context)
{
_userSignupDbContext = context;
}
public void Add(UserSignup entity)
{
_userSignupDbContext.SignupUsers.Add(entity);
_userSignupDbContext.SaveChanges();
}
public void Delete(UserSignup entity)
{
_userSignupDbContext.SignupUsers.Remove(entity);
_userSignupDbContext.SaveChanges();
}
public UserSignup Get(int id)
{
return _userSignupDbContext.SignupUsers.
FirstOrDefault(s => s.Id == id);
}
public IEnumerable<UserSignup> GetAll()
{
return _userSignupDbContext.SignupUsers.ToList();
}
public void Update(UserSignup dbEntity, UserSignup entity)
{
dbEntity.Name = entity.Name;
dbEntity.Email = entity.Email;
dbEntity.Password = entity.Password;
_userSignupDbContext.SaveChanges();
}
}
}
This is my startup:
namespace SignupUsers
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<UserSignupDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("UserSignup")));
services.AddScoped<IDataRepository<UserSignup>, DataManager>();
//services.AddCors();
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
When I post data to that (with Postman), I get back an error 415 (unsupported media type).
What can I do?
Thank you in advance for your help.
in postman, set the "content-type" as JSON (application/json)

How to store a JSON Object that as a list of strings as one of the fields into SQL with EntityFramework

So I am presented with the following JSON :
[
{
"Title": "TOY STORY 4",
"GENRE": "COMEDY",
"Actors": [
"Tom Hanks",
"Tim Allen",
"Annie Potts"
],
"Id": 1
},
{
"Title": "The Matrix",
"GENRE": "Action",
"Actors": [
"Keanu Reeves",
"Laurence Fishburne",
"Carrie-Anne Moss"
],
"Id": 2
}
]
C# object
class Movies
{
public string Title {get; set;}
public string GENRE {get; set;}
public string[] Actors {get; set;}
public int id {get; set;}
}
When I create a controller for movie it does not have a column for Actors and it does not create a new table for actors.
Movies Controller
public class MoviesController : ApiController
{
private DataContext db = new DataContext();
// GET: api/Movies
public IQueryable<Movies> GetMovies()
{
return db.Movies;
}
// GET: api/Movies/5
[ResponseType(typeof(Movies))]
public IHttpActionResult GetMovies(int id)
{
Movies movies = db.Movies.Find(id);
if (movies == null)
{
return NotFound();
}
return Ok(movies);
}
// PUT: api/Movies/5
[ResponseType(typeof(void))]
public IHttpActionResult PutMovies(int id, Movies movies)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != movies.id)
{
return BadRequest();
}
db.Entry(movies).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!MoviesExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return StatusCode(HttpStatusCode.NoContent);
}
// POST: api/Movies
[ResponseType(typeof(Movies))]
public IHttpActionResult PostMovies(Movies movies)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Movies.Add(movies);
db.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = movies.id }, movies);
}
// DELETE: api/Movies/5
[ResponseType(typeof(Movies))]
public IHttpActionResult DeleteMovies(int id)
{
Movies movies = db.Movies.Find(id);
if (movies == null)
{
return NotFound();
}
db.Movies.Remove(movies);
db.SaveChanges();
return Ok(movies);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
private bool MoviesExists(int id)
{
return db.Movies.Count(e => e.id == id) > 0;
}
}
Here is the other one where I made Actors as an object :
public class Movies1
{
public string Title { get; set; }
public string GENRE { get; set; }
public List<Actor> Actors { get; set; }
public int id { get; set; }
}
public class Actor
{
public string Actors { get; set; }
public int Id { get; set; }
}
Movies1 controller :
public class Movies1Controller : ApiController
{
private DataContext db = new DataContext();
// GET: api/Movies1
public IQueryable<Movies1> GetMovies1()
{
return db.Movies1;
}
// GET: api/Movies1/5
[ResponseType(typeof(Movies1))]
public IHttpActionResult GetMovies1(int id)
{
Movies1 movies1 = db.Movies1.Find(id);
if (movies1 == null)
{
return NotFound();
}
return Ok(movies1);
}
// PUT: api/Movies1/5
[ResponseType(typeof(void))]
public IHttpActionResult PutMovies1(int id, Movies1 movies1)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != movies1.id)
{
return BadRequest();
}
db.Entry(movies1).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!Movies1Exists(id))
{
return NotFound();
}
else
{
throw;
}
}
return StatusCode(HttpStatusCode.NoContent);
}
// POST: api/Movies1
[ResponseType(typeof(Movies1))]
public IHttpActionResult PostMovies1(Movies1 movies1)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Movies1.Add(movies1);
db.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = movies1.id }, movies1);
}
// DELETE: api/Movies1/5
[ResponseType(typeof(Movies1))]
public IHttpActionResult DeleteMovies1(int id)
{
Movies1 movies1 = db.Movies1.Find(id);
if (movies1 == null)
{
return NotFound();
}
db.Movies1.Remove(movies1);
db.SaveChanges();
return Ok(movies1);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
private bool Movies1Exists(int id)
{
return db.Movies1.Count(e => e.id == id) > 0;
}
}
This is the result of the two an none of them is writing the Actors to DB.
I do hope this helps to clear up the confusion and make sense of what the issue is that I am having.
Should you have more questions please let me know as I am trying to save this to database.
Table in SQL
If I understand you correctly and all you want is to store your Actors as a raw json string in Db, you could add a value converter to your DbContext OnModelCreating method like so:
using System.Text.Json;
public class MyDbContext : DbContext
{
...
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
...
modelBuilder
.Entity<Movies>()
.Property(m => m.Actors)
.HasConversion(
a => JsonSerializer.Serialize(a),
a => JsonSerializer.Deserialize<string[]>(a));
}
}
In short what this does is it tells EF to serialize/deserialize your Actors on write to/read from database.
EDIT:
Since you have a json.net tag, this is how you'd do it for your particular package.
using Newtonsoft.Json;
...
// Everything else remains the same.
.HasConversion(
a => JsonConvert.SerializeObject(a),
a => JsonConvert.DeserializeObject<string[]>(a));

Entity Framework Core deletes entities during update

I have a problem concerning entities in ASP.NET Core.
I use Entity Framework Core as data access library.
The issue I've come across happens when I'm trying to update an entity. After I modify the properties and call SaveChanges, the entity gets deleted and I don't understand why.
Here's the entity:
public class Contract
{
public int Id { get; set; }
[Required]
public DateTime ExpiryDate { get; set; }
[Required]
[Range(0, float.MaxValue)]
public float MonthlyFee { get; set; }
[Required]
public string UserId { get; set; }
[Required]
public int CarId { get; set; }
public User User { get; set; }
public Car Car { get; set; }
}
Here's the related entities for reference:
public class User : IdentityUser
{
[Required]
[PersonalData]
public string Name { get; set; }
[Required]
[PersonalData]
public string Surname { get; set; }
[Required]
[PersonalData]
public string TaxCode { get; set; }
[Required]
[PersonalData]
[DataType(DataType.Date)]
public DateTime DateOfBirth { get; set; }
public string ProfilePictureUrl { get; set; }
public Contract Contract { get; set; }
public ICollection<CarAccident> CarAccidents { get; set; }
}
public class Car
{
public int Id { get; set; }
[Required]
[RegularExpression("[A-Z][A-Z][0-9][0-9][0-9][A-Z][A-Z]")]
public string LicensePlate { get; set; }
public int CarModelId { get; set; }
public string FittingDescription { get; set; }
public Contract Contract { get; set; }
public ICollection<CarAccident> CarAccidents { get; set; }
public CarModel CarModel { get; set; }
}
Here's my update method in repository:
public async Task<Contract> Update(Contract entity)
{
var dbContract = await GetById(entity.Id);
if (dbContract == null)
return null;
var dbUser = await _userRepository.GetById(entity.UserId);
if (dbUser == null)
return null;
var dbCar = await _carRepository.GetById(entity.CarId);
if (dbCar == null)
return null;
dbContract.ExpiryDate = entity.ExpiryDate;
dbContract.User = entity.User;
dbContract.Car = dbCar;
dbContract.User = dbUser;
//_context.Contracts.FromSqlInterpolated($"UPDATE dbo.Contracts SET ExpiryDate={entity.ExpiryDate}, MonthlyFee={entity.MonthlyFee} WHERE Id={entity.Id}");
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateException)
{
return null;
}
return await GetById(entity.Id);
}
Has anyone got any idea how to solve this?
UPDATE:
This is the new Update method:
public async Task<Contract> Update(Contract entity)
{
var dbContract = await GetById(entity.Id);
if (dbContract == null)
return null;
var dbUser = await _userRepository.GetById(entity.UserId);
if (dbUser == null)
return null;
var dbCar = await _carRepository.GetById(entity.CarId);
if (dbCar == null)
return null;
dbContract.ExpiryDate = entity.ExpiryDate;
dbContract.Car = dbCar;
dbContract.User = dbUser;
//_context.Contracts.FromSqlInterpolated($"UPDATE dbo.Contracts SET ExpiryDate={entity.ExpiryDate}, MonthlyFee={entity.MonthlyFee} WHERE Id={entity.Id}");
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateException)
{
return null;
}
return await GetById(entity.Id);
}
Here's the Fluent API configuration:
private void _configureUsers(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.HasOne(u => u.Contract)
.WithOne(c => c.User)
.HasForeignKey<Contract>(c => c.UserId);
}
private void _configureCars(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>()
.HasAlternateKey(c => c.LicensePlate);
modelBuilder.Entity<Car>()
.HasOne(c => c.Contract)
.WithOne(c => c.Car)
.HasForeignKey<Contract>(c => c.CarId);
}
Both this methods get called in the OnModelCreating method of the context.
I've finally managed to solve my issue.
I was already tracking the entity in my api controller like that:
[HttpPut("{id}")]
[Authorize(Roles = "Backoffice")]
public async Task<ActionResult<ContractDTO>> PutContract(int id, [FromBody] PutContractViewModel viewModel)
{
if (viewModel == null || !ModelState.IsValid)
return BadRequest(new { message = "Your model is wrong" });
var contract = await _contractService.GetContractDTO(id);
if (contract == null)
return NotFound();
var modifiedContract = await _contractService.UpdateContract(viewModel);
if (modifiedContract == null)
return BadRequest(new { message = "User or car may be busy in another contract" });
return Ok(modifiedContract);
}
This type of approach works in one to many relationships, but evidently when you have one to one relationship and you have to objects that rapresent the same entity the ChangeTracker cannot track the changes correctly.
I post my new controller and repository code if someone will burst into my same problem.
Controller:
[HttpPut("{id}")]
[Authorize(Roles = "Backoffice")]
public async Task<ActionResult<ContractDTO>> PutContract(int id, [FromBody] PutContractViewModel viewModel)
{
if (viewModel == null || !ModelState.IsValid)
return BadRequest(new { message = "Your model is wrong" });
ContractDTO modifiedContract;
try
{
modifiedContract = await _contractService.UpdateContract(viewModel);
}
catch (EntityNotFoundException)
{
return NotFound();
}
if (modifiedContract == null)
return BadRequest(new { message = "User or car may be busy in another contract" });
return Ok(modifiedContract);
Service:
public async Task<ContractDTO> UpdateContract(PutContractViewModel viewModel)
{
try
{
return await ParseContractToContractDTO(await _contractRepository.Update(ParsePutContractViewModelToContract(viewModel)));
}
catch(EntityNotFoundException)
{
throw;
}
}
Repository:
public async Task<Contract> Update(Contract entity)
{
var dbContract = await _context.Contracts.Include(c => c.User).Include(c => c.Car).FirstOrDefaultAsync(c => c.Id == entity.Id);
if (dbContract == null)
{
throw new EntityNotFoundException();
}
var dbUser = await _context.Users.Include(u => u.Contract).FirstOrDefaultAsync(u => u.Id == entity.UserId);
if (dbUser == null)
return null;
var dbCar = await _context.Cars.Include(c => c.Contract).FirstOrDefaultAsync(c => c.Id == entity.CarId);
if (dbCar == null)
return null;
dbContract.ExpiryDate = entity.ExpiryDate;
dbContract.MonthlyFee = entity.MonthlyFee;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateException)
{
return null;
}
return await GetById(entity.Id);
}
I want to thank you all, you've been very helpful and patient with me.

WEB API post from uri/ Query string in post

i have a model
public partial class TalentVendorShots
{
public int Id { get; set; }
public string Email { get; set; }
public string One { get; set; }
public string Two { get; set; }
public string Three { get; set; }
public string Four { get; set; }
public string Five { get; set; }
public string Six { get; set; }
public string Seven { get; set; }
public string Eight { get; set; }
public string Nine { get; set; }
public string Ten { get; set; }
}
and basic controllers
[Route("api/[controller]")]
[ApiController]
public class TalentVendorShotsController : ControllerBase
{
private readonly champagneDatabase _context;
public TalentVendorShotsController(champagneDatabase context)
{
_context = context;
}
// GET: api/TalentVendorShots
[HttpGet]
public async Task<ActionResult<IEnumerable<TalentVendorShots>>> GetTalentVendorShots()
{
return await _context.TalentVendorShots.ToListAsync();
}
// GET: api/TalentVendorShots/5
[HttpGet("{id}")]
public async Task<ActionResult<TalentVendorShots>> GetTalentVendorShots(int id)
{
var talentVendorShots = await _context.TalentVendorShots.FindAsync(id);
if (talentVendorShots == null)
{
return NotFound();
}
return talentVendorShots;
}
// PUT: api/TalentVendorShots/5
[HttpPut("{id}")]
public async Task<IActionResult> PutTalentVendorShots(int id, TalentVendorShots talentVendorShots)
{
if (id != talentVendorShots.Id)
{
return BadRequest();
}
_context.Entry(talentVendorShots).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!TalentVendorShotsExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
// POST: api/TalentVendorShots
[HttpPost]
public async Task<ActionResult<TalentVendorShots>> PostTalentVendorShots(TalentVendorShots talentVendorShots)
{
_context.TalentVendorShots.Add(talentVendorShots);
await _context.SaveChangesAsync();
return CreatedAtAction("GetTalentVendorShots", new { id = talentVendorShots.Id }, talentVendorShots);
}
// DELETE: api/TalentVendorShots/5
[HttpDelete("{id}")]
public async Task<ActionResult<TalentVendorShots>> DeleteTalentVendorShots(int id)
{
var talentVendorShots = await _context.TalentVendorShots.FindAsync(id);
if (talentVendorShots == null)
{
return NotFound();
}
_context.TalentVendorShots.Remove(talentVendorShots);
await _context.SaveChangesAsync();
return talentVendorShots;
}
private bool TalentVendorShotsExists(int id)
{
return _context.TalentVendorShots.Any(e => e.Id == id);
}
}
}
all of this works fine. i get information from the database fine. now i want to make a post to the table via uri. no body.for example
/api/TalentVendorShots/id=1,email=testemail should create a new record with id of 1 and email of testemail. how can i accomplish this?
The basic rule is, You should use POST if the action is not idempotent. Though you can pass the query parameters and no body to POST. But It would not make sense in this scenario. Basically query parameters are used to get/filter information.
Similar way many Web API testing tools like ARC, Swagger, and PostMan (chrome extension does not allow, but standalone application allows) does not allow to send body with the GET request. Though you can send the body in GET requests.

Using TryUpdateModelAsync with an IEnumerable Collection

Model:
public class InvoiceCategory
{
[Key]
public int InvoiceCategoryID { get; set; }
[Required]
public string CategoryName { get; set; }
}
Controller Edit Method:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(IEnumerable<InvoiceCategory> invoiceCategories)
{
if (ModelState.IsValid)
{
try
{
var categoryToUpdate = await _context.InvoiceCategory.ToListAsync();
if (await TryUpdateModelAsync<InvoiceCategory>(
categoryToUpdate,
"",
i => i.InvoiceCategories)) /// <-- This is incorrect
{
}
await _context.SaveChangesAsync();
}
catch (Exception ex)
{
...
}
}
return View();
}
How can you use TryUpdateModelAsync to update an IEnumerable collection?
Or is there a better way to update it?

Categories

Resources