change phone number in asp identity - asp.net-core

I have problem with updating of phone number in my ASP net core application.
All fields except phone number are saving in DB. I tried 3 different ways to update phone:
set manualy
use UserManager.SetPhoneNumberAsync()
use UserManager.ChangePhoneNumberAsync() with token generation
All of them are not working. And there are no any errors. Help me please
[HttpPost][AllowAnonymous]
public async Task UpdateLogin(UpdateAccountRequest request)
{
try {
var user = await UserService.FindExistingUserAsync(request.CurrentEmail, request.CurrentPhoneNumber);
var account = user.Accounts.SingleOrDefault(x = > x.AccountId == request.AccountId);
account.FirstName = request.PatientFirstName;
account.LastName = request.PatientLastName;
var changePhoneNumberToken = await UserManager.GenerateChangePhoneNumberTokenAsync(user, request.UpdatedPhoneNumber);
var changePhoneResult = await UserManager.ChangePhoneNumberAsync(user, request.UpdatedPhoneNumber, changePhoneNumberToken);
if (!changePhoneResult.Succeeded) {
return StatusCode(StatusCodes.Status500InternalServerError, changePhoneResult.Errors);
}
var updateResult = await UserManager.UpdateAsync(user);
if (!result.Succeeded) {
return StatusCode(StatusCodes.Status500InternalServerError);
}
return Ok("User updated");
}
catch (Exception ex) {
return StatusCode(StatusCodes.Status500InternalServerError, ex.Message);
}
}

Problem disappeared. Loks like DB was not updated

Related

Using MQTT ManagedClient with ASP NET API, how to?

I'm currently working on a project that has to rely heavily on MQTT - one of the parts that needs to utilize MQTT is a ASP Net API, but I'm having difficulties receiving messages.
Here is my MQTTHandler:
public MQTTHandler()
{
_mqttUrl = Properties.Resources.mqttURL ?? "";
_mqttPort = Properties.Resources.mqttPort ?? "";
_mqttUsername = Properties.Resources.mqttUsername ?? "";
_mqttPassword = Properties.Resources.mqttUsername ?? "";
_mqttFactory = new MqttFactory();
_tls = false;
}
public async Task<IManagedMqttClient> ConnectClientAsync()
{
var clientID = Guid.NewGuid().ToString();
var messageBuilder = new MqttClientOptionsBuilder()
.WithClientId(clientID)
.WithCredentials(_mqttUsername, _mqttPassword)
.WithTcpServer(_mqttUrl, Convert.ToInt32(_mqttPort));
var options = _tls ? messageBuilder.WithTls().Build() : messageBuilder.Build();
var managedOptions = new ManagedMqttClientOptionsBuilder()
.WithAutoReconnectDelay(TimeSpan.FromSeconds(5))
.WithClientOptions(options)
.Build();
_mqttClient = new MqttFactory().CreateManagedMqttClient();
await _mqttClient.StartAsync(managedOptions);
Console.WriteLine("Klient startet");
return _mqttClient;
}
public async Task PublishAsync(string topic, string payload, bool retainFlag = true, int qos = 1)
{
await _mqttClient.EnqueueAsync(new MqttApplicationMessageBuilder()
.WithTopic(topic)
.WithPayload(payload)
.WithQualityOfServiceLevel((MQTTnet.Protocol.MqttQualityOfServiceLevel)qos)
.WithRetainFlag(retainFlag)
.Build());
Console.WriteLine("Besked published");
}
public async Task SubscribeAsync(string topic, int qos = 1)
{
var topicFilters = new List<MQTTnet.Packets.MqttTopicFilter>
{
new MqttTopicFilterBuilder()
.WithTopic(topic)
.WithQualityOfServiceLevel((MQTTnet.Protocol.MqttQualityOfServiceLevel)(qos))
.Build()
};
await _mqttClient.SubscribeAsync(topicFilters);
}
public Status GetSystemStatus(MqttApplicationMessageReceivedEventArgs e)
{
try
{
var json = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
var status = JsonSerializer.Deserialize<Status>(json);
if (status != null)
{
return status;
}
else
{
return null;
}
}
catch (Exception)
{
throw;
}
}
The above has been tested with a console app and works as it should.
The reason I need MQTT in the APi is that a POST method has to act on the value of a topic;
In particular I need to check a systems status before allowing the post;
[HttpPost]
public async Task<ActionResult<Order>> PostOrder(Order order)
{
if (_lastStatus != null)
{
if (_lastStatus.OpStatus)
{
return StatusCode(400, "System is busy!");
}
else
{
var response = await _orderManager.AddOrder(order);
return StatusCode(response.StatusCode, response.Message);
}
}
return StatusCode(400, "Something went wrong");
}
So I will need to set up a subscriber for this controller, and set the value of _lastStatus on received messages:
private readonly MQTTHandler _mqttHandler;
private IManagedMqttClient _mqttClient;
private Status _lastStatus;
public OrdersController(OrderManager orderManager)
{
_orderManager = orderManager;
_mqttHandler = new MQTTHandler();
_mqttClient = _mqttHandler.ConnectClientAsync().Result;
_mqttHandler.SubscribeAsync("JSON/Status");
_mqttClient.ApplicationMessageReceivedAsync += e =>
{
_lastStatus = _mqttHandler.GetSystemStatus(e);
return Task.CompletedTask;
};
}
However, it's behaving a little odd and I'm not experienced enough to know why.
The first time I make a POST request, _lastStatus is null - every following POST request seem to have the last retained message.
I'm guessing that I am struggling due to stuff being asynchronous, but not sure, and every attempt I've attempted to make it synchronous have failed.
Anyone have a clue about what I'm doing wrong?

Update existing table row in the same method that uses HttpPost to add a new entry

I have a web game that uses .NetCore Entity Framework.
I have one method that uses HttpPost to create a new Monster in the database.
This method also needs to add a foreign key, the new MonsterId, to an existing Dungeon in the table called DungeonList.
I got the part where the method creates a new Monster correctly.
However I'm not sure how to insert the new MonsterId into the appropriate Dungeon of DungeonList.
I'm not exactly sure how to get the Id of the Dungeon.
Should I pass in the DungeonId from the frontend?
I'm really confused.
Here is what I have so far but I am not sure where to go from here.
I'd love some advice...thank you!
[HttpPost]
public async Task<ActionResult<MonsterList>> PostMonsterList(MonsterList monsterList)
{
monsterList.MonsterId = Guid.NewGuid();
_context.MonsterList.Add(monsterList);
var dungeonListRef = new DungeonList();
if(dungeonListRef.MonsterId == null)
{
// ????
}
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateException)
{
if (MonsterListExists(monsterList.MonsterId))
{
return Conflict();
}
else
{
throw;
}
}
_context.DungeonList.Add(dungeonListRef);
return CreatedAtAction("GetMonsterList", new { id = monsterList.MonsterId }, monsterList);
}
Add Dungeon drop down list in your "Add new Monster" page. Send drop down list's dungeonID to PostMonsterList function.
[HttpPost]
public async Task<ActionResult<MonsterList>> PostMonsterList(Guid dungeonId, MonsterList monsterList)
{
Guid newMonsterId = Guid.NewGuid();
monsterList.MonsterId = newMonsterId;
_context.MonsterList.Add(monsterList);
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateException)
{
if (MonsterListExists(monsterList.MonsterId))
{
return Conflict();
}
else
{
throw;
}
}
var dungeonList = _context.DungeonList.Where(x => x.DungeonId == dungeonId).FirstOrDefault();
dungeonList.MonsterId = newMonsterId;
_context.DungeonList.Update(dungeonList);
await _context.SaveChangesAsync();
return CreatedAtAction("GetMonsterList", new { id = monsterList.MonsterId }, monsterList);
}

how to delete users including roles and users from AspnetRoleUsers

I am making a project using asp.net core 3.1 and I can't find the right source of deleting users including roles in Asp.net core 3.1 using Web.api
This is the code I have tried but seems like not appropriate but haven't tried yet. Do you have any ideas of how to realize that?
I want to appropriately check the error using Web Api functions such as statuscode or any error messages to the frontend.
[HttpPost, ActionName("Delete")]
public async Task<ActionResult> DeleteUser(string id)
{
var user = await _userManager.FindByIdAsync(id);
var rolesForUser = await _userManager.GetRolesAsync(user);
if (rolesForUser.Count() > 0)
{
foreach (var item in rolesForUser.ToList())
{
// item should be the name of the role
var result = await _userManager.RemoveFromRoleAsync(user, item);
}
}
await _userManager.DeleteAsync(user);
return OkResult(result);
}
You don't need to loop the roles and delete , you can use RemoveFromRolesAsync :
public virtual Task<IdentityResult> RemoveFromRolesAsync(TUser user, IEnumerable<string> roles);
And each operation will return IdentityResult which could be used to check the operation status :
if (User.Identity.IsAuthenticated)
{
try
{
var user = await _userManager.FindByIdAsync(id);
var roles= await _userManager.GetRolesAsync(user);
var result = await _userManager.RemoveFromRolesAsync(user, roles);
if (result.Succeeded)
{
var resultdelete = await _userManager.DeleteAsync(user);
if (result.Succeeded)
{
return Ok();
}
else
{
List<string> errors = new List<string>();
foreach (var error in result.Errors)
{
errors.Add(error.Description);
}
return BadRequest(errors);
}
}
else
{
List<string> errors = new List<string>();
foreach (var error in result.Errors)
{
errors.Add(error.Description);
}
return BadRequest(errors);
}
}
catch (Exception exception)
{
List<string> errors = new List<string>() { exception.Message };
return StatusCode(StatusCodes.Status500InternalServerError, errors);
}
}
But use database stored procedures with transaction is always a good choice .

Flurl Post Not Returning from Web Api

I've got a Xamarin application using Flurl, with the following post to a Web Api
Xamarin App:
private async Task<LoginResponse> processLogin()
{
try
{
return await "http://192.168.0.12:60257/api/loginapi/Login".WithTimeout(10).PostJsonAsync(new { username = "fsdafsd", password = "gdfgdsf" }).ReceiveJson<LoginResponse>();
}
catch (Exception e)
{
return new LoginResponse { ResponseStatusCode = -1 };
}
}
Web Api:
public LoginResponse Login([FromBody]LoginRequest loginRequest)
{
var result = new LoginResponse();
try
{
var user = this.UserManager.FindAsync(loginRequest.username, loginRequest.password);
if (user != null)
{
result.ResponseStatusCode = 1;
}
else
{
result.ResponseStatusCode = 0;
}
}
catch (Exception e)
{
result.ResponseStatusCode = -1;
}
return result;
}
I can see my Web Api method getting hit, and it returns the expected object type, not my Xamarin application continues to wait on the Flurl Post.
Can anyone advise what I might be doing wrong?
UPDATE:
I have noticed that the following does work, but it's not ideal:
dynamic result = await "http://192.168.0.12:60257/api/loginapi/Login".PostJsonAsync(new { username = "fsdafsd", password = "gdfgdsf" }).ReceiveJson();
Fixed it. For whatever reason, it was the type I was trying to return. Changing the object variable type to "dynamic" fixed this, and allowed me to deserialise the object correctly.
dynamic result = await "http://192.168.0.12:60257/api/loginapi/Login".PostJsonAsync(new { username = "fsdafsd", password = "gdfgdsf" }).ReceiveJson();
Returns a dynamic object with the properties I'd expect in the normal structure.
If anyone can enlighten my why I couldn't do:
LoginRequest result = ...
It'd be appreciated.

Reditect url from the method of notify_url of paypal in mvc

i am using paypal for payment. in paypal i found two type url -
return_url
notify_url
i wan to check the validity after transaction, save some data and then redirect buyer to receipt page with a unique value that is saved in db. that is why i m not using redirect_url
here is my code
[HttpPost]
public ActionResult TestPaypalIpn()
{
var response = new StreamReader(Request.InputStream, System.Text.Encoding.UTF8).ReadToEnd();
var webClient = new WebClient();
string address = "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_notify-validate&" + response;
System.IO.File.WriteAllText(#"D:\Streamstech\Content\requestAddress.txt", address);
try
{
string result = webClient.DownloadString(address);
System.IO.File.WriteAllText(#"D:\Streamstech\Content\response.txt", result);
if (result == "VERIFIED")
{
if (Request.Params["payment_status"] == "Completed" && Request.Params["business"] == Request.Params["receiver_email"])
{
var lisenceKey = Request.Params["transaction_subject"];
var userProductLisence = UserProductLisenceRepository.GetConditional(
l => l.LisenceKey == lisenceKey).FirstOrDefault();
if (userProductLisence != null)
{
if (userProductLisence.PaypalTransactionId == null)
{
userProductLisence.PaypalTransactionId = Request.Params["txn_id"];
userProductLisence.PayerEmailForPaypalTransaction = Uri.EscapeUriString(Request.Params["payer_email"]);
UserProductLisenceRepository.Edit(userProductLisence);
return RedirectToAction("Receipt", "Transaction", new { requestId = userProductLisence.LisenceKey });
}
}
}
return RedirectToAction("ShowError", "Transaction", new { errorname = "", errorMessage = "something went wrong, try again later" });
}
return RedirectToAction("ShowError", "Transaction", new { errorname = "verification Problem", errorMessage = "Transaction not verified" });
}
catch (Exception e)
{
System.IO.File.WriteAllText(#"D:\Streamstech\Content\error.txt", e.Message);
return RedirectToAction("ShowError", "Transaction", new { errorname = "Error..!!!", errorMessage = "something went wrong, try again later" });
throw;
}
return null;
}
here i can compare, save data to database.. but it is not redirecting to receipt page.. what is the problem here in code...??
or any suggestion how can i do it.. ?
Thank You..
Based on your requirement, you need to use return_url instead of notify_url. For notify_url, it's used for receiving message in system back end and you maybe can't receive it immediately after payment is done. refer to https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNPDTAnAlternativetoIPN/