I am creating a web app with Razor Pages and I'm running into an issue. I am trying to send a message to the user when an exception is thrown. I'm imagining something similar to MessageBox class from System.Windows.Forms. Any ideas on whether this is possible or how to do it? Any help is appreciated.
try
{
double oneone = Convert.ToDouble(Project.projectServicesCost);
}
catch (Exception e)
{
//Throw message to user saying projectServicesCost is not in the correct
//format and therefore couldn't convert to double
}
Here's an example from my code.
You can use some library like NToastNotify.
You can follow the below steps to implement it:
1.Install NToastNotify package using Package Console Manager:
Install-Package NToastNotify
2.Configure NToastNotify service and
services.AddRazorPages().AddNToastNotifyNoty();
3.Add the middlware:
app.UseNToastNotify();
4.Add the view in _Layout page:
#await Component.InvokeAsync("NToastNotify")
5.Dependency injection IToastNotification then you can use it
public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;
private readonly IToastNotification _toastNotification;
public IndexModel(ILogger<IndexModel> logger, IToastNotification toastNotification)
{
_logger = logger;
_toastNotification = toastNotification;
}
public void OnGet()
{
try
{
throw new NullReferenceException();
}
catch
{
_toastNotification.AddErrorToastMessage("Some Error Message");
}
}
}
Result:
For more details, refer to:
https://github.com/nabinked/NToastNotify
You can use modal from Bootstrap and return on a ViewBag the exception and check when is not empty and display the modal
[HttpPost]
public ActionResult Save(int? id){
UserViewModel model = new UserViewModel();
if(id == null){
ViewBag.Exception = "Please select an ID";
return View();
}
model.User = context.Users.FisrtOrDefault(a => a.id == id);
return View(model);
}
<script>
$(document).ready(function(){
var exception = #String.IsNullOrEmpty(ViewBag.Exception).ToString().ToLower();
if(!exception){
$("#modal-body").text("#ViewBag.Exception");
$("#modal").modal("show");
}
});
</script>
Or use alert from js
<script>
$(document).ready(function(){
var exception = #String.IsNullOrEmpty(ViewBag.Exception).ToString().ToLower();
if(!exception){
alert("#ViewBag.Exception");
}
});
</script>
Related
I am working in a larger project, but because it is very complex I made my own small project to make an Azure Blobs Gallery, that displays images from Azure Blobs using container, to implement into the large project after that.
I was able to create this Gallery with the following .Net 6 / C# (MVC) code:
Controller
public class ResourceController : Controller
{
const string blobContainerName = "thumbnails";
static BlobContainerClient blobContainer;
private IConfiguration _configuration;
public ResourceController(IConfiguration configuration)
{
_configuration = configuration;
}
public ActionResult Index()
{
var model = LoadModelMethodAsync();
return View(model);
}
public ActionResult Info()
{
var model = LoadModelMethodAsync();
return View(model);
}
public List<Uri> LoadModelMethodAsync()
{
try
{
var s = _configuration.GetConnectionString("AzureStorageConnectionString");
BlobServiceClient blobServiceClient = new BlobServiceClient(s);
blobContainer = blobServiceClient.GetBlobContainerClient(blobContainerName);
blobContainer.CreateIfNotExistsAsync(PublicAccessType.Blob);
List<Uri> allBlobs = new List<Uri>();
foreach (BlobItem blob in blobContainer.GetBlobs())
{
if (blob.Properties.BlobType == BlobType.Block)
allBlobs.Add(blobContainer.GetBlobClient(blob.Name).Uri);
}
return allBlobs;
}
catch (Exception ex)
{
ViewData["message"] = ex.Message;
ViewData["trace"] = ex.StackTrace;
throw;
}
}
}
}
ViewModel
using Microsoft.AspNetCore.Mvc;
namespace EBP_V1.ViewModels {
public class ResourceViewModel
{
public string RequestId { get; set; }
public bool? ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
}
Partial
#using AzureBlobLearning.Models
#model List<Uri>
#{
}
#if (Model != null && Model.Count > 0)
{
foreach (var item in Model)
{
<div class="imageBlock" value="GetGallery">
<img class="thumb" src="#item" alt="images"/><br />
<div class="deleteDiv"><img class="deleteIcon" src="~/Images/deleteImage.png" title="Delete Image" onclick="deleteImage('#item');" /></div>
</div>
}
}
View: Info.cshtml
<partial name="~/Views/Resource/_ResourcePartial.cshtml"/>
This small project works well, but when I try to implement it in the large project, the page isn't working anymore, even though it doesn't throw any error, and when I try to debug it all the data the same as it was before.
Controller in the large project ( everything else is identical with the previous one)
[HttpGet]
public async Task<ViewResult> Info(Guid? id, string filterTxt )
{
await SetCompanyName(id, filterTxt);
var model = LoadModelMethodAsync();
return View(model);
}
The interesting thing is that even if I don't call the model variable in the View the page still won't work anymore.
Question:
Why my code doesn't work in the large project?
What should I change to make it work?
P.S.:
- I am a completely beginner in .Net 6 / C# world, my first language
is Javascript, so please be understanding.
- If you have any questions, suggestions don't hesitate to ask.
I am experiencing with the C#/.Net world using Azure Blobs.
I made a Gallery that takes the images from an Azure Blob Storage, and displays it on the screen.
I want to create a Partial View from it, because of the DRY principle so I could reuse it in other files as well.
When I display the Partial View on the index it works well, but when I try to display it in the Info.cshtml file doesn't find the Model variable.
Controller
public class ResourceController : Controller
{
const string blobContainerName = "blobContainer";
static BlobContainerClient blobContainer;
private IConfiguration _configuration;
public ResourceController(IConfiguration configuration)
{
_configuration = configuration;
}
// Create a List of images using Azure Blobs and Displays it on the Screen.
{
try
{
var s = _configuration.GetConnectionString("AzureConnectionString");
BlobServiceClient blobServiceClient = new BlobServiceClient(s);
blobContainer = blobServiceClient.GetBlobContainerClient(blobContainerName);
await blobContainer.CreateIfNotExistsAsync(PublicAccessType.Blob);
List<Uri> allBlobs = new List<Uri>();
foreach (BlobItem blob in blobContainer.GetBlobs())
{
if (blob.Properties.BlobType == BlobType.Block)
allBlobs.Add(blobContainer.GetBlobClient(blob.Name).Uri);
}
return View(allBlobs);
}
catch (Exception ex)
{
ViewData["message"] = ex.Message;
ViewData["trace"] = ex.StackTrace;
return View("Error");
}
}
public ActionResult Info(){
//This class doesn't see the Model variable
return View();
}
Partial
//The Info class Doesn't see the Model variable
#if (Model != null && Model.Count > 0)
{
foreach (var item in Model)
{
<div class="imageBlock" value="GetGallery">
<img class="thumb" src="#item" alt="images"/><br />
<div class="deleteDiv"><img class="deleteIcon" src="~/Images/deleteImage.png" title="Delete Image" onclick="deleteImage('#item');" /></div>
</div>
}
}
ViewModel
using Microsoft.AspNetCore.Mvc;
namespace AzureBlobLearning.Models
{
public class ResourceViewModel
{
public string? RequestId { get; set; }
public bool? ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
}
Index.csthml
//This displays the list of images
<partial name="~/Views/Resource/_ResourcePartial.cshtml" />
Info.cshtml
//This doesn't display
<partial name="~/Views/Resource/_ResourcePartial.cshtml" />
My Question:
Why it doesn't see my Info view.
How should I change my code so the Info sees the partialView?
PS.: If you have any questions feel free to ask.
Why it doesn't see my Info view.
Because the action is just returning the View, with no Model inside.
Change from this:
public ActionResult Info(){
//This class doesn't see the Model variable
return View();
}
to this:
public ActionResult Index(){
var model = LoadModelMethod();
return View(model);
}
public ActionResult Info(){
var model = LoadModelMethod();
return View(model);
}
public List<Uri> LoadModelMethod()
{
try
{
var s = _configuration.GetConnectionString("AzureConnectionString");
BlobServiceClient blobServiceClient = new BlobServiceClient(s);
blobContainer = blobServiceClient.GetBlobContainerClient(blobContainerName);
await blobContainer.CreateIfNotExistsAsync(PublicAccessType.Blob);
List<Uri> allBlobs = new List<Uri>();
foreach (BlobItem blob in blobContainer.GetBlobs())
{
if (blob.Properties.BlobType == BlobType.Block)
allBlobs.Add(blobContainer.GetBlobClient(blob.Name).Uri);
}
return allBlobs;
}
catch (Exception ex)
{
ViewData["message"] = ex.Message;
ViewData["trace"] = ex.StackTrace;
throw;
}
}
How should I change my code so the Info sees the partialView?
you can do what I said above, extract the logic which loads the images to a method, and call it in both actions.
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
I have to set the reason phrase in my asp 5 middle-ware, not just the status code for the http response messages, but I could not found any way to do it.
The StatusCode property of the Microsoft.AspNet.Http.HttpResponse class is an int property for modifying the status code only, but not the reason text.
I understand, that the reason is set automatically according to the status code, but in my case I have to set it to custom values. Which is OK according to the HTTP RFC 2616:
[..] The reason phrases listed here are only recommendations -- they MAY be replaced by local equivalents without affecting the protocol. [..]
I'm currently using beta-8 version of the asp 5 framework.
You could try:
Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = "some reason";
An HttpStatusCodeResult that also returns a reason could look like:
public class BadRequestResult : HttpStatusCodeResult
{
private readonly string _reason;
public BadRequestResult(string reason) : base(400)
{
_reason = reason;
}
public override void ExecuteResult(ActionContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
context.HttpContext.Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = _reason;
context.HttpContext.Response.StatusCode = StatusCode;
}
}
Try this
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Title = "Home Page";
return View();
}
public ActionResult TestError() // id = error code
{
return new HttpStatusCodeResult(301, "Your custom error text");
}
}
Now check http://localhost:33470/home/Testerror
And look at Fiddler
I'm working on an ASP.NET MVC application and just getting to error handling. Help me solve the issue of getting the error message back to the user.
I have a controller:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Show(string callNumber)
{
ServiceCallService sc = new ServiceCallService();
return View(sc.GetServiceCallByCallNumber("", callNumber));
}
a Service:
public ServiceCall GetServiceCallByCallNumber(string custID, string callNumber)
{
ServiceCall sc = new ServiceCall();
sc = _serviceCallRepository.GetServiceCallByCallNumber(custID, callNumber);
return sc;
}
a Repository:
public ServiceCall GetServiceCallByCallNumber(string custID, string callNumber)
{
ServiceCall sc = new ServiceCall();
try
{
LoginToDB();
sc.CallNumber = "123";
}
catch (Exception e)
{
logger.error(Server.GetLastError());
}
finally
{
LogoutFromDB();
}
return sc;
}
Let's say there is a problem in the LoginToDB() method. I am logging the error but how do I get the error message back to the controller and then to the view.
Thanks.
The easiest way are:-
1) To use the build in model validation in ASP.NET MVC Release Canditate 1 (download from asp.net/mvc).
2) Re-throw the exception and catch it in your controller action then pass a nice customized error message to the View to render to the user - pass it using ViewData["error"] or something similar.