How to automatically call a method when Session["something"] throws a NullReferenceException? - asp.net

I am going to be using Session["firmaid"] quite alot in my application. This value is set when someone logs in to my system.
If something happens, and this value is lost from the Session, i would like to somehow have a global method that will get it, if it throws a NullReferenceException.
How can i do this?
Currently, my solution is to try and catch every time i use Session["firmaid"], then execute the method that will put firmaid in the Session, if it throws an Exception.
Is there an easier way to do this?

Instead of try/catching everytime you could wrap the access to the session in a strongly typed class and then access the session through this wrapper.
Or even write an extension method:
public static class SessionExtensions
{
public static string GetFirmaId(this HttpSessionStateBase session)
{
var firmaid = session["firmaid"] as string;
if (string.IsNullOrEmpty(firmaid))
{
// TODO: call some method, take respective actions
}
return firmaid;
}
}
and then in your code instead of:
try
{
var firmaid = Session["firmaid"];
// TODO: do something with the result
}
catch (Exception ex)
{
// TODO: call some method, take respective actions
}
use:
var firmaid = Session.GetFirmaId();
// TODO: do something with the result

Why not simply write a static wrapper around this? Much more robust and more DRY:
public static int GetFirmaid() {
if (HttpContext.Current.Session["firmaid"] == null) {
//do something to fall back
}
return HttpContext.Current.Session["firmaid"]
}
You obviously would have to put this in a Class you can easily access and then call it through:
Class.GetFirmaid()

You can create an action filter which will ensure that Session["firmaid"] has a value:
public class SetFirmaIdAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
try
{
var firmaId = Session["firmaid"];
}
catch (Exception ex)
{
// pass filterContext if you need access to Request, Session etc.
Session["firmaid"] = SetFirmaId(filterContext);
}
}
private int SetFirmaId(ActionExecutingContext filterContext)
{
// TODO: implement some logic
}
}
OnActionExecuting will be called before action executes so you will already have Session["firmaid"] set when the action gets executed.
Once you implement this attribute you can put it on an action, controller or set it as global.

Related

Redirecting to an error page in a non mapped method

I was looking for a way to redirect to an error page in a method that has no mapping / direct request, but is called from a method with one.
Example:
// Calling method
#GetMapping("/")
public String listUploadedFiles() {
doSomething(); // redirect if error must happen in side this method!
return "uploadForm";
}
// Method where redirection should happen
public void doSomething()
{
try {
// try some code here
} catch(Exception e) {
// call a method which redirects to an error page
}
}
The method above is called from a method which has a mapping, I want to redirect to an error directly in the method where the exception occurs. Is this possible with spring boot?
You can use #ExceptionHandler like in
#GetMapping("/")
public String listUploadedFiles() {
doSomething(); // redirect if error must happen in side this method!
return "uploadForm";
}
public void doSomething() {
try {
// try some code here
} catch(Exception e) {
throw new YourException();
}
}
#ExceptionHandler(YourException.class)
public String handleYourException(YourException e) {
return "errorPage";
}

Working with static method Asp.Net

Good night guys!
I'm having the following problem ...
I have a web application that runs a "thread" that takes messages from the queue (MSMQ) ... Everything works correctly .. the problem is when I get this message, I can not display .. because the method that returns the message content is a "static" ..
I need to perform a function in JS to display this message.
conclusion:
The method "ProcessMessage" can not be named because he is not a static method ...
My main goal is to call a function in JS passing as parameter (m.Body.ToString ()) which is the content of the message.
Can anyone help me?
Thank you for sharing your knowledge!
This is my code.
public void StartThread()
{
try
{
while (true)
{
PrepareQueue();
}
}
catch (Exception)
{ }
}
public static void PrepareQueue()
{
MessageQueue myQueue = new MessageQueue(".\\private$\\CTIQueue");
myQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(String) });
// Add an event handler for the ReceiveCompleted event.
myQueue.ReceiveCompleted += new ReceiveCompletedEventHandler(MyReceiveCompleted);
// Define wait handles for multiple operations.
WaitHandle[] waitHandleArray = new WaitHandle[10];
for (int i = 0; i < 10; i++)
{
// Begin asynchronous operations.
waitHandleArray[i] = myQueue.BeginReceive().AsyncWaitHandle;
}
// Specify to wait for all operations to return.
WaitHandle.WaitAll(waitHandleArray);
return;
}
private static void MyReceiveCompleted(Object source, ReceiveCompletedEventArgs asyncResult)
{
try
{
Thread.Sleep(2000);
MessageQueue mq = (MessageQueue)source;
// End the asynchronous receive operation.
System.Messaging.Message m = mq.EndReceive(asyncResult.AsyncResult);
ProcessMessage(m.Body.ToString()); <-- MY PROBLEM
}
catch (MessageQueueException)
{ }
return;
}
public void ProcessMessage(string message)
{
ScriptManager.RegisterStartupScript(this, GetType(), "popup", "NewCaller('" + message + "');", true);
}
Why not instantiate an object of the class and call ProcessMessage on it? Static methods can instantiate an object of the enclosing class and invoke instance methods on it.
private static void MyReceiveCompleted(Object source, ReceiveCompletedEventArgs asyncResult)
{
try
{
Thread.Sleep(2000);
MessageQueue mq = (MessageQueue)source;
// End the asynchronous receive operation.
System.Messaging.Message m = mq.EndReceive(asyncResult.AsyncResult);
new MyClass().ProcessMessage(m.Body.ToString()); <-- MY PROBLEM
}
catch (MessageQueueException)
{ }
return;
}
But if you are planning to invoke a client side code from server side, with reactive action happening at the server's end(which I think is your case) -- then I would prefer you use ASP.NET SignalR to signal the client that something interesting has happened at the server's end.

WF 4 OnUnhandledException not hit

I've created a custom activity which contains as a Body another Activity.
[Browsable(false)]
public Activity Body { get; set; }
protected override void Execute(NativeActivityContext context)
{
ActivityInstance res = context.ScheduleActivity(Body, new CompletionCallback(OnExecuteComplete), OnFaulted);
}
private void OnFaulted(NativeActivityFaultContext faultContext, Exception propagatedException, ActivityInstance propagatedFrom)
{
throw new Exception(propagatedException.Message);
}
When an exception is thrown during the execution of the Body, ma handler for the OnFaulted is hit.
My execution starts with a call to static method Run of the WorkflowApplication class. My WorkflowApplication instance has a handler associated for the OnUnhandledException event.
instance.OnUnhandledException +=
delegate(WorkflowApplicationUnhandledExceptionEventArgs args)
{
Console.WriteLine(args.ExceptionSource);
waitEvent.Set();
return UnhandledExceptionAction.Cancel;
};
But regardless of what happens when the Activity hosted in the Body is executed, i never reach the handler defined above. I thought that if i throw an exception from the OnFaulted, i will be able to redirect the flow to the OnUnhandledException but i was wrong. Any ideas ?
I need this in order to centralize my errors, check them and display messages accordingly. Also i need a way to stop the execution and so on and i don't want to define handlers all over the application. Is there any way to accomplish this ?
As Will suggested, i will post what i did to handle my scenario.
Basically, in my custom activity i have hosted an Assign :
[Browsable(false)]
public Activity Body { get; set; }
Activity System.Activities.Presentation.IActivityTemplateFactory.Create(System.Windows.DependencyObject target)
{
return new Assignment()
{
Body = new Assign() { DisplayName = "" }
};
}
I've added this code to my Execute method :
ActivityInstance res = context.ScheduleActivity(Body, new CompletionCallback(OnExecuteComplete), OnFaulted);
I was trying to run this Assignment by giving an array a negative value as index and and an exception was thrown. This, somehow ended my execution but no handler for the events of my WorkflowApplication instance were hit.
Here is the method given as a callback when executing the body ( in our case the Assign activity ) :
private void OnFaulted(NativeActivityFaultContext faultContext, Exception propagatedException, ActivityInstance propagatedFrom)
{
faultContext.HandleFault();
CommunicationExtension ce = faultContext.GetExtension<CommunicationExtension>();
ITextExpression toTextExpression = (propagatedFrom.Activity as Assign).To.Expression as ITextExpression;
string valueTextExpression = string.Empty;
if ((propagatedFrom.Activity as Assign).Value != null)
{
if ((propagatedFrom.Activity as Assign).Value.Expression != null)
valueTextExpression = (propagatedFrom.Activity as Assign).Value.Expression.ToString();
}
if (ce != null)
{
ce.AddData(string.Format("{0} found on Assignment definition [{1} = {2}]", propagatedException.Message, toTextExpression.ExpressionText, valueTextExpression));
}
}
The trick was to call :
faultContext.HandleFault();
and use CommunicationExtension to allow me to to display the erros in the GUI.
The code for this class is trivial :
public class CommunicationExtension
{
public List<string> Messages { get; set; }
public CommunicationExtension()
{
Messages = new List<string>();
}
public void AddData(string message)
{
if (string.IsNullOrEmpty(message))
return;
Messages.Add(message);
}
}
Use this to add the extension:
CommunicationExtension ce = new CommunicationExtension();
instance.Extensions.Add(ce);
where instance is my WorkflowApplication instance.
I understood that for each instance of the workflow application we have one instance of its extension class. So i can send messages like this from all my custom activities in order to display their status.
I hope this scenario can help other people too.

Javafx pass login token from LoginController to CalendarController

I am using Angela's framework for screens management and I am trying to write a very simple Calendar-application. While writing the UI and the controllers and using the aforementioned framework, all screens initialize immediately on program start. This means I have no idea when the user is actually looking at a certain view.
I need the login-token from the server (assigned in the LoginController) to fire a changed value event of some kind in the CalendarController that is currently running in the background (I presume). At the moment I don't know when the Calendar.fxml is visible and/if the user is logged in, and hence I don't know how to structure my logic to make a function start in CalendarController ONLY after the login-token has been set.
Been stuck a few days here, any help would be greatly appreciated. I have tried using an ObservableList and Listlistener-interface to no avail. Here is the respective part of my LoginController. TokenFactory is a class of static fields and methods (mostly trying to debug).
#FXML
public boolean login() throws JSONException, UnirestException {
if(validateUsernameField() && validatePasswordField()) {
HttpResponse<JsonNode> jsonResponse = Unirest.post(TokenFactory.getSERVER_ADR())
.field("username", usernameField.getText())
.field("password", passwordField.getText())
.asJson();
if ( ((String) jsonResponse.getBody().getObject().get("message")).equalsIgnoreCase("OK")) {
String token = ((String) jsonResponse.getBody().getObject().get("token"));
//Ignore JSON to debug
TokenFactory.setToken("fakeToken123");
responseLabel.setText("Logging in...");
myController.setScreen(ScreensFramework.CalendarID);
return true;
} else {
responseLabel.setText("Wrong username or password.");
passwordField.clear();
}
} return false;
}
//Screen management
ScreensController myController;
You have a bunch of options here:
First option: instead of loading all the screens at startup, just load the calendar screen when the login is successful. Then your CalendarController's initialize() method can basically assume the user is logged in.
Second option: modify the framework so that it either returns a reference to the controllers when it loads them, or gives you access to the controllers once loaded. The first version of this would look like:
public <T extends ControlledScreen> T loadScreen(String name, String resource) {
try {
FXMLLoader myLoader = new FXMLLoader(getClass().getResource(resource));
Parent loadScreen = (Parent) myLoader.load();
T myScreenControler = myLoader.getController();
myScreenControler.setScreenParent(this);
addScreen(name, loadScreen);
return myScreenControler ;
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}
Now when you first load the calendar screen, you can get a reference to its controller:
CalendarController calendarController = screensController.loadScreen(...);
so now when you are successfully logged in, you can invoke a method on the calendarController. Note the return type of loadScreen(...) has changed, so you may need to modify other code accordingly.
Alternatively, you could introduce a new map in ScreensController:
public class ScreensController extends StackPane {
private Map<String, Node> screens = new HashMap<>();
private Map<String, ControlledScreen> controllers = new HashMap<>();
// ...
public boolean loadScreen(String name, String resource) {
try {
FXMLLoader myLoader = new FXMLLoader(getClass().getResource(resource));
Parent loadScreen = (Parent) myLoader.load();
ControlledScreen myScreenControler = ((ControlledScreen) myLoader.getController());
myScreenControler.setScreenParent(this);
addScreen(name, loadScreen);
// also save the controller:
controllers.put(name, myScreenControler);
return true;
} catch (Exception e) {
System.out.println(e.getMessage());
return false;
}
}
// ...
// new method to retrieve controller:
public ControlledScreen getController(String name) {
return controllers.get(name);
}
// modify the remove method to clean up the controller as well:
public boolean unloadScreen(String name) {
if (screens.remove(name) == null) {
System.out.println("Screen didn't exist");
return false;
} else {
controllers.remove(name);
return true;
}
}
}
Now when the user logs in, you can do
CalendarController calendarController =
(CalendarController) myController.getController(ScreensFramework.CalendarID);
and invoke whatever method you need on calendarController.
Third option: create a BooleanProperty loggedIn = new SimpleBooleanProperty(); and just set it to true when the user is logged in. Then arrange for your CalendarController to be able to observe it and react when it changes. I like this option less, because arranging for the CalendarController to see the loggedIn property will almost certainly involve some kind of additional coupling between that controller and another class, but it is possible.

Synchronous responses to `Gdx.net.sendHttpRequest` in LibGDX

I'm making a small game in LibGDX. I'm saving the player's username locally as well as on a server. The problem is that the application is not waiting for the result of the call so the online database's ID is not saved locally. Here's the overall flow of the code:
//Create a new user object
User user = new User(name);
//Store the user in the online database
NetworkService networkService = new NetworkService();
String id = networkService.saveUser(user);
//Set the newly generated dbase ID on the local object
user.setId(id);
//Store the user locally
game.getUserService().persist(user);
in this code, the id variable is not getting set because the saveUser function is returning immediately. How can I make the application wait for the result of the network request so I can work with results from the server communication?
This is the code for saveUser:
public String saveUser(User user) {
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("action", "save_user");
parameters.put("json", user.toJSON());
HttpRequest httpGet = new HttpRequest(HttpMethods.POST);
httpGet.setUrl("http://localhost:8080/provisioner");
httpGet.setContent(HttpParametersUtils.convertHttpParameters(parameters));
WerewolfsResponseListener responseListener = new WerewolfsResponseListener();
Gdx.net.sendHttpRequest (httpGet, responseListener);
return responseListener.getLastResponse();
}
This is the WerewolfsResponseListener class:
class WerewolfsResponseListener implements HttpResponseListener {
private String lastResponse = "";
public void handleHttpResponse(HttpResponse httpResponse) {
System.out.println(httpResponse.getResultAsString());
this.lastResponse = httpResponse.getResultAsString();
}
public void failed(Throwable t) {
System.out.println("Saving user failed: "+t.getMessage());
this.lastResponse = null;
}
public String getLastResponse() {
return lastResponse;
}
}
The asynchrony you are seeing is from Gdx.net.sendHttpRequest. The methods on the second parameter (your WerewolfsResponseListener) will be invoked whenever the request comes back. The success/failure methods will not be invoked "inline".
There are two basic approaches for dealing with callbacks structured like this: "polling" or "events".
With polling, your main game loop could "check" the responseListener to see if its succeeded or failed. (You would need to modify your current listener a bit to disambiguate the success case and the empty string.) Once you see a valid response, you can then do the user.setId() and such.
With "events" then you can just put the user.setId() call inside the responseListener callback, so it will be executed whenever the network responds. This is a bit more of a natural fit to the Libgdx net API. (It does mean your response listener will need a reference to the user object.)
It is not possible to "wait" inline for the network call to return. The Libgdx network API (correctly) assumes you do not want to block indefinitely in your render thread, so its not structured for that (the listener will be queued up as a Runnable, so the earliest it can run is on the next render call).
I would not recommend this to any human being, but if you need to test something in a quick and dirty fashion and absolutely must block, this will work. There's no timeout, so again, be prepared for absolute filth:
long wait = 10;
while(!listener.isDone())
{
Gdx.app.log("Net", "Waiting for response");
try
{
Thread.sleep(wait *= 2);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
public static class BlockingResponseListener implements HttpResponseListener
{
private String data;
private boolean done = false;
private boolean succeeded = false;
#Override
public void handleHttpResponse(HttpResponse httpResponse)
{
Gdx.app.log("Net", "response code was "+httpResponse.getStatus().getStatusCode());
data = httpResponse.getResultAsString();
succeeded = true;
done = true;
}
#Override
public void failed(Throwable t)
{
done = true;
succeeded = false;
Gdx.app.log("Net", "Failed due to exception ["+t.getMessage()+"]");
}
public boolean succeeded()
{
return succeeded;
}
public boolean isDone()
{
return done;
}
public String getData()
{
return data;
}
}

Resources