I have created a WEB API in visual studio 2015 using MySQL DB. I have three GET methods. One is which gives all the data, second one is which gives the result based on ID and 3rd one is which should gives result on basis of a serial number. First two methods are working perfect but the last one is not. I have also added multiple Routes in the solution. Below is my code
WebApiConfig
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "GetByMsn",
routeTemplate: "api/{controller}/{action}/{msn}",
defaults: null,
constraints: new { msn = #"^[a-z]+$" }
Controller
public HttpResponseMessage Get()
{
try
{
return Request.CreateResponse(HttpStatusCode.Found, mEntities.meters_info_dev.ToList());
}
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
}
// GET by ID
public HttpResponseMessage GetByID(int id)
{
try
{
return Request.CreateResponse(HttpStatusCode.Found, mEntities.meters_info_dev.SingleOrDefault(m => m.id == id));
}
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
}
// GET by serial number
public HttpResponseMessage GetByMsn(string msn)
{
try
{
return Request.CreateResponse(HttpStatusCode.Found, mEntities.meters_info_dev.SingleOrDefault(m=> m.meter_msn == msn));
}
catch
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, "No Data found");
}
}
GetByMsn is the one which is not working. I have tried to change the routes but still the result is same. The solution 1 and solution 2 given are not working for me.
Any help would be highly appreciated.
config.Routes.MapHttpRoute(
name: "GetByMsn",
routeTemplate: "api/{controller}/{action}/{msn}",
defaults: null,
constraints: new { msn = #"^[a-z]+$" }
In above the constraints were alphabetic, I just change it to #"^[0-9]+$" and it starts working for me.
Related
I'm not quite understanding the exception handling in await-able tasks. I have a primary task that needs to complete and yield its result to dependent tasks. So, the primary task must complete first, then, the subsequent tasks can run asynchronously. If the initial/primary task fails and throws an exception, I need to handle the exception properly and exit the program. If the 2 dependent tasks hit any exceptions, I just need to report them properly. Two things are happening in the code below... 1) Task 2 and 3 are running synchronously (I want them to run asynchronously)... AND 2) if I uncomment the exception throw inside DoStringStuff, I will get the "Exception User-Unhandled" message and the program stops (and I want this exception to bubble up to the top like normal and simply be printed to the console). I'm missing some important semantics here. Any help in the right direction is much appreciated!
UPDATE:
I found the issue, if this will help anyone... I needed to declare all my tasks at the outset of the function (not dynamically). Below is the working code. The Exceptions (if any) will propagate up as expected.
await parent();
Console.ReadKey();
static async Task parent()
{
Console.WriteLine("start of parent");
string sResult;
try
{
sResult = MyTask1("1111");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
return;
}
try
{
string result = await DoRemainingTasks(sResult);
Console.WriteLine();
Console.WriteLine(result);
}
catch(Exception ex)
{
Console.Write(ex.ToString());
}
Console.WriteLine("end of parent");
}
static async Task<string> DoRemainingTasks(string sResult)
{
Task<string> task2 = MyTask2(sResult);
Task<string> task3 = MyTask3("3333");
string t2Result = string.Empty;
string t3Result = string.Empty;
try
{
t2Result = await task2;
}
catch(Exception ex)
{
Console.WriteLine("Task 2 issue. Error = " + ex.Message);
}
try
{
t3Result = await task3;
}
catch (Exception ex)
{
Console.WriteLine("Task 3 issue. Error = " + ex.Message);
}
return "Remaining tasks done: " + t2Result + "... " + t3Result;
}
static Task<string> DoStringStuff(string s)
{
foreach (char c in s)
{
Console.Write(c);
Thread.Sleep(500);
}
Console.WriteLine();
return Task.FromResult(s);
}
static async Task<string> DoStringStuffAsync(string s)
{
return await Task.Run(() =>
{
foreach (char c in s)
{
Console.Write(c);
Thread.Sleep(500);
}
Console.WriteLine();
return s;
});
//throw new Exception($"task {s} failure");
}
static string MyTask1(string svar)
{
try
{
DoStringStuff(svar);
Console.WriteLine();
Console.WriteLine("task 1 done");
}
catch
{
throw;
}
return "2222";
}
static async Task<string> MyTask2(string svar)
{
return await Task.Run(async () =>
{
string s = await DoStringStuffAsync(svar);
return "task done for " + s;
});
}
static async Task<string> MyTask3(string svar)
{
return await Task.Run(async () =>
{
string s = await DoStringStuffAsync(svar);
return "task done for " + s;
});
}
We have an JQuery Ajax call that will execute when a user is about to leave a page on a DNN module.
This error is being logged the whole time in the DNN logs.
How can I improve the error handling so that it doesn't log the whole time?
Here is the DNN log:
Here is the Front End Code on the Module :
$(window).on("beforeunload", function () {
ClearTempUserSessionWhenLeavePage();
});
function ClearTempUserSessionWhenLeavePage() {
if ($fromButtonEvent == false) {
var Url = $.fn.GetBaseURL() + 'DesktopModules/DNNCommon/API/Store/ClearTempUserSessionWhenLeavePage';
$.ajax({
url: Url,
type: 'GET',
async: true,
dataType: 'json',
success: function () {
},
error: function (x, y, z) {
}
}).promise().done(function () {
});
}
$fromButtonEvent = false;
}
We are inheriting the DNNApiController class on our DNNCommon class.
This is the C# method being called:
[AllowAnonymous]
[HttpGet]
public void ClearTempUserSessionWhenLeavePage()
{
if (SessionManager.GetSessionObject("NewCreatedWebUser") != null)
{
System.Web.HttpContext.Current.Session["DoNotRemoveSessionIfNotAuthenticated"] = false;
SessionManager.SetSessionObject("NewCreatedWebUser", null);
SessionManager.SetSessionObject("UserInfo", null);
SessionManager.SetSessionObject("NewCustomerCode", null);
}
}
I have attempted to add two different types of Try Catch clauses, but when I debug the code it won't hit the breakpoints and somehow it still logs the error in the DNN Admin logs. Is there perhaps a Try Catch in the DNNController class that is writing this error?
First attempt with Try Catch Clause with TaskCanceledException and TimeoutException:
[AllowAnonymous]
[HttpGet]
public void ClearTempUserSessionWhenLeavePage()
{
try
{
if (SessionManager.GetSessionObject("NewCreatedWebUser") != null)
{
System.Web.HttpContext.Current.Session["DoNotRemoveSessionIfNotAuthenticated"] = false;
SessionManager.SetSessionObject("NewCreatedWebUser", null);
SessionManager.SetSessionObject("UserInfo", null);
SessionManager.SetSessionObject("NewCustomerCode", null);
}
}
catch (Exception ex)
{
EventLogController logController = new EventLogController();
if (ex.InnerException is TimeoutException)
{
ex = ex.InnerException;
}
else if (ex is TaskCanceledException)
{
if ((ex as TaskCanceledException).CancellationToken == null || (ex as TaskCanceledException).CancellationToken.IsCancellationRequested == false)
{
ex = new TimeoutException("Timeout occurred");
logController.AddLog("Timout Occured - Clearing Temp User Session When Leave Page.", ex.ToString(), EventLogController.EventLogType.ADMIN_ALERT);
}
}
logController.AddLog("Problem Clearing Temp User Session When Leave Page.", ex.ToString(), EventLogController.EventLogType.ADMIN_ALERT);
}
}
Second attempt with a TaskCanceledException:
[AllowAnonymous]
[HttpGet]
public void ClearTempUserSessionWhenLeavePage()
{
try
{
if (SessionManager.GetSessionObject("NewCreatedWebUser") != null)
{
System.Web.HttpContext.Current.Session["DoNotRemoveSessionIfNotAuthenticated"] = false;
SessionManager.SetSessionObject("NewCreatedWebUser", null);
SessionManager.SetSessionObject("UserInfo", null);
SessionManager.SetSessionObject("NewCustomerCode", null);
}
}
catch (TaskCanceledException ex)
{
EventLogController logController = new EventLogController();
logController.AddLog("Task Cancelled Exception - Clearing Temp User Session When Leave Page.", ex.ToString(), EventLogController.EventLogType.ADMIN_ALERT);
}
}
I have a controller that return a JSON text .
I write a function for it and have resource too for multi language.
but when I debug it it does not returns text.
It returns just txt : EmailExist
Is this what you have?
switch (newsLetter)
{
case NewsLetterResult.EmailExist:
return Json(new { text = _localizer["ExistsMembership"].Value });
case NewsLetterResult.Success:
return Json(new { text = _localizer["SuccessfulMembership"].Value });
default:
return Json(new { text = _localizer["UnknownMembership"].Value });
}
The return type of your method matters, it should normally be IActionResult for MVC endpoints - my test method for this question / answer looks like this (I don't have your localizer so I just returned the key):
public IActionResult Test()
{
var newsLetter = NewsLetterResult.EmailExist;
switch (newsLetter)
{
case NewsLetterResult.EmailExist:
return Json(new { text = "ExistsMembership" });
case NewsLetterResult.Success:
return Json(new { text = "SuccessfulMembership" });
default:
return Json(new { text = "Unknown" });
}
}
This works as expected / required:
{
"text": "ExistsMembership"
}
Note the following:
You should always include a default case for options that don't match the options you specify.
You don't need to wrap the case statements in brackets.
Newer syntax
If you are using C# 9 you can use new switch expressions and pattern matching which I personally prefer:
public IActionResult Test()
{
var newsLetter = NewsLetterResult.EmailExist;
return newsLetter switch
{
NewsLetterResult.EmailExist =>
Json(new { text = "ExistsMembership" }),
NewsLetterResult.Success =>
Json(new { text = "SuccessfulMembership" }),
_ =>
Json(new { text = "Unknown" })
};
}
This does the same thing as switch / case, and the _ at the end has the same purpose as the default case in the earlier example.
I am just starting using Vapor 4, and I created a POC to test how to save a Model into a local mySQL database.
Here is the code I am using for the controller that is supposed to save the model to the database.
public class ProductController {
static func create(req: Request) throws -> HTTPStatus {
do {
let input = try req.content.decode(Product.self)
let product = Product(name: input.name, imageUrl: input.imageUrl, priceAmount: input.priceAmount, priceCurrencyCode: input.priceCurrencyCode, category: input.category)
let _ = input.create(on: req.db).map {
print("Product saved")
}
return HTTPStatus.ok
} catch {
return HTTPStatus.badRequest
}
}
For some reason, "Product saved" never gets printed, so the closure is never called.
When I check in the database, the table products is always empty.
Thank you in advance for your help!
Karim
Try saving the product instead of the input:
return product.create(on: req.db).map { print("Product saved") }
.transform(to: .ok)
I have a method of action result in a controller where i have some conditions if the conditions fails then i want to send a json object to the view but i am not able to do it. can any one help me out.
[HttpPost]
public ActionResult Loginuser(LoginDetails newlogin)
{
LoginDetails objlogin = new LoginDetails();
objlogin.UserEmail = newlogin.UserEmail;
objlogin.UserPassword = newlogin.UserPassword;
try
{
if (ModelState.IsValid)
{
RegisterBAL Regball = new RegisterBAL();
objlogin = Regball.LoginUserBAL(objlogin);
if(objlogin.ResponseCode == "000")
{
if(objlogin.UserRole =="CityHelpdesk")
{
return RedirectToAction("CityHelpdesk", "RoleDashbord");
}
if (objlogin.UserRole == "CityAdmin")
{
return RedirectToAction("CityAdmin", "RoleDashbord");
}
if (objlogin.UserRole == "StateAdmin")
{
return RedirectToAction("StateAdmin", "RoleDashbord");
}
if (objlogin.UserRole == "StateHelpdesk")
{
return RedirectToAction("StateHelpdesk", "RoleDashbord");
}
}
else
{
return json object//// Hear i want to return the json object
}
}
}
catch (Exception)
{
objlogin.ResponseCode = "EXC";
}
}
You can return Json via the return Json() method
For your situation, that would be return Json(objlogin);
Be aware that you will be posting the username and password back to the client. Better filter out the fields that you need and return a new model
You can Use:
return NotFound({JsonObject})
Or
return BadRequest({JsonObject})
Or
return Ok({JsonObject})
Or
return Content("String")