I am trying to add PerformanceCounter logging as part of our WebForms application. I am attempting to port an MVC implementation that uses ActionFilters to write request durations per controller action to custom performance counter instances here.
My implementation is to write an HttpModule that logs the OnBeginRequest and OnEndRequest to write to these custom performance counters. However, when I view in PerfMon, I can see the instances of my counters show up in PerfMon, but the values are all empty ("------").
I am initializing the performance counter using the following code:
var counter = new PerformanceCounter {
CategoryName = categoryName,
CounterName = counterName,
InstanceName = instanceName,
ReadOnly = false,
InstanceLifetime = PerformanceCounterInstanceLifetime.Process,
RawValue = 0,
};
Even if I didn't update the value, I would assume that the Last value would be 0, but instead it is '-------'.
The code in the sample associated with the article does work and uses the same syntax. I did notice that the counters written by the MVC attribute have no 'Parent' but the ones created by the WebForms module have a parent specified. I don't know if this has anything to do with it.
I have checked to ensure that no errors are being recorded in the Event log. I would appreciate guidance on why my performance counters are not updating.
Thanks
UPDATE 6/5/2014
I discovered that the issue was a '/' in the instance name, which gets turned into parent/instance which cannot be found once created. Make sure that you clean up your instance name to ensure that no forward slashes exist, or you won't be able to update the values.
I discovered that the issue was a forward slash ('/') in the instance name I was assigning, which gets split into parent/instance which cannot be found once created. Make sure that you clean up your instance name to ensure that no forward slashes exist, or you won't be able to update the performance counter's values.
Related
A problem appears when two users are logged on to our service system at the same time and looking at the service list gridview. If user1 does a search to filter the gridview and user2 happens to click to another page user2 sees the results from the search performed by user1. That means one company can see another company's data.
It's an ASP.NET application that was developed in house with C#/ASP.NET 3.5. The data is stored in a SQL 2000 database and relies very heavily on stored procedures to update, select, and delete data. There are multiple user types that are restricted to what data they can see. For example, we have a company use that can only see data relavant to that company.
From what I've seen, the security is handled through If statements in the front end. Example, if userlevel = 1 then do this, if userlevel = 2 do this. These statments are used to show or hide columns in a grid, run queries to return data, and any other restrictions needed. For a company user the code behind gets the companyid assigned to the user and uses that in a query to return the results of all the data associated with that companyid (services, ships, etc).
Any recommendations for fixing this will be highly appreciated.
It's hard to say without seeing any implementation details, but on the surface it appears that there maybe some company level caching. Check for OutputCache settings, DataSource caching, explicit caching with Page.Cache, etc.
This article is a little dated, but at a glance it looks like most information is still relevant in ASP.NET 4.0.
ASP.NET Caching: Techniques and Best Practices
In addition to jrummerll's answer, check the Data Acces Layer of our app and make sure that you don't have any static variables defined. Having a static variable defined could cause this sort of issue too, since 2 contending requests may overwrite the value of the CompanyID, for example.
You basic model should work. What you've told us is not enough to diagnose the problem. But, I've got a few guesses. Most likely your code is confusing UserID or CompanyID values.
Are you mistakenly storing the CompanyID in the Cache, rather than the session?
Is the CompanyID stored in a static variable? A common (and disastrous!) pitfall in web applications is that a value stored in a static variable will remain the same for all users! In general, don't use static variables in asp.net apps.
Maybe your db caching or output caching doesn't vary properly by session or other variables. So, a 2nd user will see what was created for the previous user. Stop any caching that's happening and see if that fixes it, but debug from there.
Other variations on the above themes: maybe the query is stored in a static variable. Maybe these user-related values are stored in the cache or db, but the key for that record (UserID?) is stored in a static variable?
You can put that if statements in a thread. Threading provides you the option that only 1 user can access the application or gridview in your case.
See this link: http://msdn.microsoft.com/en-us/library/ms173179.aspx
Here is some sample code that is throughout the entire application that is used for filtering results. What is the best way to fix this so that when one user logs on, the other user doesn't see those results?
protected void PopulategvServiceRequestListing(string _whereclause)
{
_dsGlobalDatasource = new TelemarServiceRequestListing().GetServiceRequestListingDatasource(_whereclause);
if(_dsGlobalDatasource.Tables[0].Rows.Count!=0)
{
gv_ServiceRequest.DataSource = _dsGlobalDatasource;
gv_ServiceRequest.DataBind();
}
else
{
gv_ServiceRequest.DataSource=new TelemarServiceRequestListing().DummyDataset();
gv_ServiceRequest.DataBind();
gv_ServiceRequest.Rows[0].Visible = false;
gv_ServiceRequest.HeaderStyle.Font.Bold = true;
}
}
In the controllers generated by Visual Studio, as well as the sample application (ContosoUniversity), the Index action always has something like
var departments = db.Departments.Include(d => d.Administrator);
What's the difference between that and
var departments = db.Departments;
First I suspected that the first one (with Include) enables the view to retrieve department.Administrator. But the second one (without Include) seems to be able to do that as well.
The Include tells Entity Framework work to eagerly load the Administrator for each Department in the results. In this case, Entity Framework can use a SQL join to grab the data from both tables in a single request.
The code will still work without the Include, but the first time you access a Department's Administrator, EF will need to hit the database to load it (since it wasn't pre-loaded). Loading data on demand (lazily) is a nice feature but it can be a serious performance problem (known as an N+1 problem). Especially if you are accessing the Administrator for each Department (for example, in a loop) - instead of one database call, you will end up with many!
In first case (with Include) when you write department.Administrator servers the object from memory that has been eagerly loaded due to Include method. In the second case, an sql statement will be executed to fetch the Administrator record from the db for each department object.
See the "Lazy, Eager, and Explicit Loading of Related Data" section in this tutorial:
http://www.asp.net/entity-framework/tutorials/reading-related-data-with-the-entity-framework-in-an-asp-net-mvc-application
var departments = db.Departments;
This will retrieves the aggregate domains only if LazyLoadingEnabled is enabled & MultipleActiveResultSets is set to true in connection string.
I'm using WF, I res-hosted the designer, and everything is fine till i need in my custom activities to wait a value when workflow is running, that what i made using BOOKMARK. i tried bookmark in ConsoleApplication and its work.
the following code i used in the main class in the ConsoleApplication:
AutoResetEvent syncEvent = new AutoResetEvent(false);
wa.Completed = delegate(WorkflowApplicationCompletedEventArgs r)
{
syncEvent.Set();
};
wa.Run();
wa.ResumeBookmark("bookmarkName", Console.ReadLine());
syncEvent.WaitOne();
but here in my rehosted project, i need to call many workflows. not only 1. and I can't specify it before runtime.
for this method:
wa.ResumeBookmark("bookmarkName", Console.ReadLine());
1st argument: bookmarks' names, i tried and i found i can name all bookmarks the same name.
About the 2nd argument, how can I pass the value for each workflow, and some workflows have more than 1 bookmark.
I have to read the value from many places, asp.net pages, DB and others.
Im sure there is something like these in WF 4.0, but i didnt find it. can u help me please :)
Thank you.
You need to keep track of each workflow's Id, and record that Id when a bookmark is created. Once you wish to return to the workflow, you can search for the one with the matching Id and then resume your bookmark.
I have an ASP.NET MVC application. I have come to an idea of generating autoincremented values to be used as unique element ids. The question is, how can I have and work with a global variable which should be there for the duration of a request (page generation) but no longer?
I thought of using TempData for this shared variable and then just delete this key when the page is done. But then, where in code to purge this TempData key? Obviously it has to be some very last piece of code where the page has been rendered already.
Any input is highly appreciated.
EDIT: I have a number of HTML helpers that can be called from various views and partial views, so declaring a variable on a page and passing it to each helper is obviously not a good solution. I wish to just use the helpers and know they all are getting unique ids behind the scenes.
Okay, I have googled a little bit and found a solution on ASP.NET forums.
http://forums.asp.net/t/1401685.aspx
Obviously, I can use the HttpContext.Current.Items collection to have my little static variable for the duration of a request.
If all you need is to store a number, the resources that would take to manage its lifestyle would take a lot more than just having a one static integer and always reusing it.
Do not bother deleting the key after each request. Just use a static (I think this is shared in visual basic) integer, use and increment it every time you need a unique value. Also take its mod with a ridiculously high number each time to make sure it will not be reused in a single request and it will never overflow.
Why don't you define your integer variable at the top of the page view file?
Use it throughout the view rendering execution and at the end of it you can easily leave it as is. You don't have to explicitly destroy anything. Your variables live for the duration of request only. IIS is stateless service (if you subtract Session, Cache and Application variables) so it doesn't really remember anything explicitly.
I would imagine you could use the Application_BeginRequest and Application_EndRequest methods in global.asax.cs; Note I can't double check the method names currently, but I think they are close.
You could create a member variable in your controller which would be regenerated for each request:
public class ItemController : Controller
{
private int _UniqueID = 0;
public ActionResult Index()
{
foreach (var item in items)
{
item.UniqueID = _UniqueID++;
}
// etc...
}
I think I have a solution to this, but is there a better way, or is this going to break on me?
I am constructing a localized web site using global/local resx files. It is a requirement that non-technical users can edit the strings and add new languages through the web app.
This seems easy enough -- I have a form to display strings and the changes are saved with code like this snippet:
string filename = MapPath("App_GlobalResources/strings.hu.resx");
XmlDocument xDoc = new XmlDocument();
XmlNode xNode;
xDoc.Load(filename);
xNode = xDoc.SelectSingleNode("//root/data[#name='PageTitle']/value");
xNode.InnerText = txtNewTitle.Text;
xDoc.Save(filename);
Is this going to cause problems on a busy site? If it causes a momentary delay for recompilation, that's no big deal. And realistically, this form won't see constant, heavy use. What does the community think?
I've used a similar method before for a very basic "CMS". The site wasn't massively used but it didn't cause me any problems.
I don't think changing a resx will cause a recycle.
We did something similar, but used a database to store the user modified values. We then provided a fallback mechanism to serve the overridden value of a localized key.
That said, I think your method should work fine.
Have you considered creating a Resource object? You would need to wrap your settings into a single object that all the client code would use. Something like:
public class GuiResources
{
public string PageTitle
{
get return _pageTitle;
}
// Fired once when the class is first created.
void LoadConfiguration()
{
// Load settings from config section
_pageTitle = // Value from config
}
}
You could make it a singleton or a provider, that way the object is loaded only one time. Also you could make it smart to look at the current thread to get the culture info so you know what language to return.
Then in your web.config file you can create a custom section and set restartOnExternalChanges="true". That way, your app will get the changed when they are made.