There are some unhandled FacesMessages, this means not every FacesMessage had a chance to be rendered - jsf-1.2

I am little frustrated on this problem - I have an small application recently migrated to Webspehere 8.5.5 and trying to save an order, expected to render a message that is not displaying. Below is snippet of code we are using for rendering the message.
Error Message- are some unhandled FacesMessages, this means not every FacesMessage had a chance to be rendered.
if (headerKey != null && !headerKey.equals("0")) {
addErrorMessage("A new order has been submitted.");
}
protected void addErrorMessage(String message) {
addErrorMessage(null, message);
}
protected void addErrorMessage(String componentId, String message) {
this.getFacesContext().addMessage(
componentId, new FacesMessage(FacesMessage.SEVERITY_ERROR,
message, message));
}

just run over this by google:
In my case the problem was that I forgot to update the h:message/p:growl etc component in the view.
After adding an update=":form:growlMessages" to my action, it worked.

Related

Why ActivityIndicator changes state after entire method is completed?

I would like to show ActivityIndicator object after user tap the login button on page. Unfortunately there is small problem to do that because it seems like ActivityIndicator change state after entire method is completed. This is code I wrote so far:
private void Login(object sender, EventArgs ev)
{
BusyIndicator.IsVisible = true; //<- here I want to show indicator
try
{
//some input validation, connection opening etc
ConnectionHandler.OpenConnection(ServerIP, "dmg", false);
}
catch (Exception e)
{
Logging.Error(e.Message, "Connection", e);
}
}
When I set breakpoint after BusyIndicator.IsVisible = true; there is absolutely no change in app. However I noticed that when method is completed then indicator is shown. Is this a correct behavior of this control?
Why I need this? Because field validation and connecting with server takes some time and I need to show to user that something happens in background. Login function takes ~1 sec so indicator show and hide quickly I can't even see any change.
How can I show indicator immediately after user tap a button?
Your problem is that Login() method is being executed in the UI thread. So, despite setting BusyIndicator.IsVisible = true;, the thread continues tio execute the method to get data, so the UI does not respond.
Solution, run the OpenConnection in a different thread:
private async void Login(object sender, EventArgs ev)
{
BusyIndicator.IsVisible = true; //<- here I want to show indicator
try
{
//some input validation, connection opening etc
await Task.Run(() => { ConnectionHandler.OpenConnection(ServerIP, "dmg", false);});
}
catch (Exception e)
{
Logging.Error(e.Message, "Connection", e);
}
}

Override Elmah logged error message

Is there any way of overriding the error message logged by Elmah without duplicating it?
I have a custom exception class:
public class BusinessException : Exception
{
// detailed error message used for logging / debugging
public string InternalErrorMessage { get; set; }
public BusinessException(string message, string internalMessage)
:base(message)
{
InternalErrorMessage = internalMessage;
}
}
From the code, i throw an exception like this:
string detailedErrorMessage = string.Format("User {0} does not have permissions to access CreateProduct resource", User.Identity.Name);
throw new BusinessException("Permission denied", detailedErrorMessage);
When Elmah logs the error, it only logs Permission denied message. However, i need to log the InternalErrorMessage property of the exception instead.
I've tried to create a custom HandleErrorAttribute to do this, but this duplicates the exceptions logged:
public class ErrorHandleAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
if (filterContext.ExceptionHandled == true)
return;
Exception exception = filterContext.Exception;
BusinessException businessException = exception as BusinessException;
if (businessException != null)
{
ErrorSignal.FromCurrentContext().Raise(new Exception(businessException.InternalErrorMessage, exception));
}
}
}
I think your issue might be here:
if (businessException != null) {
ErrorSignal.FromCurrentContext().Raise(
new Exception(businessException.InternalErrorMessage, exception));
}
When you create a new exception rather than something like this:
if (businessException != null) {
ErrorSignal.FromCurrentContext().Raise(businessException));
}
I have this done the code for one of my sites and can see if I can recreate your issue later today (assuming this does not work). I think this is the SO post that helped me implement: How to get ELMAH to work with ASP.NET MVC [HandleError] attribute?
Edit:
Re-reading your question and the other answer I realize I was trying to solve your attempted correction and not the actual problem. Have you tried something like this solution which is only a slight deviation from your current attempt:
public override void OnException(ExceptionContext filterContext) {
if (filterContext.ExceptionHandled == true) {
return;
}
Exception exception = filterContext.Exception;
BusinessException businessException = exception as BusinessException;
if (businessException != null) {
var customEx = new Exception(
businessException.InternalErrorMessage, new BusinessException());
ErrorSignal.FromCurrentContext().Raise(customEx);
return;
}
}
Check that the InternalErrormessage is returning what you expect, and I expect that forcing a return here will prevent the exception from being logged twice. Otherwise it is essentially what you had done.
I suspect you'll need to create your own errorlog implementation to log anything other than the standard properties. This shouldn't be too difficult.
Using the SqlErrorLog as an example, you only need to override the log method & put in your own logic to modify what the Error class contains before calling the base implementation.
Using what #Matthew has also said will stop you logging the exception twice.
All the source code is here

Display exception message using JavaScript in Base Page's OnError event

I want to display all unhandled excpetions in the appplication using Javascript. For this I have defined onError event inside my custom base class of my pages. Here is the code for my Base Page:
namespace Loan
{
public class BasePage : System.Web.UI.Page
{
public BasePage()
{
}
protected override void OnError(EventArgs e)
{
//Report Error
Exception ex = Server.GetLastError();
if (ex is HttpUnhandledException && ex.InnerException != null)
{
ex = ex.InnerException;
}
var _message = "Error : "+ ex.Message.ToString();
DisplayAlert(_message);
Server.ClearError();
return;
}
protected virtual void DisplayAlert(string message)
{
ClientScript.RegisterStartupScript(
this.GetType(),
Guid.NewGuid().ToString(),
string.Format("alert('{0}');", message.Replace("'", #"\'")),
true
);
}
}
}
The alert is never displayed for an unhandled exception. However, if I call the DisplayAlert from any Page
base.DisplayAlert(ex.Message);
the javascript alert is displayed. How can I get the javascript alert to be displayed for the unhandled exceptions from the base page.Or is there any other way to display these exception messages to the user. I don't want to redirect them to a generic error page as it sends them back and forth.
This is expected. If the exception is unhandled, the OnError event on BasePage will execute and your child page won't continue to execute, there's nothing to render as the BasePage is pure code. If you want to spit out the alert you'd need to write directly to the Response but you should still see a blank page after an unhandled exception occurs.
protected virtual void DisplayAlert(string message)
{
Response.Write(string.Format("<script>alert('{0}');</script>", message.Replace("'", #"\'")));
}
Of course, when you call DisplayAlert directly, it works because you are just calling a method, the Page execution continues normally.
I frankly dislike your approach. You should log the exception and redirect to another page, the typical Oooooooooopsss, me screwed up kind of thing.

Force Method to Run During Event

Is there a way to force methods to be accessible only during certain events during the page life cycle. For example, I have a extension to System.Web.UI.Page that adds a PrependTitle method.
I also have a masterpage that embeds another masterpage. The first masterpage sets the base title (Google), the next masterpage prepends the title (Calendar), and a page also prepends the title (21 May 2011).
The result should be:
21 May 2011 :: Calendar :: Google
And this is the case when the PrependTitle is run during the Page_Init event. However, when the method is run during Page_Load the following the results:
Google
So, that brings me to the question: How can it be enforced that a method only be accessible during specified life cycle events?
// The Method Mentioned
public static class PageExtensions
{
public static void PrependTitle(this Page page, string newTitle)
{
page.Title = newTitle + " " + Global.TITLE_DELIMITER + " " + page.Title;
}
}
I think this can be done similar to the following. The general idea is declare the method as private, declare the ones that should have access to it as sealed
class AppsBasePage : Page
{
abstract void PrependTitle(string title);
}
class PageWithTitlePrepended : AppsBasePage
{
private void PrependTitle(string title)
{
Title = String.Format("{0} {1} {2}", newTitle, Global.TITLE_DELIMITER, Title);
}
protected sealed override void Page_Init(object sender, EventArgs e)
{
PrependTitle("This is a title")
}
}
class ActualPageInApp: PageWithTitlePrepended
{
override void Page_Load(object s, EventArgs e)
{
// can't access PrependTitle here
}
}
This solves your question in bold, but I'm not convinced this situation is what is causing your problem with PrependTitle specifically. I think more code / context would be needed to solve your actual problem
If you want to brute force ensure that the method is being called from Init, you can inspect the call stack. Something like this:
public static bool CalledFromInit()
{
//Grab the current Stack Trace and loop through each frame
foreach(var callFrame in new StackTrace().GetFrames())
{
//Get the method in which the frame is executing
var method = callFrame.GetMethod();
//Check if the method is Control.OnInit (or any other method you want to test for)
if(method.DeclaringType == typeof(Control) && method.Name == "OnInit")
//If so, return right away
return true;
}
//Otherwise, we didn't find the method in the callstack
return false;
}
Then you would use it like:
public static void PrependTitle(this Page page, string newTitle)
{
//If we aren't called from Init, do something
if (!CalledFromInit())
{
//We could either return to silently ignore the problem
return;
//Or we could throw an exception to let the developer know they
// did something wrong
throw new ApplicationException("Invalid call to PrependTitle");
}
//Do the normally processing
page.Title = newTitle + " " + Global.TITLE_DELIMITER + " " + page.Title;
}
However, I'd caution that the stack trace isn't the most reliable thing. In release, code could get optimized such that the Control.OnInit method is inlined so your code wouldn't be able to see it in the call stack. You could wrap this check in an #if DEBUG block so it only executes during development. Depending on your use case, it might be good enough to catch this problem while in DEBUG and not bother doing the check in RELEASE. But that's up to you.
Another option...building on Tommy Hinrichs answer, if all your pages inherit from a base class, you'll be able to do it a bit more reliably. I'd suggest something like this:
public abstract class BasePage : Page
{
private bool _executingInit;
protected internal override void OnPreInit(EventArgs e)
{
_executingInit = true;
base.OnPreInit(e);
}
protected internal override void OnInitComplete(EventArgs e)
{
base.OnInitComplete(e);
_executingInit = true;
}
public void PrependTitle(string newTitle)
{
if (!_executingInit)
throw new ApplicationException("Invalid call to PrependTitle.");
Title = newTitle + " " + Global.TITLE_DELIMITER + " " + Title;
}
}
That way, PrependTitle will throw an exception unless it's called between PreInit and InitComplete (which sounds like exactly what you want).
As one last option, you could be sneaky and use reflection to access the Control.ControlState property (which is a confusing name because it's not related to Control State - the thing similar to View State). That property tracks the Control as it goes throw its lifecycle - and it has the following values:
internal enum ControlState
{
Constructed,
FrameworkInitialized,
ChildrenInitialized,
Initialized,
ViewStateLoaded,
Loaded,
PreRendered
}
You'll notice that Enum is internal. So is the Control.ControlState property. But with Reflection, you could use that - and you could even use it from an extension method that is external to the Page.
Hope one of those ways will work for you!
Your best bet is probably to use the Handles Keyword to attach the method to the event.
You might have to create a subclass of System.Web.UI.Page to ensure this is enforced.
It seems that the issue is in the prependTitle method, it should append the text to the page title not replace it.
Just call the PrependTitle method in the page_load of each mashterpage and page and append the text to the title.

Is it possible to style the Windows Identity Foundation postback page?

Is it possible to style the Windows Identity Foundation postback page?
This is the page that comes across as blank after you successfully login and the url is similar to https://sts.address.com/?wa=wsignin1.0&wtrealm=https....
I read the following article, http://www.paraesthesia.com/archive/2011/01/31.aspx, which led me to using dotPeek on the Microsoft.IdentityModel assembly. Which shows me that all the ProcessSignInResponse message does, is the following:
public static void ProcessSignInResponse(SignInResponseMessage signInResponseMessage, HttpResponse httpResponse)
{
if (signInResponseMessage == null)
throw DiagnosticUtil.ExceptionUtil.ThrowHelperArgumentNull("signInResponseMessage");
else if (httpResponse == null)
{
throw DiagnosticUtil.ExceptionUtil.ThrowHelperArgumentNull("httpResponse");
}
else
{
signInResponseMessage.Write(httpResponse.Output);
httpResponse.Flush();
httpResponse.End();
}
}
The signInResponseMessage.Write method does the following:
public override void Write(TextWriter writer)
{
if (writer == null)
{
throw DiagnosticUtil.ExceptionUtil.ThrowHelperArgumentNull("writer");
}
else
{
this.Validate();
writer.Write(this.WriteFormPost());
}
}
As you can see, in essence, all that is performed, is to write the content of WriteFormPost to the response stream.
So I am, as we speak, changing my "ProcessSignIn" method to return the HTML to be output, instead of calling FederatedPassiveSecurityTokenServiceOperations.ProcessSignInResponse.
So, I have changed my method essentially from this:
public static void ProcessSignIn(SignInRequestMessage signInRequest, HttpResponse httpResponse)
{
FederatedPassiveSecurityTokenServiceOperations.ProcessSignInResponse(signInResponseMessage, httpResponse);
}
To:
public static string ProcessSignIn(SignInRequestMessage signInRequest)
{
return signInResponseMessage.WriteFormPost();
}
Of course, the SignInResponseMessage should have provided a cleaner method of returning just the "main" content of what you want to write to your form post, but getting the
HTML form as a string at least makes it easier to modify the result before returning it to the client with Response.Write(result).
I don't know if this is a documented feature, but I will suggest the following as a jumping-off point:
If your code looks anything at all like mine, you have a line of code that looks like:
FederatedPassiveSecurityTokenServiceOperations.ProcessSignInResponse(responseMessage, HttpContext.Current.Response)
The second parameter to ProcesssignInResponse is an HttpResponse object. I tried, unsuccessfully, to find an answer to your question, by trying to pass in a custom HttpResponse message in order to capture the output so we can manipulate it however you like:
Dim myStringbuilder As New StringBuilder
Dim myStringWriter As New IO.StringWriter(myStringbuilder)
Dim myResponse As New Web.HttpResponse(myStringWriter)
If you pass in myResponse to ProcessSignInResponse, the following exception is thrown:
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Web.HttpResponse.End()
at Microsoft.IdentityModel.Web.FederatedPassiveSecurityTokenServiceOperations.ProcessSignInResponse(SignInResponseMessage signInResponseMessage, HttpResponse httpResponse)
at Logon_App.LCLoginBase.issueTokenAndRedirect(logonParamsStruct& logonParams) in C:\Logon App\Logon App\Code\LCLogin\LCLoginBase.vb:line xxx

Resources