debugging the asp.net core web API - asp.net-core-webapi

I wrote this API in .net. I am trying to call this method through Fiddler and getting the below error message:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET /api/allItProjectsLists/Index</pre>
</body>
</html>
Not sure what am I doing wrong. Is there any way, I can put a breakpoint inside method Index and find out what is wrong. Below is my API code:
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 ProjectDetails.Models;
using ProjectDetails.Data;
using ProjectDetails.Interfaces;
namespace ProjectDetails.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class AllItProjectsListsController : ControllerBase
{
private readonly KPIContext _context;
private readonly IProject objProject;
public AllItProjectsListsController(IProject _objProject)
{
objProject = _objProject;
}
[HttpGet("/Index")]
public IEnumerable<AllItProjectsList> Index()
{
return objProject.GetAllProjectDetails();
}
[HttpPost]
[Route("api/AllItProjectsLists/Create")]
public int Create([FromBody] AllItProjectsList project)
{
return objProject.AddProject(project);
}
[HttpGet]
[Route("api/AllItProjectsLists/Details/{id}")]
public AllItProjectsList Details(int id)
{
return objProject.GetProjectData(id);
}
[HttpPut]
[Route("api/AllItProjectsLists/Edit")]
public int Edit([FromBody]AllItProjectsList project)
{
return objProject.UpdateProject(project);
}
[HttpDelete]
[Route("api/AllItProjectsLists/Delete/{id}")]
public int Delete(int id)
{
return objProject.DeleteProject(id);
}
[HttpGet]
[Route("api/AllItProjectsLists/GetAppDevList")]
public IEnumerable<AppDev> GetAppDev()
{
return objProject.GetAppDevs();
}
any help with the above debugging will be highly appreciated. In Fiddler, I typed the following URL:
https://localhost:44313/api/AllItProjectsLists/Index
Below is the image from Fiddler:

You need to change [HttpGet("/Index")] to [HttpGet("Index")] on your action for attribute routing.
[HttpGet("/Index")] will be executed for a URL as https://localhost:44313/Index
[HttpGet("Index")] will be executed for a URL as https://localhost:44313/api/AllItProjectsLists/Index
Refer to attribute routing

Related

.NET 5 WEB API not returning response in postman and browser

.NET 5 WEB API not returning response in postman and browser. Please help me to resolve this issue.
Here is the code:
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Mime;
using System.Text;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using RestSharp;
namespace WebAPIApplication.Controllers
{
[Route("api")]
[ApiController]
[Produces(MediaTypeNames.Application.Json)]
[Consumes(MediaTypeNames.Application.Json)]
public class ApiController : ControllerBase
{
[HttpGet("public")]
public IActionResult myPublic()
{
MyStatus _status = new MyStatus();
return Ok(_status);
}
}
}
Here is the response:
{}
return Ok(_status);
Here is the response: {}
Please check and make sure you defined properties well in your class MyStatus, perhaps you defined them as fields not properties, which cause this issue.
public class MyStatus
{
public int StatusCode;
//...
To fix the issue, can modify it as below
public class MyStatus
{
public int StatusCode { get; set; }
//...

Using Asp.Net Core Identity in MVC, Authorize attribute is rebouncing to login page after succesfull login

After long googling nights, asking my question here is the last drastic attempt to solve the problem. I'm reading a book of Adam Freeman, called Pro Asp.Net Core Mvc 2. I reached a very interesting chapter where the author creates a user login/register system using Identity API. The example is really simple but I've got stucked, and as I haven't seen any post using this approach, I decided to create a question here. So in the book, here is the user model class inherited from IdentityUser:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
namespace supafood.Models
{
public class AppUser:IdentityUser
{
//basic identity instalation
}
}
And then here is an addition userviewmodel class, model passed to the login form
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
namespace supafood.Models
{
public class CreateModel
{
[Required]
public string Name { get; set; }
[Required]
public string Email { get; set; }
[Required]
public string Password { get; set; }
}
public class LoginModel
{
[Required]
[UIHint("email")]
public string Email { get; set; }
[Required]
[UIHint("password")]
public string Password { get; set; }
public string returnUrl { get; set; }
}
}
Controller of the starting page, redirect unauthorized users to login page
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
namespace supafood.Controllers
{
public class HomeController:Controller
{
[Authorize]
public ViewResult Index() =>
View(new Dictionary<string, object>
{
["Placeholder"] = "Placeholder"
});
}
}
Login View page:
#model LoginModel
<div class="bg-primary mm-1 p-1 text-white"><h4>Log in</h4></div>
<div class="text-danger" asp-validation-summary="All"></div>
<h3>#ViewBag.returnUrl</h3>
<p>#ViewData["mess"]</p>
<form asp-action="Login" method="post">
<input type="hidden" asp-for="returnUrl" value="#ViewBag.returnUrl" />
<div class="form-group">
<label asp-for="Email"></label>
<input asp-for="Email" class="form-control" />
</div>
<div class="form-group">
<label asp-for="Password"></label>
<input asp-for="Password" class="form-control" />
</div>
<button type="submit" class="btn btn-sm btn-primary">Login</button>
</form>
And the AccountController handling the login attempt, returning the redirect to the requested page.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using supafood.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
namespace supafood.Controllers
{
[Authorize]
public class AccountController : Controller
{
private UserManager<AppUser> userMan;
private SignInManager<AppUser> signinMan;
public AccountController(UserManager<AppUser> UserM,
SignInManager<AppUser> SignM)
{
userMan = UserM;
signinMan = SignM;
}
[AllowAnonymous]
public IActionResult Login(string returnUrl)
{
ViewBag.returnUrl = returnUrl;
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginModel details)
{
if (ModelState.IsValid)
{
AppUser user =await userMan.FindByEmailAsync(details.Email);
ViewData["name"] = user.UserName;
if (user != null)
{
await signinMan.SignOutAsync();
Microsoft.AspNetCore.Identity.SignInResult result = await
signinMan.PasswordSignInAsync(user, details.Password, false, false);
if (result.Succeeded)
{
return Redirect(details.returnUrl);
}
}
ModelState.AddModelError(nameof(LoginModel.Email), "Invalid user
or password");
}
return View(details);
}
}
}
StartUp Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using supafood.Models;
using supafood.Infrastructure;
namespace supafood
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IPasswordValidator<AppUser>,
CustomPasswordValidator>();
services.AddDbContext<AppIdentityDbContext>(options =>
options.UseSqlServer(
Configuration["Data:SupafoodConnection:ConnectionString"]));
services.ConfigureApplicationCookie(opts => opts.LoginPath =
"/Users/Login");
services.AddIdentity<AppUser, IdentityRole>(opts =>
{
opts.User.RequireUniqueEmail = true;
opts.User.AllowedUserNameCharacters="abcdefghijklmnopqrstuvwxyz";
opts.Password.RequiredLength = 6;
opts.Password.RequireNonAlphanumeric = false;
opts.Password.RequireLowercase = false;
opts.Password.RequireUppercase = false;
opts.Password.RequireDigit = false;
}
)
.AddEntityFrameworkStores<AppIdentityDbContext>()
.AddDefaultTokenProviders();
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure
the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseStatusCodePages();
app.UseStaticFiles();
app.UseDeveloperExceptionPage();
app.UseMvc(routes =>
routes.MapRoute("default", "
{controller=Home}/{action=Index}/{id?}"));
app.UseAuthentication();
}
}
}
The problem is, that after login, the authorize attribute is rebouncing "the user" to the login page. I read some posts regarding some custom cookie setting options and IPrincipal implementation in order to fix this issue. The question is how is possible, that it worked for the author with no additional customization.
My knowledge is still basic so I'm trying to keep it simple for now, until I understand the core concepts.
Every help is appreciated.
Thanks, Zsolt.
The order of middleware registration matters. Move the app.UseAuthentication() call to before app.UseMvc(...).
Typically, anything that happens before a response is returned (like authentication) should come before the MVC middleware is registered.

asp.net core post json data with name property with too slow with non localhost url

Create asp.net core web api project in visual studio (dotnet core 2.0)
it will create a values controller with get,post,put and delete method
update the program.cs to make the api accessible in non localhost interfaces also.
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseUrls("http://0.0.0.0:61160")
.Build();
run the application and post {"name":"abc"} to the http://{machine}:61160/api/values url. it will take more than 6 seconds to get the response. if you change the url to localhost or rename the name property in the json to something else you will get immediate response.
does anybody faced this weird issue?
here is the code for default controller, it is just the auto generated sample controller
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace TestApp.Controllers
{
[Route("api/[controller]")]
public class ValuesController : Controller
{
// GET api/values
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
[HttpGet("{id}")]
public string Get(int id)
{
return "value";
}
// POST api/values
[HttpPost]
public void Post()
{
var data =new StreamReader(Request.Body).ReadToEnd();
}
// PUT api/values/5
[HttpPut("{id}")]
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/values/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
}

Server Side Scripting not working

I am new to MVC and creating a sample application by viewing this video.I have created a class in Model and a controller.Now when i try to access Class property through view,i am not able to access it,even when i am writing in view like <%=Model.Id %>,the angular brackets are not yellow marked as in case of server side scripting.I am not able to find where the problem is?
Class Customer in Model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcCustomer.Models
{
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public double Amount { get; set; }
}
}
and Controller is
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcCustomer.Models;
namespace MvcCustomer.Controllers
{
public class LoadCustomerAndDisplayController : Controller
{
//
// GET: /LoadCustomerAndDisplay/
public ActionResult Index()
{
Customer customer = new Customer();
customer.Name = "Devesh";
customer.Amount = 22.9;
customer.Id = 1;
return View(customer);
}
}
}
and my strongly typed view(IntelliSense is also not working) is
#model MvcCustomer.Models.Customer
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
</head>
<body>
<div>
The Customer id is: <%= Model.Id %>
</div>
</body>
</html>
First off, you're using a Razor view, not an ASP.NET view, so the syntax is #Model.Id not <%= Model.Id %>.
Your view is coded with Razor.
To initiate server side behavior use #, not <%= ... %>
Have a look here.
http://haacked.com/archive/2011/01/06/razor-syntax-quick-reference.aspx

sharp architecture question

I am trying to get my head around the sharp architecture and follow the tutorial. I am using this code:
using Bla.Core;
using System.Collections.Generic;
using Bla.Core.DataInterfaces;
using System.Web.Mvc;
using SharpArch.Core;
using SharpArch.Web;
using Bla.Web;
namespace Bla.Web.Controllers
{
public class UsersController
{
public UsersController(IUserRepository userRepository)
{
Check.Require(userRepository != null,"userRepository may not be null");
this.userRepository = userRepository;
}
public ActionResult ListStaffMembersMatching(string filter) {
List<User> matchingUsers = userRepository.FindAllMatching(filter);
return View("ListUsersMatchingFilter", matchingUsers);
}
private readonly IUserRepository userRepository;
}
}
I get this error:
The name 'View' does not exist in the current context
I have used all the correct using statements and referenced the assemblies as far as I can see. The views live in Bla.Web in this architecture.
Can anyone see the problem?
Thanks.
Christian
You should inherit UsersController from System.Web.Mvc.Controller class. View() method is defined in Controller class.
public class UsersController : Controller
{
//...
}

Resources