I have a C# ASP.net website. Locally I can run it in debug and step through the code to see why things arent working but when its hosted on my live site I cannot do this.
What is the best way to debug what is going on with my website?
Should I add debut/output/trace statements?
If so, which and how do I view the output of these? Can I view them in Chrome-->Developer Tools somehow?
For example, right now I can register a user on my site so I know the database connection is good, but I cannot login a registered user and want to figure out why.
Thanks
You may add trace and debug logs on your app. For ease, you may use logging frameworks like
http://nlog-project.org/
https://serilog.net/
You can actually write your own logging mechanism in which you can create a log class and some functions in it eg
public class Log
{
internal static bool RecordLog(string strSource, string strMethodName, string strStatement)//additional params you think appropriate for your logs
{
List<string> lstInfo = new List<string>();
string strProductName = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location.ToString()).ProductName.ToString();
string strProductVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location.ToString()).ProductVersion.ToString();
try
{
strProductName = FileVersionInfo.GetVersionInfo(Assembly.GetCallingAssembly().Location.ToString()).ProductName.ToString();
strProductVersion = FileVersionInfo.GetVersionInfo(Assembly.GetCallingAssembly().Location.ToString()).ProductVersion.ToString();
}
catch
{
}
try
{
lstInfo.Add("** Date=" + DateTime.Now.ToString("d MMM yy, H:mm:ss") + ", " + strProductName + " v" + strProductVersion);
lstInfo.Add("Source=" + strSource + ", Server=" + strServerIP + ""); //add more info in list as per rquirement
bool flag = blnWriteLog("LogFilename", lstInfo);
}
catch (Exception objEx)
{
//exception handling
}
return true;
}
private static bool blnWriteLog(string strProductName, List<string> lstInfo)
{
string strPath = strGetLogFileName(strProductName);
using StreamReader write in the log file received
return true;
}
private static string strGetLogFileName(string strFilePrefix)
{
//logic to check your file name, if it exists return name else create one
return strFile;
}
}
and then you can use the same from your file
Log.RecordLog()// Values as per your code and requirement
Note : Above is just a suggested way to do it, there can be many other and efficient ways also
You can use the built-in Microsoft Intellitrace feature to step through code from the generated intellitrace logs. This link https://msdn.microsoft.com/en-us/library/dn449058.aspx gives instructions on how to achieve the following;
"If you are using Microsoft Monitoring Agent to control IntelliTrace,
you also need to set up set up application performance monitoring on
your web server. This records diagnostic events while your app runs
and saves the events to an IntelliTrace log file. You can then look at
the events in Visual Studio Enterprise (but not Professional or
Community editions), go to the code where an event happened, look at
the recorded values at that point in time, and move forwards or
backwards through the code that ran. After you find and fix the
problem, repeat the cycle to build, release, and monitor your release
so you can resolve future potential problems earlier and faster."
Related
I am facing issue with perforce api (.net), as i am unable to pull sync logs in real time.
- What am I trying to do
I am trying to pull real time logs as Sync is triggered using the
Perforce.P4.Client.SyncFiles() command. Similar to the P4V GUI Logs, which update when we try to sync any files.
- What is happening now
As the output is generated only after the command is done execution its not something intended for.
Also tried looking into Perforce.P4.P4Server.RunCommand() which does provide detailed report but only after the execution of the command.
Looked into this
Reason is -
I am trying to add a status update to the Tool i am working on which shows which Perforce file is currently being sync'd.
Please advise. Thanks in Advance.
-Bharath
In the C++ client API (which is what P4V is built on), the client receives an OutputInfo callback (or OutputStat in tagged mode) for each file as it begins syncing.
Looking over the .NET documentation I think the equivalents are the P4CallBacks.InfoResultsDelegate and P4CallBacks.TaggedOutputDelegate which handle events like P4Server.InfoResultsReceived etc.
I ended up with the same issue, and I struggled quite a bit to get it to work, so I will share the solution I found:
First, you should use the P4Server class instead of the Perforce.P4.Connection. They are two classes doing more or less the same thing, but when I tried using the P4.Connection.TaggedOutputReceived events, I simply got nothing back. So instead I tried with the P4Server.TaggedOutputReceived, and there, finally, I got the TaggedOutput just like I wanted.
So, here is a small example:
P4Server p4Server = new P4Server(cwdPath); //In my case I use P4Config, so no need to set user or to login, but you can do all that with the p4Server here.
p4Server.TaggedOutputReceived += P4ServerTaggedOutputEvent;
p4Server.ErrorReceived += P4ServerErrorReceived;
bool syncSuccess=false;
try
{
P4Command syncCommand = new P4Command(p4Server, "sync", true, syncPath + "\\...");
P4CommandResult rslt = syncCommand.Run();
syncSuccess=true;
//Here you can read the content of the P4CommandResult
//But it will only be accessible when the command is finished.
}
catch (P4Exception ex) //Will be caught only when the command has failed
{
Console.WriteLine("P4Command failed: " + ex.Message);
}
And the method to handle the error messages or the taggedOutput:
private void P4ServerErrorReceived(uint cmdId, int severity, int errorNumber, string data)
{
Console.WriteLine("P4ServerErrorReceived:" + data);
}
private void P4ServerTaggedOutputEvent(uint cmdId, int ObjId, TaggedObject Obj)
{
Console.WriteLine("P4ServerTaggedOutputEvent:" + Obj["clientFile"]); //Write the synced file name.
//Note that I used this only for a 'Sync' command, for other commands, I guess there might not be any Obj["clientFile"], so you should check for that.
}
I have a C# console application which creates, parses and deletes multiple xml files at runtime. The application used to run fine in Windows 2003 server with .Net 2.0.
Recently, the Application framework was upgraded to >net 4.0 and the Windows Server OS to Windows 2008 64-bit.
Since then, the application encounters the following exception at random:
Access to the path 'D:\Content\iSDC\GDCOasis\GATE_DATA\LOG\635125008068192773\635125008074911566\SOD\AllRespId.xml' is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.Delete(String path)
at ProcessGateFile.SOD.saveFile(String psFile, String psXMLString, Boolean isNonAscii)
The code for the creation, parsing and deletion is as follows:
saveFile(tmpPath + "\\SOD\\AllRespId.xml", "<?xml version= \"1.0\" ?><XML>" + sbldDistinctResp.ToString() + "</XML>", isChinese);
//Save list of Distinct responsibilities for User
sbldDistinctResp.Remove(0, sbldDistinctResp.Length);
xmlCase.Load(tmpPath + "\\SOD\\AllRespId.xml");
arrResps.Clear();
//Start preparing Responsibility selection criteria
RespNodes = xmlCase.SelectNodes("//row");
sRespCriteria = "";
if (RespNodes.Count > 0)
{
foreach (XmlNode RespNode in RespNodes)
{
string RespName = RespNode.Attributes.GetNamedItem("RespId").Value.ToString();
if (!arrResps.Contains(RespName))
{
arrResps.Add(RespName);
}
}
for (int i = 0; i < arrResps.Count; i++)
{
sbldDistinctResp.Append("(#RespId = '" + arrResps[i].ToString() + "') or ");
}
sbldDistinctResp.Remove(sbldDistinctResp.Length - 4, 4);
sRespCriteria = sbldDistinctResp.ToString();
if (!sRespCriteria.Equals(""))
{
sRespCriteria = "(" + sRespCriteria + ")";
}
}
File.Delete(tmpPath + "\\SOD\\AllRespId.xml");
I repeat, the error is happening at random, i.e. it works at times and does not at other times during the same process.
Any idea what might be causing this and how to resolve?
Just a couple of observations:
Why are you saving and then immediately loading the file again? In fact, why do you even need to save this file - you already have all the information you need in the sbldDistinctResp variable to generate the XML you need to work with (as evidenced by the saveFile call at the start of the code) - couldn't you just make a copy of it, surround it with the same XML as you did during saveFile, and work with that?
"It happens randomly" is a very subjective observation :). You should profile this (run it 10,000 times in a loop for example) and record the pattern of errors. You may well be surprised that what seems random at first actually shows a clear pattern over a large number of runs. This may help you to make a connection between the problem and some other apparently unrelated event on the server; or it may confirm that it truly is random and therefore outside of your control.
If you really can't find the problem and you go with the idea of anti-virus, etc, then you could wrap the loading code in a try/catch and re-try a couple of times if you get the error. It's hacky but it would work, assuming you have accepted that the initial error is beyond your control.
Is there any API for writing a C# program that could interface with Windows update, and use it to selectively install certain updates?
I'm thinking somewhere along the lines of storing a list in a central repository of approved updates. Then the client side applications (which would have to be installed once) would interface with Windows Update to determine what updates are available, then install the ones that are on the approved list. That way the updates are still applied automatically from a client-side perspective, but I can select which updates are being applied.
This is not my role in the company by the way, I was really just wondering if there is an API for windows update and how to use it.
Add a Reference to WUApiLib to your C# project.
using WUApiLib;
protected override void OnLoad(EventArgs e){
base.OnLoad(e);
UpdateSession uSession = new UpdateSession();
IUpdateSearcher uSearcher = uSession.CreateUpdateSearcher();
uSearcher.Online = false;
try {
ISearchResult sResult = uSearcher.Search("IsInstalled=1 And IsHidden=0");
textBox1.Text = "Found " + sResult.Updates.Count + " updates" + Environment.NewLine;
foreach (IUpdate update in sResult.Updates) {
textBox1.AppendText(update.Title + Environment.NewLine);
}
}
catch (Exception ex) {
Console.WriteLine("Something went wrong: " + ex.Message);
}
}
Given you have a form with a TextBox this will give you a list of the currently installed updates. See http://msdn.microsoft.com/en-us/library/aa387102(VS.85).aspx for more documentation.
This will, however, not allow you to find KB hotfixes which are not distributed via Windows Update.
The easiest way to do what you want is using WSUS. It's free and basically lets you setup your own local windows update server where you decide which updates are "approved" for your computers. Neither the WSUS server nor the clients need to be in a domain, though it makes it easier to configure the clients if they are. If you have different sets of machines that need different sets of updates approved, that's also supported.
Not only does this accomplish your stated goal, it saves your overall network bandwidth as well by only downloading the updates once from the WSUS server.
If in your context you're allowed to use Windows Server Update Service (WSUS), it will give you access to the Microsoft.UpdateServices.Administration Namespace.
From there, you should be able to do some nice things :)
P-L right. I tried first the Christoph Grimmer-Die method, and in some case, it was not working. I guess it was due to different version of .net or OS architecture (32 or 64 bits).
Then, to be sure that my program get always the Windows Update waiting list of each of my computer domain, I did the following :
Install a serveur with WSUS (may save some internet bandwith) : http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=5216
Add all your workstations & servers to your WSUS server
Get SimpleImpersonation Lib to run this program with different admin right (optional)
Install only the administration console component on your dev workstation and run the following program :
It will print in the console all Windows updates with UpdateInstallationStates.Downloaded
using System;
using Microsoft.UpdateServices.Administration;
using SimpleImpersonation;
namespace MAJSRS_CalendarChecker
{
class WSUS
{
public WSUS()
{
// I use impersonation to use other logon than mine. Remove the following "using" if not needed
using (Impersonation.LogonUser("mydomain.local", "admin_account_wsus", "Password", LogonType.Batch))
{
ComputerTargetScope scope = new ComputerTargetScope();
IUpdateServer server = AdminProxy.GetUpdateServer("wsus_server.mydomain.local", false, 80);
ComputerTargetCollection targets = server.GetComputerTargets(scope);
// Search
targets = server.SearchComputerTargets("any_server_name_or_ip");
// To get only on server FindTarget method
IComputerTarget target = FindTarget(targets, "any_server_name_or_ip");
Console.WriteLine(target.FullDomainName);
IUpdateSummary summary = target.GetUpdateInstallationSummary();
UpdateScope _updateScope = new UpdateScope();
// See in UpdateInstallationStates all other properties criteria
_updateScope.IncludedInstallationStates = UpdateInstallationStates.Downloaded;
UpdateInstallationInfoCollection updatesInfo = target.GetUpdateInstallationInfoPerUpdate(_updateScope);
int updateCount = updatesInfo.Count;
foreach (IUpdateInstallationInfo updateInfo in updatesInfo)
{
Console.WriteLine(updateInfo.GetUpdate().Title);
}
}
}
public IComputerTarget FindTarget(ComputerTargetCollection coll, string computername)
{
foreach (IComputerTarget target in coll)
{
if (target.FullDomainName.Contains(computername.ToLower()))
return target;
}
return null;
}
}
}
right now this code works by picking up the authenticated user (windows authentication). we are using active directory. however if you are off the network and try to log into this specific application you get redirected to our ISA 2006 server, which then passes login information into the application (in theory, lol)
when I access this app on my phone over 3g its pretty slow, but i dont get an error (the error just being a popup with an ok button, sometimes it says error, sometimes it doesnt). However when I use a faster better computer over the external it does give me this error. Unit testing by my colleagues revealed there to be some sort of recursive loop or some sort which was giving the error. any time you log into the web application while on the network, it picks up windows authentication with no problem and gives no error. I have spent 3 days trying to figure out my bug but cant find it, I hope another few set of eyes can help me track it down (I am using ASP.net 4.0 with C#)
public string IdentifyUser()
{
string retval = string.Empty;
try{
//System.Security.Principal.WindowsPrincipal p = System.Threading.Thread.CurrentPrincipal as System.Security.Principal.WindowsPrincipal;
//string UserIdentityName = p.Identity.Name;
string UserIdentityName = Request.ServerVariables["AUTH_USER"];
//string UserIdentityName = HttpContext.Current.User.Identity.Name.ToString();
string slash = #"\";
string Username = UserIdentityName.Substring(UserIdentityName.IndexOf(slash) + 1);
retval = Data_Access_Layers.SQL.GetUserID(Username);
}
catch (Exception ex)
{
throw ex;
}
return retval;
}
basically this fires off, pulls the username, it gets sent to "GetUserID" which looks up that username and sends back the user id attached to that person, which is then sent back out to the main page, and is stored in a javascript variable (to be used on other parts of the page)
Is the problem that AUTH_USER is empty?
What is the value of the AUTH_TYPE header when accessing the app from inside and outside the network?
I've developed a sample software in c# windows Appliation. How to make it a multilingual supporting software.
For Example: One of the message boxes display " Welcome to sample application"
i installed the software in a chinees os , but it displays the message in english only.
i'm using "string table" (Resource File) for this problem.
In string table i need to create entry for each messages in english and Chinees.
its a timely process. is there any other way to do this?
Create Resources files for each language you want to give support for mentioned below.
alt text http://geekswithblogs.net/images/geekswithblogs_net/dotNETPlayground/resx.gif
Based on the language/currentculture of the user, read values from respective Language Resource file and display in label or MessageBox. Here's some sample code:
public static class Translate
{
public static string GetLanguage()
{
return HttpContext.Current.Request.UserLanguages[0];
}
public static string Message(string key)
{
ResourceManager resMan = null;
if (HttpContext.Current.Cache["resMan" + Global.GetLanguage()] == null)
{
resMan = Language.GetResourceManager(Global.GetLanguage());
if (resMan != null) HttpContext.Current.Cache["resMan" + Global.GetLanguage()] = resMan;
}
else
resMan = (ResourceManager)HttpContext.Current.Cache["resMan" + Global.GetLanguage()];
if (resMan == null) return key;
string originalKey = key;
key = Regex.Replace(key, "[ ./]", "_");
try
{
string value = resMan.GetString(key);
if (value != null) return value;
return originalKey;
}
catch (MissingManifestResourceException)
{
try
{
return HttpContext.GetGlobalResourceObject("en_au", key).ToString();
}
catch (MissingManifestResourceException mmre)
{
throw new System.IO.FileNotFoundException("Could not locate the en_au.resx resource file. This is the default language pack, and needs to exist within the Resources project.", mmre);
}
catch (NullReferenceException)
{
return originalKey;
}
}
catch (NullReferenceException)
{
return originalKey;
}
}
}
In asn asp.net application, you'd use it as following:
<span class="label">User:</span>
You now would put:
<span class="label"><%=Translate.Message("User") %>:</span>
If you were going to use resource files as Ram suggested, there is a good blog post about localisation
here: ASP.NET MVC 2 Localization complete guide. (I should have mentioned that this is for Asp.net mvc 2, it may or may not be useful) You still have to spend time making tables for each language. I have not used any other approach for this before, hope you find something useful
You can do it using resource files. You need to create resource file for each language and you can use the appropriate one while running the application.
Resharper 5.0 can greatly improve the time you spend on localization. It has features that allows easy move to resource and it underlines (if chosen so) all strings that are localizable so it's harder to miss them.
Given that it has 30 days trial (full version) you can simply install it, do your job and uninstall if you can't afford it, but i would suggest to keep it :-) It's really worth it's price.
Software localization and globalization have always been tough and at times unwanted tasks for developers. ReSharper 5 greatly simplifies working with resources by providing a full stack of features for resx files and resource usages in C# and VB.NET code, as well as in ASP.NET and XAML markup.
Dedicated features include Move string to resource, Find usages of resource and other navigation actions. Combined with refactoring support, inspections and fixes, you get a convenient localization environment.