prodijay
prodijay
CC#
Created by prodijay on 7/2/2024 in #help
✅ Azure app service Web API project not running
I'm trying to deploy my Web API using Azure App Service. I followed this guide for VSCode: https://learn.microsoft.com/en-us/azure/app-service/quickstart-dotnetcore?tabs=net80&pivots=development-environment-vscode After deploying the project, when I go to the default domain, it says that the page cannot be found, with a HTTP ERROR 404. When I go to the diagnosis page, it says that I have 10 instances of 503 HttpStatus errors, indicating that the server is unavailable (I was trying to access the web API from my deployed React frontend). Does this indicate that there's something in my web API that's broken? I was trying to configure environment variables and perhaps that could be the source of the issue. I have restarted the project on Azure App Service a few times and it is still not working. When running my frontend app and web API locally, they work properly; the frontend successfully fetches to and from the Web API, and CORS is set up correctly to allow this. This is my first time using Azure App Service and deploying to it.
4 replies
CC#
Created by prodijay on 6/26/2024 in #help
What return method is appropriate for controller actions for SPA frontend?
I have a basic CRUD app with a React SPA and a Postgres database. I want to know what I should return in the controller actions, specifically for Get, Post, Put and Delete actions. I've inspected some docs like this: https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/details?view=aspnetcore-8.0 which use RedirectToAction. However this doesn't seem like it makes sense to use for a React SPA. I've been unable to find any relevant information on this topic of appropriate return methods for SPA. Any help would be appreciated. For instance would it make sense to use the CreatedAtAction for my Post controller action? Or could I simply just return createdNoteDTO? I want to send the created object back to the frontend.
c#
[HttpPost("{studyId}")]
public async Task<ActionResult<NoteDTO>> CreateNote(int studyId, [FromBody] CreateNoteInput input)
{
Note newNote = new Note
{...};

_context.Notes.Add(newNote);
await _context.SaveChangesAsync();

var createdNoteDTO = new NoteDTO
{...};

return CreatedAtAction(nameof(CreateNote), new { id = newNote.Id }, createdNoteDTO);
}
c#
[HttpPost("{studyId}")]
public async Task<ActionResult<NoteDTO>> CreateNote(int studyId, [FromBody] CreateNoteInput input)
{
Note newNote = new Note
{...};

_context.Notes.Add(newNote);
await _context.SaveChangesAsync();

var createdNoteDTO = new NoteDTO
{...};

return CreatedAtAction(nameof(CreateNote), new { id = newNote.Id }, createdNoteDTO);
}
Additionally, what should I do regarding the delete action? I don't want to return anything but it seems I have to return something.
3 replies
CC#
Created by prodijay on 6/24/2024 in #help
Unable to get logged in user when using React SPA
I'm trying to get the logged in user so that I can add them to my Study model instances, to then add to my database. I get the logged in user in my controller like so: var user = await _userManager.GetUserAsync(HttpContext.User); When accessing my controller via Swagger, user correctly returns the logged in user. However when accessing my controller via my React SPA (after logging in and returning a cookie), it returns null. Is there something I'm missing? For context, I am currently using cookie-based authentication with my React SPA. My fetch requests look like this: Login fetch; query is required to set useCookies to true.
export async function fetchWithQuery(endpoint, method, data, query) {
try {
const response = await fetch(
`${import.meta.env.VITE_BACKEND_DOMAIN}${endpoint}?${new URLSearchParams(
query
).toString()}`,
{
method,
body: data,
credentials: "include",
headers: {
"Content-Type": "application/json",
},
}
);
return response;
} catch (err) {
if (err) return err;
}
}
export async function fetchWithQuery(endpoint, method, data, query) {
try {
const response = await fetch(
`${import.meta.env.VITE_BACKEND_DOMAIN}${endpoint}?${new URLSearchParams(
query
).toString()}`,
{
method,
body: data,
credentials: "include",
headers: {
"Content-Type": "application/json",
},
}
);
return response;
} catch (err) {
if (err) return err;
}
}
Fetch function used to get all studies made by a user.
export async function getDataFromFetch(endpoint) {
try {
const response = await fetch(
`${import.meta.env.VITE_BACKEND_DOMAIN}${endpoint}`,
{
mode: "cors",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
}
);
return response;
} catch (err) {
if (err) return err;
}
}
export async function getDataFromFetch(endpoint) {
try {
const response = await fetch(
`${import.meta.env.VITE_BACKEND_DOMAIN}${endpoint}`,
{
mode: "cors",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
}
);
return response;
} catch (err) {
if (err) return err;
}
}
I think I've set up CORS correctly, as when I login from the React SPA a cookie is set.
c#
builder.Services.AddCors(options =>
{
options.AddPolicy(
name: MyAllowSpecificOrigins,
policy =>
{
policy.WithOrigins(["http://localhost:5173"])
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
c#
builder.Services.AddCors(options =>
{
options.AddPolicy(
name: MyAllowSpecificOrigins,
policy =>
{
policy.WithOrigins(["http://localhost:5173"])
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
The repo for the backend code: https://github.com/jasonHYLam/csharp-test
18 replies
CC#
Created by prodijay on 6/21/2024 in #help
Unable to get logged in user with GetUserAsync
In my controller's post action, I am trying to obtain the logged in user to add to an instance of my Study model, to then add to the database. For context I am using ASPNET Core Identity, with cookies. After successfully using the /register and /login Identity endpoints, I attempt to use the HttpPost for the controller which contains the logic for obtaining the logged in user. However the logged in user seems to be null. I have attempted several ways, including: var user = await _userManager.GetUserAsync(HttpContext.User); This is the set up for my controller:
c#
[ApiController]
[Route("api/[controller]")]
public class StudyController : ControllerBase
{
private readonly UserManager<User> _userManager;
private readonly ApplicationDbContext _context;

public StudyController(ApplicationDbContext context, UserManager<User> userManager)
{
_context = context;
_userManager = userManager;
}
c#
[ApiController]
[Route("api/[controller]")]
public class StudyController : ControllerBase
{
private readonly UserManager<User> _userManager;
private readonly ApplicationDbContext _context;

public StudyController(ApplicationDbContext context, UserManager<User> userManager)
{
_context = context;
_userManager = userManager;
}
Both _userManager and HttpContext.User exist.
39 replies
CC#
Created by prodijay on 6/21/2024 in #help
Unable to set User FK in another model (User extends IdentityUser)
I am attempting to establish relationships between my models. For context I'm using EntityFrameworkCore and Identity. I have a User model (extends IdentityUser) and a Study model. Studies should have one User, and Users can have multiple Studies. The first time I tried to establish the relationships I wrote them in the models, like so:
c#
// Study.cs
public class Study
{
public int Id { get; set; }
//...
public required string UserId { get; set; }
public IdentityUser? User { get; set; }
}
c#
// Study.cs
public class Study
{
public int Id { get; set; }
//...
public required string UserId { get; set; }
public IdentityUser? User { get; set; }
}
c#
// User.cs
public class User : IdentityUser
{
public List<Study> Studies { get; set; } = new List<Study>();
}
c#
// User.cs
public class User : IdentityUser
{
public List<Study> Studies { get; set; } = new List<Study>();
}
That resulted in the warning The foreign key property 'Study.UserId1' was created in shadow state because a conflicting property with the simple name 'UserId' exists in the entity type, but is either not mapped, is already used for another relationship, or is incompatible with the associated primary key type. I am now trying to use OnModelCreating to create the relationships in DBContext instead, like so:
c#
public class ApplicationDbContext : IdentityDbContext<IdentityUser>
{
public DbSet<User> Users { get; set; }
public DbSet<Study> Studies { get; set; }

public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{ }

protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);

builder.Entity<Study>()
.HasOne(s => s.User)
.WithMany(u => u.Study)
.HasForeignKey(s => s.UserId)
}
}
c#
public class ApplicationDbContext : IdentityDbContext<IdentityUser>
{
public DbSet<User> Users { get; set; }
public DbSet<Study> Studies { get; set; }

public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{ }

protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);

builder.Entity<Study>()
.HasOne(s => s.User)
.WithMany(u => u.Study)
.HasForeignKey(s => s.UserId)
}
}
However this says that IdentityUser does not contain a definition for Study and no accessible extension method 'Study' accepting a first argument of type 'IdentityUser' could be found I have henceforth changed public IdentityUser? User { get; set; } to public User? User { get; set; } with the same result. However User should contain a list of Study objects...
7 replies