I ve been struggling with stateless http request for days on my razpr .NET6 webapp
My razor page has a button that opens a modal, this triggers a method (with ajax)
public OracleConnection connection { get; set; }
public OracleTransaction transaction { get; set; }
public JsonResult OnPostGetOrder(string order)
{
connection = ConnectionManager.GetConnection();//
transaction = connection.BeginTransaction();
....}
The connection should remain opened until the modal is closed or the form inside it is cancelled.
So I need to get connection and transaction values in the following method
public async Task<IActionResult> OnPostCloseModal()
{
connection.close()
transaction.Rollback();
...
}
Of course it won't work because of http being stateless, so connection being null
Here are all my attempt and none of it worked:
[tempdata] public oracleconnection connection
doesn't work because razor cannot store oracleconn inside tempdata
[bindproperty] public oracleconnection connection with #Html.HiddenFor(model=>model.connection) or don't work: the OnpostClose doesn't just trigger
_httpContextAccessor.HttpContext.Items["Connection"] = connection; I have no idea what should I use to retrieve its value because VS2022 refuse the following: HttpContext.Session.Get("Connection"); HttpContext.Session["connection"]; HttpContext.session.Get("Connection") ; HttpContext.Session.TryGetValue("connection",OracleConnection);
store connection and transaction in javascript then sending it back to server but Ajax s not able to pass oracleconnection to C# parameter (closeModal function doesn't trigger)
Please tell me there is something I can use to do this trivial task
Related
I am trying to implement Refresh key repository (JWT). At the moment it looks like this:
public class AuthenticateController : ControllerBase
{
ConcurrentDictionary<string, string> refreshTokens = new ConcurrentDictionary<string, string>();
....
....
....
public async Task<IActionResult> Login()
{
...
GenerateRefreshToken()
...
}
public string GenerateRefreshToken(ApplicationUser user)
{
var randomNumber = new byte[32];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(randomNumber);
var token = Convert.ToBase64String(randomNumber);
refreshTokens.AddOrUpdate(user.Id, token, (key, oldValue) => token);
return token;
}
}
public async Task<IActionResult> RefreshToken([FromBody] RefreshModel model)
{
....
refreshTokens.TryGetValue(user.Id, out string savedRefreshToken);
if (savedRefreshToken != model.RefreshToken)
throw new SecurityTokenException("Invalid refresh token");
...
}
(I removed the code that I thought was unnecessary to explain)
The user tries to log in, the information about the first update key is entered into the collection. I put a breakpoint, you can see that the information is entered:
After the JWT key has expired, the frontend sends a request to update the key. But the collection is empty. Why is this happening? I am definitely not clearing the collection before.
I think the problem may be that the web api processes each new request in isolation from each other.
How do I solve this?
Controllers are transient meaning they are newly instantiated every time a request comes in. So your dictionary is wiped out between requests.
To fix this, you'd made your dictionary static, like so:
private static readonly ConcurrentDictionary<string, string> refreshTokens =
new ConcurrentDictionary<string, string>();
Now it will live the lifetime of the application.
I'm using an architetture that has: AJAX, Liferay 6.2, Spring 4.3.18.RELEASE;
From AJAX i make a call to the backend, that pass throu liferay and reach my controller;
Now, I want to generete an exception in the controller in order to reach the the failure of the ajax call; I've googled a lot but I wasn't able to find the solution.
my controller:
#Controller("movemementCon")
#RequestMapping("VIEW")
public class movemementCon {
#ResourceMapping("getDis")
#ResponseBody
public ResponseEntity<BenException> getImp(ResourceRequest request, ResourceResponse response, Model model) throws BenException{
return new ResponseEntity<BenException>(HttpStatus.NOT_ACCEPTABLE);
}
But when i reach the code in javascript (the AJAX call) it ignored definitively that I've throw an exception;
The desidered behaviur is that i force to go to the error statment in the AJAX call.
In web browser you can't catch java errors on client side, because client doesn't know anything about backend. You have to catch that error in spring controller method and then return ResponseEntity with some status, response body, custom response headers, so you can notify client that something went wrong and handle it correctly there.
#Controller("movemementCon")
#RequestMapping("VIEW")
public class movemementCon {
#ResourceMapping("getDis")
#ResponseBody
public ResponseEntity<SomeClass> getImp(ResourceRequest request, ResourceResponse response, Model model) {
try{
deleteFromDatabase(model);
} catch(BenException e) {
return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE);
}
return new ResponseEntity<>(HttpStatus.OK);
}
}
Then in your JS read the status and execute right action.
In my MVC project most of the calls to server are done using Ajax. It works smoothly until the session expires. I have added custom attribute to redirect the page to login page once the session gets expired. But when the call is from AJAX then it is not redirecting to login page.
I have gone through many threads regarding this which has basically suggested to use OnActionExecuted method of ActionFilterAttribute class, but while doing so i am only getting the type HttpActionExecutedContext instead of type ActionExecutingContext.
Here's my code:
public class SessionExpired : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
//My Code to handle the session event
base.OnActionExecuted(actionExecutedContext);
}
}
Thanks in advance.
Ajax functions are used to get data or to post data primarily. If you are trying to redirect to any page using ajax request mechanism then you are going in wrong direction.
Create a custom Action Filter that handles session expiration and if session is null, redirect to Login Action.
namespace Mayur.Web.Attributes
{
public class SessionTimeoutAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpContext ctx = HttpContext.Current;
if (HttpContext.Current.Session["ID"] == null)
{
filterContext.Result = new RedirectResult("~/Home/Login");
return;
}
base.OnActionExecuting(filterContext);
}
}
}
I' writing some websockets apllication on spring boot. From front-end there are send request to my controller, and there message is send message to another user, below I show controllers method:
private MessagingService messagingService;
private DaoMessageService daoMessageService;
public MessageController(MessagingService messagingService, DaoMessageService daoMessageService){
this.messagingService = messagingService;
this.daoMessageService = daoMessageService;
}
#MessageMapping("/hello")
public void sendMessage(MessageDto messageDto, Principal principal) throws InterruptedException {
String recipient = messageDto.getRecipient();
String user = principal.getName();
Message message = new Message(messageDto.getContent());
message.setSenderName(user);
message.setRecipient(recipient);
daoMessageService.saveMessageForUser(user, message);
messagingService.convertAndSendToUser(recipient, message);
}
My question is : If many users will be write messages, there will create some like queue for these message wait for handle by this controller ? Or maybe there are create one controller for request or session scope ? if not, how I can use it asynchronously ? I can't read it anywhere.
I have built a simple login system for my JSF/Primefaces site using a sessionMap. In my main view, ParliamentManager which is a SessionScoped bean I have:
#PostConstruct
public void postInit() {
logger.log(Level.INFO,"Session started");
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
Map<String, Object> sessionMap = externalContext.getSessionMap();
user = (User) sessionMap.get("user");
logger.log(Level.INFO, "user trader is: {0}",
new Object[]{user.getTrader().getTraderId().toString()});
userId = user.getUserId();
In my login view which is a RequestScoped ManagedBean I have:
public void login(ActionEvent event) {
RequestContext requestContext = RequestContext.getCurrentInstance();
FacesContext context = FacesContext.getCurrentInstance();
boolean loggedIn = false;
User user = request.findUser(username);
if(user.getPassword().equals(this.getPassword()))
{
loggedIn = true;
context.getExternalContext().invalidateSession();
context.getExternalContext().getSession(true);
context.getExternalContext().getSessionMap().put("user", user);
logger.log(Level.INFO, "put user {0}",
new Object[]{user.getUserId()});
logger.log(Level.INFO, "session id {0}",
new Object[]{context.getExternalContext().getSessionId(false)});
requestContext.addCallbackParam("loggedIn", loggedIn);
}
}
In my login page I simply redirect to the main index page:
<script type="text/javascript">
function handleLoginRequest(xhr, status, args) {
if(args.validationFailed || !args.loggedIn) {
PF('dlg').jq.effect("shake", {times:5}, 100);
}
else {
PF('dlg').hide();
$('#loginLink').fadeOut();
window.location = "http://localhost:8080/mysite/index.xhtml"
}
}
This works ok if I have two users logged in (one in a browser session, another in an incognito session). However if I add a third user (another invognito session) I get a ViewExpiredException when submitting my ajax request within a form. I thought that I could have a large amount of sessions as I'd expect many users so I'm not clear on why I get the exception in these cirumstances. Am I associating the user and session incorrectly or could there be some other issue causing the exception?
Thanks,
Zobbo
In Chrome all incognito sessions share the same cookie jar. It's only destroyed once all incognito sessions are closed. This means that a second incognito session shares the cookies with the other incognito sessions. See [1].
You can either use a session in another browser or use a browser like Firefox with multiple private sessions as Firefox doesn't share cookies like that.
[1] https://bugs.chromium.org/p/chromium/issues/detail?id=24690