C# console doesn't print exception message - asp.net

I have a ASP.NET project and in some part of it I call a business rule to test the form:
[HttpPost]
public ActionResult InsertProduct(Product Product)
{
try
{
InsertProductBLL ProductInsertion = new InsertProductBLL (Product.Value, Product.Description);
ProductInsertion.IsValid();
return PartialView("Success");
}
catch (Exception e)
{
Console.Write(e.Message);
return PartialView("Fail");
}
}
On the BLL, I have this:
public void IsValid()
{
if (Value> 10) ; //I just want the else section
else
{
Exception e = new Exception("Insert a bigger value");
throw e;
}
}
However, the console only prints that the exception has been thrown, but not the message that I asked for. Is there any syntax mistake or something that I just messed up?

You can do something like this,
Create Result Object which can be used to transmit data between layers.
public class Result
{
public HasResult { get; set; }
public ErrorMessage { get; set;}
public SuccessMessage { get; set;}
}
Transfer as a Result Object to the calling layer (here in your case Controller) after all your business validations.
public Result IsValid(int Value)
{
var result = new Result();
result.HasResult = Value > 10;//set this after all your business rules
if(HasResult)
{
result.SuccessMessage = "Success";
}
else
{
result.ErrorMessage = "Insert a bigger value";
}
return result;
}
In Controller
[HttpPost]
public ActionResult InsertProduct(Product Product)
{
var returnMessage = "";
try
{
InsertProductBLL ProductInsertion = new InsertProductBLL (Product.Value, Product.Description);
var result = ProductInsertion.IsValid(Product.Value);
returnMessage = result.HasResult
? result.SuccessMessage
: result.ErrorMessage;
}
catch (Exception e)
{
Console.Write(e.Message);
returnMessage = "Fail";
}
return PartialView(returnMessage);
}

Related

How to create a custom error message for Authorize attribute?

I want only admins to have access to this controller and its actions, so I've written this code:
[Authorize(Roles = Helper.AdminRole)]
public class AdminController : Controller
{
public IActionResult AdminPanel()
{
return View();
}
//other actions only available to admins
}
If the user is not logged in and he's not in the specified role I get a 404 Not Found page and this in the URL:
..../AccessDenied?ReturnUrl=%2FAdmin%2FAdminPanel
How can I make a custom error page for this scenario where the user is asked to log in so he can confirm his role, and when he does log in successfully AND he is in the right role to be redirected to where he wanted to go, but if his role is invalid to be redirected elsewhere/ shown a custom error page?
Your error was caused due to lack of Loginpath settings,not wrong role or password.(So the error code was 404 not 401)
You could see the test Result:
If you want to custom error page,you could read the official document:
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-5.0
I tried with the codes below:
ErrorResult class:
public class ErrorResult
{
public bool Success { get; set; } = true;
public string Msg { get; set; } = "";
public string Type { get; set; } = "";
public object Data { get; set; } = "";
public object DataExt { get; set; } = "";
}
ErrorHandlingMiddleware:
public class ErrorHandlingMiddleware
{
private readonly RequestDelegate next;
public ErrorHandlingMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext context)
{
try
{
await next(context);
}
catch (Exception ex)
{
var statusCode = context.Response.StatusCode;
if (ex is ArgumentException)
{
statusCode = 200;
}
await HandleExceptionAsync(context, statusCode, ex.Message);
}
finally
{
var statusCode = context.Response.StatusCode;
var msg = "";
if (statusCode == 401)
{
msg = "unauthorize";
}
else if (statusCode == 404)
{
msg = "NotFound";
}
else if (statusCode == 400)
{
msg = "BadRequest";
}
else if (statusCode != 200)
{
msg = "Unkonwn";
}
if (!string.IsNullOrWhiteSpace(msg))
{
await HandleExceptionAsync(context, statusCode, msg);
}
}
}
private static Task HandleExceptionAsync(HttpContext context, int statusCode, string msg)
{
var result = JsonConvert.SerializeObject(new ErrorResult() { Success = false, Msg = msg, Type = statusCode.ToString() });
context.Response.ContentType = "application/json;charset=utf-8";
return context.Response.WriteAsync(result);
}
}
public static class ErrorHandlingExtensions
{
public static IApplicationBuilder UseErrorHandling(this IApplicationBuilder builder)
{
return builder.UseMiddleware<ErrorHandlingMiddleware>();
}
}
in startup class:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
.....
app.UseErrorHandling();
....
}
The Result:
Take cookie authentication as an example, you just need to configure it like this in program.cs(.Net 6):
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(x =>
{
//When user doesn't login and he access to an action with [Authorize],
//He will redirect to the loginPath
x.LoginPath = "/{controller}/{action}";
//When user has loged in but the role is not the specified role,
//He will redicet to the AccessDeniedPath,
//Then you can custom your own error page in this path.
x.AccessDeniedPath = "/{controller}/{action}";
});

Returning all json objects using asp net core 2.1

I am able to retrive one json object from a url. I need help in retrieving a page full of json objects. I found this site, https://jsoneditoronline.org/, to show the json architecture of the page I want to return:
enter image description here
Here is my code:
namespace iexName.Controllers
{
[Route("api/IexName")]
[ApiController]
public class IexNameController : ControllerBase
{
private IHttpClientFactory _httpClientFactory;
public IexNameController(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
[HttpGet]
public IEnumerable<Models.IexTradingStock> GetQuote()
{
string responseString = string.Empty;
var Client = _httpClientFactory.CreateClient();
try
{
responseString =
Client.GetStringAsync($"https://api.iextrading.com/1.0/stock/aapl/chart/1y").Result;
}
catch (HttpRequestException hre)
{
Console.WriteLine(hre.Message);
//TODO do something
}
catch (Exception e)
{
Console.WriteLine(e.Message);
//TODO do something
}
//quit if get content fail
if (responseString == string.Empty) return null;
try
{
var stock = JsonConvert.DeserializeObject<IexTradingStock>
(responseString);
return stock;
}
The error is on "return stock;". I realize I do not know how to return all of the json objects.
Soon after I typed this into stackflow I realized what to do. This worked.
namespace iexName.Controllers
{
[Route("api/IexName")]
[ApiController]
public class IexNameController : ControllerBase
{
private IHttpClientFactory _httpClientFactory;
public IexNameController(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
[HttpGet]
public IEnumerable<Models.IexTradingStock> GetQuote()
{
string responseString = string.Empty;
var Client = _httpClientFactory.CreateClient();
try
{
responseString =
Client.GetStringAsync($"https://api.iextrading.com/1.0/stock/aapl/chart/1y").Result;
}
catch (HttpRequestException hre)
{
Console.WriteLine(hre.Message);
//TODO do something
}
catch (Exception e)
{
Console.WriteLine(e.Message);
//TODO do something
}
//quit if get content fail
if (responseString == string.Empty) return null;
try
{` List<IexTradingStock> stock =
JsonConvert.DeserializeObject<List<IexTradingStock>>(responseString);
return stock;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
//TODO do something
return null;
}
}
}
}`

sqlite-net-extensions -- Create Table Async

My problem is that I'm using the CreateTableAsync method and is always returning "0". I researched and saw that this return is a mistake.
I wanted to know what I'm doing wrong.
Class Service Table:
public class SqliteTable
{
private readonly SqliteWrapper _sqliteWrapper;
public SqliteTable()
{
_sqliteWrapper = new SqliteWrapper();
}
private async Task<bool> CheckIfExistTable<T>() where T : new()
{
var connection = _sqliteWrapper.OpenDatabase();
try
{
var result = await connection.Table<T>().CountAsync();
return result.Equals(0);
}
catch (Exception e)
{
Logs.Logs.Error($"Error get count table {typeof(T).Name}: {e.Message}");
return false;
}
}
public async void CreateTable<T>() where T : new()
{
var connection = _sqliteWrapper.OpenDatabase();
if (await CheckIfExistTable<T>())
{
Logs.Logs.Info($"This table {typeof(T).Name} was created");
return;
}
var createTableResult = await connection.CreateTableAsync<T>();
var value = createTableResult.Results.Values.FirstOrDefault();
if (value.Equals(1))
{
Logs.Logs.Info($"Create table {typeof(T).Name}");
}
else
{
throw new Exception($"Error create table {typeof(T).Name}");
}
}
}
I create a Class Model Login. which would be the object to create the database.
public class Login
{
public Login()
{
}
public Login(string user, string password)
{
User = user;
Password = password;
}
public Login(int id, string user, string password)
{
Id = id;
User = user;
Password = password;
}
[PrimaryKey, AutoIncrement, Column("login_id")]
public int Id { get; set; }
[Unique, NotNull, Column("login_user")]
public string User { get; set; }
[NotNull, Column("login_password")] public string Password { get; set; }
}
I create Class CreateTableAsync. Which would be to intanciar the SqliteTable, to call the method CreateTable sending the object to create the database:
protected override void OnStart()
{
try
{
var sqliteTable = new SqliteTable();
sqliteTable.CreateTable<Login>();
}
catch (Exception e)
{
Logs.Logs.Error($"Error init application: {e.Message}");
}
}
Can someone help me?

How can I confirm if an async EF6 await db.SaveChangesAsync() worked as expected?

My code looks like this:
public async Task<IHttpActionResult> Delete(int id)
{
var userId = Int32.Parse(User.Identity.GetUserId());
UserTest userTest = await db.UserTests.FindAsync(id);
if (userTest == null)
{
return NotFound();
}
if (userTest.UserId != userId)
{
return Unauthorized();
}
db.UserTests.Remove(userTest);
await db.SaveChangesAsync();
return Ok();
}
I think everything up to the db.SaveChangesAsync is okay but how can I confirm if the db.SaveChangesAsync works before doing a return Ok() ? Ideally I think I should be checking for exceptions and things but I am not sure how I could fit that into this code block.
From msdn:
public virtual Task<int> SaveChangesAsync()
Return Value Type: System.Threading.Tasks.Task A task that
represents the asynchronous save operation. The task result contains
the number of objects written to the underlying database.
Check if the result is greater than 0:
if(await db.SaveChangesAsync() > 0)
{
.....
}
More info here
Another option is to wrap this with try ... catch block:
try
{
await db.SaveChangesAsync();
return Ok();
}
catch (Exception ex)
{
return NotFound(ex.Message);
}
You can use the following below :)
try {
int writtenEntriesCount = await db.SaveChangesAsync();
if(writtenEntriesCount > 0){
// is saved
}else{
// is not saved
}
} catch(e) {
// handle error here
}
I normally use this if it helps:
try
{
_context.Events.Add(entity);
await _context.SaveChangesAsync(cancellationToken);
return new CommandResult() { IsSuccess = true };
}
catch (Exception ex)
{
return new CommandResult() { IsSuccess = false,IsError =True, Message=ex.Message };
}
public class CommandResult
{
public bool IsSuccess { get; internal set; }
public bool IsError { get; internal set; }
public string Message { get; internal set; }
}

How to consume this web service?

This is my first time creating a web service. I am not sure if my implementation is incorrect, but I am trying to use much like a class. The problem is that when I am trying to consume I am getting confused and not being able to set the values of the properties.
here is the web service.
public class Service1 : System.Web.Services.WebService
{
private bool _isUserActive { get; set; }
private bool _isCredentialValid { get; set; }
public string email { get; set; }
public string pass { get; set; }
public int customerID { get; set; }
[WebMethod]
public bool VerifyUserCredential()
{
bool result = false;
PURLDataContext purl = new PURLDataContext();
try
{
var res = purl.Sel_User(email.ToLower(), pass);
if (res != null)
result = true;
_isUserActive = true;
_isCredentialValid = true;
}
catch (Exception ex)
{
if (ex.Message == "Account is inactive, please contact your administrator!")
{
_isUserActive = false;
_isCredentialValid = false;
}
else
_isCredentialValid = false;
//Invalid credentials.
}
return result;
}
[WebMethod]
public ArrayList retrieveCustomerInfo()
{
ArrayList customerInfo = new ArrayList();
string validate = "Please Validate";
if (_isCredentialValid)
{
PURLDataContext purl = new PURLDataContext();
var customer = purl.Sel_Recipient(customerID);
foreach (var c in customer)
{
customerInfo.Add(c);
}
}
else
customerInfo.Add(validate);
return customerInfo;
}
}
Here is what I am trying to do to consume.
PURLServices.Service1SoapClient webserv = new Service1SoapClient();
bool result;
ArrayOfAnyType array = new ArrayOfAnyType();
webserv.email = "email#email.com";
webserv.pass = "pass";
webserv.customerID = 12345;
result = webserv.VerifyUserCredential();
array = webserv.retrieveCustomerInfo();
Thank you for any help/
You do not want to try to use properties like this. Your method should look more like this:
public bool VerifyUserCredential(string userName, string password)
{
// method body here
}
Probably you would want to return an access token of some sort that the server will cache. This can then be passed into other methods to show that the user is valid.

Resources