MiniProfiler can't display SqlTimings - mvc-mini-profiler

I am using MiniProfiler to Profile My MVC app and WCF services, this works like a charm with one caveat - when the profile information contains sql.
Symptoms:
The "query time (ms)" heading is missing from the popup
The "% in sql" is also missing from the bottom of the popup
If I click on the " sql" links it shows the grey overlay but no information and throws some jQuery error (it can't find the element).
After a little digging I discovered that this is all to do with HasSqlTimings in the json response there is an inconsistency between HasSqlTimings (false) at the root of the json response and the information that is in Root / Children hierarchy (true).
[OnDeserialized]
void OnDeserialized(StreamingContext ctx)
{
HasSqlTimings = GetTimingHierarchy().Any(t => t.HasSqlTimings);
HasDuplicateSqlTimings = GetTimingHierarchy().Any(t => t.HasDuplicateSqlTimings);
if (_root != null)
{
_root.RebuildParentTimings();
}
}
I took a look at the source and it looks like it should work just fine but no deal! Does anyone have any idea where I might be going wrong?

I had the same issue when implementing this. The issue occurs when the UI layer doesn't make any sql calls but then the WCF data comes back with sql calls. The root timing doesn't know there are sql timings below in the hierarchy.
I added one line so that when adding "remote" timings we set the "hasSqlTimings" field so that the UI knows how to render the box properly. Here is the code I modified in MvcMiniProfiler\MiniProfiler.cs:
/// <summary>
/// Adds <paramref name="externalProfiler"/>'s <see cref="Timing"/> hierarchy to this profiler's current Timing step,
/// allowing other threads, remote calls, etc. to be profiled and joined into this profiling session.
/// </summary>
public static void AddProfilerResults(this MiniProfiler profiler, MiniProfiler externalProfiler)
{
if (profiler == null || externalProfiler == null) return;
profiler.Head.AddChild(externalProfiler.Root);
profiler.HasSqlTimings = profiler.GetTimingHierarchy().Any(t => t.HasSqlTimings);
}

Related

Where do the Context fit between the GridField and the GridTab in Idempiere/Adempiere

I m trying to grasp the purpose of the following 3 concepts ( classes ) that are core functionalities in Idempiere/Adempiere.
Based on code description
I do understand that GridTab have the state of the model representing the ad_tab which is the ViewModel Part of any ad_table. simple said we will found the data bound to the ad_table.
First, for the GridField I believe is the model of the view, if I can abuse it is like the the DOM state: what do we have as fields, values of fields and events, I believe that is template view centric.
Dicovering this two ( if I m not mistaken in my analyses ) made me wonder. What do really the Ctx stands for? what state is it representing ?
The code is not commenting on this , can any body answer me?
Thanks .
In iDempiere the context is a Properties object that is global to the whole application.
You can think about the context as a global set of variables that you can access from any point of the system.
The context variables can be viewed clicking on the iDempiere icon, then navigating to the Errors tab, and then clicking on the View button, you'll find there the variables after the line:
=== Context ===
Within the context you can find a lot of information:
Login variables: some of those starting with #, like #AD_Role_ID
Defaults: records that are marked as default, also starting with #, like #C_BP_Group_ID
Accounting related variables: those starting with $, like $C_Currency_ID
Global Preferences: starting with P like P|AutoCommit
Window Preferences: starting with P and a number, example P132|GL_Category_ID
And then, the context variables that you're interested in, the value of each field on the windows that are open:
Window fields: those starting with a number, like 1|DiscountSchema - this means the field DiscountSchema in the first window opened
Tab fields: those starting with two numbers, like 1|2|DatePromised - this means the field DatePromised in the third tab (the number 2, tabs are numbered from zero) of the first window opened (the number 1)
You can access those context variables using Env.getContext... methods, and you can also add and delete your own variables with methods Env.setContext...
The use and intent of Context in ADempiere is the same as described by Carlos except for the access. In the web you can access the context from the top right of the window as shown below.
Another example of how the context provides global state is in testing. Here is a snippet from a test setup class that initializes the context with the time and login information. The context can then be accessed by test classes performing integration tests with a database as if they were in actual use. The context here is limited to login information but it could be extended to include any other element of the context required for the tests.
#BeforeAll
public static void setUpBeforeClass() {
today = TimeUtil.getDay(System.currentTimeMillis());
ctx = Env.getCtx();
ctx.setProperty("#AD_Org_ID", Integer.toString(AD_ORG_ID));
ctx.setProperty("#AD_User_ID", Integer.toString(AD_USER_ID));
ctx.setProperty("#AD_Client_ID", Integer.toString(AD_CLIENT_ID));
ctx.setProperty("#Date", TimeUtil.getDay(System.currentTimeMillis()).toString());
ctx.setProperty("#AD_Language", "en");
Ini.setClient (IS_CLIENT);
Ini.loadProperties(false);
org.compiere.Adempiere.startup(IS_CLIENT);
trxName = Trx.createTrxName("TestRun_" + randomString(4));
trx = Trx.get(trxName, false);
try {
mainSavepoint = trx.setSavepoint("AllTests_" + randomString(4));
} catch (SQLException e) {
fail(e.getMessage());
}
}
#AfterAll
public static void tearDownAfterClass() {
try {
tryToRollback(mainSavepoint);
trx.close();
}
catch(SQLException e) {
fail("Unable to rollback. " + e.getMessage());
}
finally {
trx.close();
trx = null;
ctx = null;
}
}

WebApi Help Page: don't escape HTML in XML documentation

I am using XML Documentation for my ASP.NET Web API Help Page as shown here.
I would like to know if there is a way to include html in the comments such that it will be rendered on the web page, instead of it being removed/ignored/escaped.
Specifically, I am looking for a way to create a newline, but being able to create bulleted lists, etc. would be great!
Ex/ I would like to be able to do something like this:
/// <summary>
/// CRUD operations for SalesDocument<br/>
/// This is a new line
/// </summary>
[RoutePrefix("api/SalesDocument")]
public partial class SalesDocumentController : ApiController
And have it show on the help page like this:
CRUD operations for SalesDocument
This is a new line.
Instead of this: (in this case, <br/> gets removed somehow - if I try using <p> tags, they are just escaped)
CRUD operations for SalesDocument This is a new line.
*I have already tried the <para> tag as suggested by multiple posts for tooltips, but this does not work on my help page.
Any suggestions are greatly appreciated!
In the installed XmlDocumentationProvider.cs file at Areas\HelpPage, you can look for a method called GetTagValue. Here modify the return value from node.Value.Trim() to node.InnerXml.
private static string GetTagValue(XPathNavigator parentNode, string tagName)
{
if (parentNode != null)
{
XPathNavigator node = parentNode.SelectSingleNode(tagName);
if (node != null)
{
return node.InnerXml;
}
}
return null;
}
Now open the installed file Areas\HelpPage\Views\Help\DisplayTemplates\ApiGroup.cshtml and modify the following line from:
<p>#controllerDocumentation</p>
to
<p>#Html.Raw(controllerDocumentation)</p>
#controllerDocumentation does not work for me, but changing the line to#api.Documentation works. i.e. #html.raw(api.Documentation).

Keep my in cached memory objects when recompiling in Visual Studio

I have an MVC 3 site that uses cached in memory objects.
when the site first gets hit, it takes around a minute to build the cache, once built its very fast for everyone then on.
when im developing, ive had to reduce the number of cached objects as everytime i recomple my project it drops the cache and has to rebuild it.
Is there a way i can set Visual studio so it keeps the in memory cache when i recomple ?
here is some of my code i use for caching....
/// <summary>
/// Method to get all the prices
/// </summary>
public static List<DB2011_PriceRange> AllPrices
{
get
{
lock(_PriceLock)
{
if (HttpRuntime.Cache["Prices"] != null)
{
return (List<DB2011_PriceRange>)HttpRuntime.Cache["Prices"];
}
else
{
PopulatePrices();
return (List<DB2011_PriceRange>)HttpRuntime.Cache["Prices"];
}
}
}
}
/// <summary>
/// Poplate the Cache containing the prices
/// </summary>
private static void PopulatePrices()
{
// clear the cache and the list object
ClearCacheAndList("Trims", ref ListAllPrices);
using(var DB = DataContext.Get_DataContext)
{
ListAllPrices = (from p in DB.DB2011_PriceRange
select p).ToList();
}
// add the list object to the Cache
HttpRuntime.Cache.Add("Prices", ListAllPrices, null, DateTime.Now.AddHours(24), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
}
any help is always appricaiated
Truegilly
Recompiling your application causes the AppDomain that is hosting it to be restarted which is what is disposing of your cache. You could:
Try to save your cache to disk and read it from there when the app starts. It might be faster.
Use an out-of-process cache such as Velocity
I don't believe so. When you publish new DLLs the a new process that runs the application is created. Since you're using an in-memory cache, all objects would be removed.
You could "warm the caches" with a special method that would pre-populate them all when you publish new code.

Entlib Cache.Contains NULL problem

I have a combined authorization and menustructure system on our backend.
For performance reasons EntLib caching is used in the frontend client (MVC rel 1.0 website, IIS 5.1 local, IIS 6.0 server, no cluster).
Sometimes 'Cache.Contains' will return true, but the contents of the cache is NULL. I know for certain that I filled it correctly, so what can be the problem here?
EDIT: when I set the cache to 1 minute and add the cacheKey 'A_Key', I will see the key coming back when inspecting the CurrentCacheState. When I view CurrentCacheState after 2 minutes, the key is still there. When I execute 'contains', true is returned. When I execute 'contains' again, the cacheKey is gone!
Synchronization problem??
Regards,
Michel
Excerpt:
if (IntranetCaching.Cache.Contains(cacheKey))
{
menuItems = (List<BoMenuItem>)IntranetCaching.Cache[cacheKey];
}
else
{
using (AuthorizationServiceProxyHelper authorizationServiceProxyHelper = new AuthorizationServiceProxyHelper())
{
menuItems = authorizationServiceProxyHelper.Proxy.SelectMenuByUserAndApplication(APPNAME, userName, AuthorizationType.ENUM_LOGIN);
IntranetCaching.Add(cacheKey, menuItems);
}
}
And the cachehelper:
public static class IntranetCaching
{
public static ICacheManager Cache { get; private set; }
static IntranetCaching()
{
Cache = CacheFactory.GetCacheManager();
}
public static void Add(string key, object value)
{
Cache.Add(
key
, value
, CacheItemPriority.Normal
, null
, new Microsoft.Practices.EnterpriseLibrary.Caching.Expirations.AbsoluteTime(TimeSpan.FromMinutes(10)));
}
}
Thanks Michael for following up your own issue, I have been stuck with this all day identifying that if I try and retrieve an item from Cache this is due to expire (+ 0 up to 25 seconds) I will get a NULL value. Codeplex have posted a workaround (of sorts)as it is in their FAQ:
a. How do I avoid getting a null value from the CacheManager when the item is being refreshed? - Intermittently, you may encounter this situation. To work around this, create your own implementation of an ICacheItemExpiration. In the HasExpired()method, implement a logic that will check whether the item has already expired and will update the item's value if it has expired. This method should always return false for the item to not be tagged as expired. As a result of returning false in the HasExpired() method, the item will not be refreshed and will contain the updated value as implemented in the method.
REF: link
I got the following response from Avanade (creators of Entlib):
Most likely, the BackgroundScheduler
hasn't performed its sweeping yet. If
you're going to examine the source
code, the Contains method only checks
if the specific key is present in the
inmemory cache hashtable while on the
GetData method, the code first checks
if the item has expired, if it has,
the item is removed from the cache.
Sarah Urmeneta Global Technology &
Solutions Avanade, Inc.
entlib.support#avanade.com
That solution is working for me.
Still the question remains why you can use 'Contains' when its outcome cannot be used in a sensible way.
Regards,
M.

How to see Word document text changes in ThisDocument_New()

I'm considering migration of all of our Word templates from VBA to VSTO and have the following question: How can I debug code in a VSTO project?
Unlike debugging in VBA, I can't see the results of code executing line-by-line when stepping through a procedure.
For example, I build a prototype Word document in VS 2019:
using ...;
namespace MyCompany.OfficeTemplates.MyTemplate
{
public partial class ThisDocument
{
private void ThisDocument_Startup(object sender, System.EventArgs e)
{
}
private void ThisDocument_Shutdown(object sender, System.EventArgs e)
{
}
private void ThisDocument_New()
{
var currentSelection = Application.Selection;
currentSelection.TypeText("This text was added by using code.");
}
#region VSTO Designer generated code
/// ...<summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InternalStartup()
{
this.Startup += new System.EventHandler(ThisDocument_Startup);
this.Shutdown += new System.EventHandler(ThisDocument_Shutdown);
this.New += new Microsoft.Office.Interop.Word.DocumentEvents2_NewEventHandler(this.ThisDocument_New);
}
#endregion
}
}
I plan to put way more code (showing a dialog box, choosing customers, choosing language and other information) into the ThisDocument_New() event. Why is the text not inserted into the word document when I step over the command ...TypeText()... with the debugger?!?
Instead, It's inserted when debugger leaves ThisDocument_New()?
What am I missing and where else to put my code when ThisDocument_New() does not allow propper debugging?
That one cannot see what's happening during code execution is typical for VSTO. Debugging is different than with VBA - the results are only visible after the code has finished. Nothing can be done to change this - it's in the nature of the thing (.NET <-> COM interaction).
I struggled with this, myself, when starting with VSTO, and had to learn to work around it.
Generally, if during trouble-shooting it's necessary to see what's happening as it happens, I first test in VBA, then transfer that code to VSTO.
If it's necessary to check values being generated by code as it runs I stick some Debug.Print lines in that I can follow in the Visual Studio output window when stepping through the code.
It's also possible to track what's assigned to objects when stepping through the code.

Resources