Vaadin flow 23 losing parent layout on page refresh - vaadin-flow

We have a Vaadin 23.1.3 application that uses a parent layout for all pages.
The path/urls are dynamically registered and so far this works just fine.
But when a user hits F5, then only the child/main layout is displayed, losing everything from the parent layout.
The same also happens, when a user manually modifies the url to point to another part of the system
When I look at the registered routes, then all routes also have the parentLayout specified
Here the example for the /translations and /translations// routes
Here is my code for creating the routes
protected Button createNavButton(String route, String text, Class<? extends Component> listNavigationTarget, Class<? extends Component> detailNavigationTarget) {
RouteConfiguration configuration = RouteConfiguration.forSessionScope();
if (configuration.getRoute(route).isEmpty()) {
try {
configuration.setRoute(route, listNavigationTarget, getMainLayoutClass());
} catch (Exception ex) {
LOG.error("Error in configuring routes for {} {}", route, text, ex);
}
if (detailNavigationTarget != null) {
try {
configuration.setRoute(route+"/:primaryKey/:displayTab", detailNavigationTarget, getMainLayoutClass());
} catch (Exception ex) {
LOG.error("Error in configuring routes for {} {}", route, text, ex);
}
}
}
Button retVal = new Button(text);
retVal.setWidthFull();
retVal.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
retVal.addClickListener((event) -> {
UI.getCurrent().navigate(route);
});
return retVal;
}
The getMainLayoutClass() method returns the main layout (Based on the AppLayout)
Any idea why this happens?

Related

Is there any way where I can set user information into Session values from cookies while rendering a controller in MVC?

I have tried in Global.asax.cs
protected void Application_BeginRequest(object sender, EventArgs e)
{
try
{
var cookiesDataUserinfo = HttpContext.Current.Request.Cookies["UserInfo"];
if (cookiesDataUserinfo != null)
{
Session["UserId"] = cookiesDataUserinfo["UserId"].ToString();
}
}
catch (Exception ex)
{
string msg = ex.Message;
}
}
But I am getting the error "Session state is not available in this context."
I also tried to load data from cookies in constructor of a controller. But cookies is null inside constructor.
Is there any way where I can set session values from cookies before any view is rendered in my MVC project?
I have found the solution I was looking for. I need to use the Application_AcquireRequestState method in Global.asax.cs
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
try
{
var cookiesDataUserinfo = HttpContext.Current.Request.Cookies["UserInfo"];
if (cookiesDataUserinfo != null)
{
Session["UserId"] = cookiesDataUserinfo["UserId"].ToString();
}
}
catch (Exception ex)
{
string msg = ex.Message;
}
}
For every request the Application_AcquireRequestState method is called and I can set session values from Cookies if available.

How to make same routing name with same parameter with different versions in asp.net core 2.2 web api

I want to call service with the same routing name(same parameter ) with different versions ...
bellow is the my code
[Route("api/v{version:apiVersion}/[controller]/")]
[ApiController]
[ApiVersion("1.0")]
[ApiVersion("1.1")]
public class AccountController : ControllerBase
{
[MapToApiVersion("1")]
[HttpGet("getacounttypes")]
[ProducesResponseType(typeof(Models.ReturnString), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(Models.ErrorMessage), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(Models.ErrorMessage), StatusCodes.Status500InternalServerError)]
public async Task<ActionResult> GetAddressTypes()
{
logger.LogInformation("Request is processing at account types");
try
{
return Ok(await accountBS.GetAccountTypes());
}
catch (ArgumentException ex)
{
logger.LogError(ex, ex.Message);
this.Response.StatusCode = StatusCodes.Status400BadRequest;
return new JsonResult(new Models.ErrorMessage() { Code = StatusCodes.Status400BadRequest.ToString(), Message = ex.Message });
}
catch (Exception e)
{
logger.LogError(e, e.Message);
this.Response.StatusCode = StatusCodes.Status500InternalServerError;
return new JsonResult(new Models.ErrorMessage() { Code = StatusCodes.Status500InternalServerError.ToString(), Message = e.Message });
}
}
[MapToApiVersion("1.1")]
[HttpGet("getacounttypes")]
[ProducesResponseType(typeof(Models.ReturnString), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(Models.ErrorMessage), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(Models.ErrorMessage), StatusCodes.Status500InternalServerError)]
public async Task<ActionResult> GetAddressTypesV1_1()
{
logger.LogInformation("Request is processing at account types");
try
{
return Ok(await accountBS.GetAccountTypes());
}
catch (ArgumentException ex)
{
logger.LogError(ex, ex.Message);
this.Response.StatusCode = StatusCodes.Status400BadRequest;
return new JsonResult(new Models.ErrorMessage() { Code = StatusCodes.Status400BadRequest.ToString(), Message = ex.Message });
}
catch (Exception e)
{
logger.LogError(e, e.Message);
this.Response.StatusCode = StatusCodes.Status500InternalServerError;
return new JsonResult(new Models.ErrorMessage() { Code = StatusCodes.Status500InternalServerError.ToString(), Message = e.Message });
}
}
}
in this im having error like
An unhandled exception has occurred while executing the request.
System.NotSupportedException: HTTP method "GET" & path "api/v{version}/Account/[actions]/getacounttypes" overloaded by actions - API.Controllers.AccountController.GetAddressTypes (GSOnline.API),
API.Controllers.AccountController.GetAddressTypesV1_1 . Actions require unique method/path combination for Swagger 2.0. Use ConflictingActionsResolver as a workaround
at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.CreatePathItem(IEnumerable`1 apiDescriptions, ISchemaRegistry schemaRegistry)
at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.CreatePathItems(IEnumerable`1 apiDescriptions, ISchemaRegistry schemaRegistry)
at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GetSwagger(String documentName, String host, String basePath, String[] schemes)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
so could u please suggest me the solution for the same routing with same parameters with diff versions ??
i can manage method with diff parameters but im looking same routing with same parametrs ...
expecting result is
GET
/api/v1/Account/getacounttypes
GET
/api/v1.1/Account/getacounttypes
Your question is not entirely clear, but it appears you are referring to generating a single OpenAPI/Swagger document with Swashbuckle. Normally, Swashbuckle will create a single document per API version. Using the URL segment method, it is possible to create a single document with all of the URLs. The document only allows distinct URLs, which are derived from route templates. The route parameter is filled in at request time, but the document generator doesn't know or otherwise understand that.
To achieve this behavior, you need to have the API Explorer fill in the API version when it generates descriptions. Your configuration should look like this:
services.AddVersionedApiExplorer(options => options.SubstituteApiVersionInUrl = true);
With this option configured, the API version will be substituted automatically on your behalf and achieve your expected results.

NLog use in MVC application

How can I use NLog to get detail information regarding a local error?
Until now I have this:
private static Logger logger = LogManager.GetCurrentClassLogger();
public ActionResult Index()
{
try
{
var domain = db.Works.ToList();
var model = Mapper.Map<IList<Work>, IList<WorkIndexViewModels>>(domain);
return View(model);
}
catch (Exception e)
{
logger.Error("Error in Index: " + e);
}
}
If I put the return after the catch, the model is out of scope.
If I put the return inside the try, I get "not all code path returns a value" from the Action.
So how can I solve this?
Since you've already captured the error and you can't show the requested page, you could redirect within the catch to your error page:
catch (Exception e)
{
logger.Error("Error in Index: " + e);
return RedirectToAction("Index", "Error"); // Redirect to error controller or page
}
Alternatively, and probably more appropriate, you could have your action raise a 500 error so that your error configuration within your web.config can properly handle redirection.
catch (Exception e)
{
logger.Error("Error in Index: " + e);
return new HttpStatusCodeResult(500); // Raise internal server error
}

JSF View- returning null on actions do not update the view

i have read the post that have same problem as mine
JSF ViewScope - returning null on actions do not update the view
but it haven't worked for me cause i already use the h:commandLink in another page and its works perfectly but in this page it doesn't .
this is the request Bean
public class AddSectionBean {
public String delete(String id) {
try {
HttpSession session = SessionUtil.getSession();
UserVO userVOCreater = (UserVO) session.getAttribute("userVO");
SectionsDao.getInstance().deleteSectionById(
Integer.parseInt(id));
LoggerVO loggerVO =new LoggerVO();
loggerVO.setUserid(userVOCreater.getId());
loggerVO.setLog("deleted Section Id:"+id);
LoggerDao.getInstance().insertLogger(loggerVO);
} catch (Exception e) {
e.printStackTrace();
BundleMessages.getInstance().setMessage("error",
FacesMessage.SEVERITY_ERROR);
logger.error(e.getMessage(), e);
}
return null;
}
}
and the link is inside a richtable for every column
<rich:column>
<h:commandLink id="actualDelete" styleClass="delete_#{sectionsBean.datatableSections.rowIndex}" action ="#{addSectionBean.delete(s.id)}" />
</rich:column>
Note That: i tried to return the outcome instead of null but when i do that i lose the style and scripts in page
, note that the scripts have no effect cause i have tested it with them and had the same result
the problem solved by moving the delete method to the bean that view the table and calling the database method again inside the delete function to reload the table even its reloads in the postConstruct function
public class SectionsBean{
List<SectionVO> sectionsList = new ArrayList<SectionVO>();
#PostConstruct
public void postConstruct() {
try {
this.sectionsList = SectionsDao.getInstance().getSections();
} catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage(), e);
}
}
public String delete(String id) {
try {
HttpSession session = SessionUtil.getSession();
UserVO userVOCreater = (UserVO) session.getAttribute("userVO");
SectionsDao.getInstance().deleteSectionById(
Integer.parseInt(id));
LoggerVO loggerVO =new LoggerVO();
loggerVO.setUserid(userVOCreater.getId());
loggerVO.setLog("deleted Section Id:"+id);
LoggerDao.getInstance().insertLogger(loggerVO);
//reload the database table
this.sectionsList = SectionsDao.getInstance().getSections();
} catch (Exception e) {
e.printStackTrace();
BundleMessages.getInstance().setMessage("error",
FacesMessage.SEVERITY_ERROR);
logger.error(e.getMessage(), e);
}
BundleMessages.getInstance().setMessage("success",
FacesMessage.SEVERITY_INFO);
System.out.println("calling delete id="+id);
return null;
}
}

Transaction exception problem - s#arp architecture

I am deleting things like this:
[Transaction]
[AcceptVerbs(HttpVerbs.Post)]
public RedirectToRouteResult DeleteQualitativeGlobalFeatureValue(string Id)
{
try
{
BlaService.DeleteBla(Id);
}
catch (Exception e)
{
ModelState.AddModelError("Exception", e.Message);
}
return RedirectToAction("Bladibla", new { Id = FeatureId });
}
However, if something is ’illegally’ deleted (e.g. causing the violation of a referential constraint) I get a horrible exception which is not caught by my try catch block. I presume this has to do with the [Transaction] attribute. How can I avoid this to catch ANY exceptions in the controller method?
Thanks.
Best wishes,
Christian
This is because actual commit and database-side validation happens on transaction commit.
You can use your own, slightly modifed version of the Sharp attribute.
public class TransactionAttribute: ActionFilterAttribute
{
private TransactionAttributeHelper helper = new TransactionAttributeHelper();
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
helper.BeginTransaction();
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
try
{
// notice that I rollback both on exception and model error, this helps a lot
helper.FinishTransaction(filterContext.Exception == null &&
filterContext.Controller.ViewData.ModelState.IsValid);
}
catch (Exception ex)
{
// here add ModelError, return error, or redirect
}
}
}
TransactionAttributeHelper is placed to .Data assembly to avoid NHibernate reference in .Controllers.
public class TransactionAttributeHelper
{
public void BeginTransaction()
{
NHibernateSession.CurrentFor(GetEffectiveFactoryKey()).BeginTransaction();
}
public void FinishTransaction(bool commit)
{
string effectiveFactoryKey = GetEffectiveFactoryKey();
ITransaction currentTransaction =
NHibernateSession.CurrentFor(effectiveFactoryKey).Transaction;
if (currentTransaction.IsActive)
{
if (commit)
{
currentTransaction.Commit();
}
else
{
currentTransaction.Rollback();
}
}
}
private static string GetEffectiveFactoryKey()
{
return NHibernateSession.DefaultFactoryKey;
}
}
Alternatively, of course, you can do transations without the attribute using repository.DbContext.BeginTransaction/Commit/etc methods and catch/process errors manually. But the above approach saves from a lot of such manual work.
You should look into an attribute that implements the IExceptionFilter interface. For example the System.Web.Mvc.HandleErrorAttribute can display an alternate view for an exception and gives that view access to the exception. You can also create your own attributes that implement IExceptionFilter if you want to handle things differently or log the exception using log4net or Elmah.
Having an IExceptionFilter attribute on the method will catch the exception even if the exception occurs in the TransactionAttribute's code.

Resources