posting with js to api (asp.net core mvc ) - c#

Hello im using a DTO for a single value(Id) & trying to post to Db using ApiController but on button click I keep getting error 400 that is referring me to xhr.send error.
(im using asp.net core 2.1 )
Code :
#section Scripts{
<script type="text/javascript">
$(document)
.ready(function() {
$(".js-toggle-HandShake")
.click(function(e) {
var button = $(e.target);
console.log(button.attr("data-QuettaOfferId")); //Value=24 >> OK
$.post("/Api/HandShake/", { QuettaOfferId: button.attr("data-QuettaOfferId") })
// Error in > POST https://localhost:44339/Api/HandShake/ 400 () &
//in jquery>> xhr.send( options.hasContent && options.data || null );
.done(function() {
button
.text("Chousen");
})
.fail(function() {
alert("Something failed");
});
});
});
</script>
}
& the ApiController code
[Microsoft.AspNetCore.Mvc.Route("api/[controller]")]
[ApiController]
[Microsoft.AspNetCore.Authorization.Authorize]
public class HandShakeController : ControllerBase
{
private readonly ApplicationDbContext _context;
private readonly UserManager<IdentityUser> _userManager;
// private readonly IHostingEnvironment hostingEnvironment;
public HandShakeController(ApplicationDbContext context ,UserManager<IdentityUser> userManager/*, IHostingEnvironment environment*/)
{
_context = context;
_userManager = userManager;
//hostingEnvironment = environment;
}
[Microsoft.AspNetCore.Mvc.HttpPost]
// public IHttpActionResult HandShakes(HandShakeDto dto)
public IActionResult HandShakes(HandShakeDto dto)
{
var userId = _userManager.GetUserId(User);
var check = _context.Quetta.Where(u => u.SiteUserId == userId);
if ( _context.handShakes.Any(f => f.QuettaOfferId == dto.QuettaOfferId))
return BadRequest("Some error Msg");
if (check.Any())
{
var hand = new HandShake
{
QuettaOfferId = dto.QuettaOfferId
};
try
{
_context.handShakes.Add(hand);
_context.SaveChangesAsync();
return Ok();
}
catch (Exception e)
{
Console.WriteLine(e);
return BadRequest("Some error Msg");
}
}
else{
return BadRequest("");}
// Check if the user id that publish the ed = login user.
//if so add the offer to selected table,
}
}
im using asp.net core 2.1 & strongly suspect that the problem is in the ApiController but im not sure.
The DTO
public class HandShakeDto
{
public int QuettaOfferId { get; set; }
}

Try replacing
$.post("/Api/Hand/", { QuettaOfferId: button.attr("data-QuettaOfferId") })
By
$.post("/Api/HandShake/", { QuettaOfferId: button.attr("data-QuettaOfferId") })
as your api controller name is HandShakeController

Related

My ASP.NET Core's ApiController is not functional - JS Fetch returns 404

So I have my endpoint defined like the following:
[ApiController]
[Route("load/stuff")]
public class SignUp : ControllerBase
{
IGoogleRecaptchaV3Service _gService { get; set; }
public SignUp(IGoogleRecaptchaV3Service gService)
{
_gService = gService;
}
[HttpPost]
public async Task<IActionResult> Post([FromQuery] SignUpModel SignUpData, GRequestModel.Factory grequestFactory)
{
GRequestModel grm = grequestFactory("resValue", "remipValue");
_gService.InitializeRequest(grm);
if (!await _gService.Execute())
{
//return error codes string.
return Ok(_gService.Response.error_codes);
}
//call Business layer
return base.Content("Content here", "text/html");
}
}
This should return the HTML content if the reCAPTCHA score is human-like.
Let me know how to debug this further and whether any further code is required.
UPDATE fetch JS Code
function loadStuff() {
if (location.pathname === "/test") {
grecaptcha.execute('recaptchasitekeyhere', { action: 'onloadafterdelay' }).then(function (token) {
console.log(token);
return fetch("/load/stuff?RecaptchaToken=" + token, {
method: "POST",
body: token,
})
}).then((response) => {
// console.log works here too
if (!response.ok) {
const errorBuild = {
type: "Error",
message: response.message || "Something went wrong",
data: response.data || "",
code: response.code || "",
};
console.log("Error: " + JSON.stringify(errorBuild));
}
response.text().then(body => {
//console.log(body);
document.getElementById("test1").innerHTML = body.split(' ')[0];
document.getElementById("test2").innerHTML = body.split(' ')[1];
});
}
)
}
}
I also added this in the program.cs file:
builder.Services.AddControllers();
// FIX TEST
builder.Services.AddTransient<GRequestModel.Factory>(serviceProvider =>
(string res, string remip) => new GRequestModel(serviceProvider.GetRequiredService<IConfiguration>(), res, remip));
//Register dependencies
builder.Services.AddRazorPages();
// REMOVE ME IN PRODUCTION, USE DI INSTEAD
// ....
Configuration = app.Configuration;
// ...
public partial class Program
{
internal static IConfiguration Configuration { get; private set; }
}
I added that code above as a temporary fix, but then I tried to implement dependency injection for the IConfiguration and my codebase got dirty. I'm still a beginner in C# and I'm learning by trial and error hence so many mistakes.

Session being lost between controllers Asp.net core

Ok I am using a session variable to store a case Id that is linked between tables. I am using .net 3.1 I just need this simple value passed between controllers It appears to only work within the current controller.
Say Relationship Controller is this.
public class RelationShipsController : Controller
{
private readonly MISDBContext _context;
public RelationShipsController(MISDBContext context)
{
_context = context;
}
// GET: RelationShips/Edit/5
public async Task<IActionResult> Edit(int? id) {
if (id == null) {
return NotFound();
}
var relationShips = await _context.RelationShips.FindAsync(id);
if (relationShips == null) {
return NotFound();
}
HttpContext.Session.SetString("relationShipId", relationShips.Id.ToString());
HttpContext.Session.SetString("CaseId", relationShips.MisObjectId.ToString());
return View(relationShips);
}
}
This is the second controller where i wish to read in the above session.
public class VesselsController : Controller
{
private readonly MISDBContext _context;
public VesselsController(MISDBContext context) {
_context = context;
GetCompanies();
}
// POST: Vessels/Create
// To protect from overposting attacks, enable the specific properties you want to bind to, for
// more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Name,CountryOfOrigon,CompanyId,IMONumber,Flag,Company,Country,CallSign,MMSI,VesselType,Active,isDeleted,isActive,CreatedDate,CreatedBy,MISObjectId,RelationShipId")] Vessels vessels)
{
if (ModelState.IsValid) {
var realtionShipId = Int32.TryParse(HttpContext.Session.GetString("relationShipId"), out int resultRelationshipId);
Int32.TryParse(HttpContext.Session.GetString("CaseId"), out Int32 resultCaseId);
vessels.isActive = true;
vessels.isDeleted = false;
vessels.CreatedBy = HttpContext.Session.GetString("Intitals");
vessels.LastModfiedDate = DateTime.Now;
vessels.CreatedDate = DateTime.Now;
vessels.LastModfiedBy = HttpContext.Session.GetString("Intitals");
vessels.MISObjectId = resultCaseId;
vessels.RelationShipId = resultRelationshipId;
_context.Add(vessels);
await _context.SaveChangesAsync();
return RedirectToAction("Edit", "Relationships", new { Id = vessels.MISObjectId });
}
GetCompanies();
return View(vessels);
}
}
Its this resultCaseId I have lost the variable and yes I have setup the configure middle ware.
app.UseSession();
Make sure you as the user have provided consent. Or mark the session cookie as "essential" like this:
services.AddSession(opts =>
{
opts.Cookie.IsEssential = true; // make the session cookie Essential
});
You can read more about GDPR changes in asp.net core here.

Problem with call Controller from Angular

I have a problem with running Controller from angular ClientApp service.
Cannot understand why Controller has not got any calls.
My angular service code:
export class MediaService extends BaseService {
constructor(private http: Http, configService: ConfigService) {
super(configService);
}
getMedia(mediaId: string) {
return this.http
.get(
'api/media',
{
params: {
id: mediaId
},
headers: this.getBaseHttpHeaders()
}).map(result => {
return result.json();
})
.map(result => {
if (result.status === 1) {
return { success: true, data: result.data };
}
else {
return { success: false, data: result.data };
}
});
}
MediaController.cs
[Authorize(Policy = "UserExists")]
[Produces("application/json")]
[Route("api/media")]
public class MediaController : BaseController
{
private readonly IMediaService _mediaService;
private readonly ICollectionPhotosService _collectionPhotosService;
public MediaController(IUserService userService, IMediaService mediaService, ICollectionPhotosService collectionPhotosService) : base(userService)
{
_mediaService = mediaService;
_collectionPhotosService = collectionPhotosService;
}
[HttpGet]
public IActionResult Index(string id, string collectionPhotoId = null)
{
try
{
Guid guidId = Guid.Empty;
Guid collectionPhotoGuidId = Guid.Empty;
if ((!Guid.TryParse(id, out guidId) && collectionPhotoId == null) || (!Guid.TryParse(collectionPhotoId, out collectionPhotoGuidId) && id == null))
{
return NotFound();
}
if (string.IsNullOrWhiteSpace(UserId))
{
return GenerateBadResult("Incorrect user");
}
var isItemMedia = guidId != Guid.Empty;
return isItemMedia ? HandleMediaItem(guidId, UserId) : HandleCollectionPhotoItem(collectionPhotoGuidId, UserId);
}
catch (Exception)
{
return GenerateBadResult("Some error occured");
}
}
BaseService.cs
public class BaseController : Controller
{
protected readonly IUserService _userService;
public BaseController(IUserService userService)
{
_userService = userService;
}
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
DbInitializer.AdminV2Initialize(Configuration.GetConnectionString("DefaultConnection"));
// Get options from app settings
var jwtAppSettingOptions = Configuration.GetSection(nameof(JwtIssuerOptions));
services.Configure<SmtpClientConfig>(Configuration.GetSection(nameof(SmtpClientConfig)));
services.TryAddTransient<IHttpContextAccessor, HttpContextAccessor>();
services.AddScoped<ITokenService, TokenService>();
services.AddScoped<IEmailProvider, EmailProvider>();
services.AddScoped<IUserService, UserService>();
services.AddScoped<IMediaService, MediaService>();
services.AddScoped<ICollectionService, CollectionService>();
services.AddScoped<IEmailService, EmailService>();
services.AddScoped<ILocationService, LocationService>();
services.AddScoped<ICollectionPhotosService, CollectionPhotosService>();
services.AddSingleton<IUserDataCSVGenerator, UserDataCSVGenerator>();
I also have AuthController which works fine.
And when I'm using MediaController I have only 500 Internal Server Error (
Controller not even try to Initialize - what the problem?

How to extract request headers and pass it to the business logic in case of asp.net core 2 graphql endpoint?

I have the following code snippet developed using asp.net web api 2 and EntityFramework 6.
public class TestController : BaseApiController
{
private readonly ITestService _testService;
private readonly ICommonService _commonService;
private readonly IImageService _imageService;
public TestController(ITestService testService, ICommonService commonService, IImageService imageService)
{
_testService = testService;
_commonService = commonService;
_imageService = imageService;
}
[Route("test")]
public IHttpActionResult Get()
{
var resp = _testService.GetDetailsForLocation(locale);
return Ok(resp);
}
}
public class BaseApiController : ApiController
{
public string locale
{
get
{
if (Request.Headers.Contains("Accept-Language"))
{
return Request.Headers.GetValues("Accept-Language").First();
}
else
{
return string.Empty;
}
}
}
public string GetCookieId()
{
string value = string.Empty;
IEnumerable<CookieHeaderValue> cookies = this.Request.Headers.GetCookies("mycookie");
if (cookies.Any())
{
IEnumerable<CookieState> cookie = cookies.First().Cookies;
if (cookie.Any())
{
var cookieValue = cookie.FirstOrDefault(x => x.Name == "mycookie");
if (cookieValue != null)
value = cookieValue.Value.ToLower();
}
}
return value;
}
}
I am converting the existing restapi endpoint to graphql endpoint using asp.net core 2 and graphql.net. In the below method, at present I am sending "en" as the value but I want to pass the locale value as exactly done in case of asp.net web api 2 in the above implementation.
Here I would like to know what is the best way to read the request headers and pass the value to the business loigc (i.e in this case to the method:GetDetailsForLocation("en")
public class TestQuery : ObjectGraphType<object>
{
public TestQuery(ITestService testService)
{
Field<TestResultType>("result", resolve: context => testService.GetDetailsForLocation("en"), description: "Test data");
}
}
Can anyone help me to provide their guidance in resolving the issue?
The easiest route would be to use IHttpContextAccessor. Register IHttpContextAccessor as a singleton.
https://adamstorr.azurewebsites.net/blog/are-you-registering-ihttpcontextaccessor-correctly
In StartUp.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
GraphQL class:
public class TestQuery : ObjectGraphType<object>
{
public TestQuery(ITestService testService, IHttpContextAccessor accessor)
{
Field<TestResultType>(
"result",
description: "Test data",
resolve: context => testService.GetDetailsForLocation(accessor.HttpContext...)
);
}
}

OWIN - Object reference not set to an instance of object

I am using asp.net mvc 5 to develop a web application.But i got some error while playing with the users account.I have Created a user account and i want to delete it but facing the following issue while doing it with ajax-jquery.
I am trying to delete a user account using ajax request but it gives the error for null object reference as Owin Context is not initiated due to ajax call.
public class AdmissionsController : Controller
{
private ApplicationSignInManager _signInManager;
private ApplicationUserManager _userManager;
public AdmissionsController()
{
}
public AdmissionsController(ApplicationUserManager userManager, ApplicationSignInManager signInManager)
{
UserManager = userManager;
SignInManager = signInManager;
}
public ApplicationSignInManager SignInManager
{
get
{
return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
}
private set
{
_signInManager = value;
}
}
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
//function to delete user account
public async Task<object> DeleteUser(string id)
{
ApplicationDbContext context = new ApplicationDbContext();
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var user = await _userManager.FindByIdAsync(id);
var logins = user.Logins;
var rolesForUser = await _userManager.GetRolesAsync(id);
using (var transaction = context.Database.BeginTransaction())
{
foreach (var login in logins.ToList())
{
await _userManager.RemoveLoginAsync(login.UserId, new UserLoginInfo(login.LoginProvider, login.ProviderKey));
}
if (rolesForUser.Count() > 0)
{
foreach (var item in rolesForUser.ToList())
{
// item should be the name of the role
var result = await _userManager.RemoveFromRoleAsync(user.Id, item);
}
}
await _userManager.DeleteAsync(user);
transaction.Commit();
}
return new{success=true};
}
}
And my ajax call as follow :
var userid = $(this).attr("data-StudentId");
var success = false;
$.ajax({
method: "Get",
url: "/Area/Admissions/DeleteUser",
data: { "id": userid },
success: function (response) {
if (response.Success == true) {
success = true;
}
else if (response.Success == false) {
//window.location.reload();
}
},
error: function (response) {
notificationMSG("fa fa-thumbs-up", "error", "Error", response.message);
}
});
How can i resolve this issue???
I am getting the error at the following line:
var user = await _userManager.FindByIdAsync(id);
This is just a wild guess, but it seems to me that you do not instantiate _userManager. You have a corresponding property where this creation takes place. However, in the line with error you use private field. Try to use the property:
var user = await UserManager.FindByIdAsync(id);
This will call the getter where you get this manager from the owin context.

Categories

Resources