ASP.NET MVC How to debug a published folder - c#

Good day Someone.
I am new to asp.net mvc.
I created a simple web application using asp.net mvc.
The application is used to upload image from to a folder. The application works well in visual studio, but once i publish and put on iis it does not upload the image.
I am thinking if there is way to debug the published version so that i can get where the issued is ?
Kindly help on how i can debug the published version and how to solve the problem .
Below is where it is catching the error
string path = System.IO.Path.Combine(targetLocation, file.FileName);

I Would suggest doing the debugging for ASP.NET MVC Application to follow the below points.
Server-side - You should use do exception filter to write any issues to text files and track it
Front - End - the developer tool in the browser level for javascript related things.
DataBase Side - You can use the SQL profiler to use catch the server-side debugging.

add try catch block in your codes
and in the catch code log the exception error message into a file in server to see what is the exact error as following:
add this model to your solution under "Models" folder or anywhere
public class ExceptionLogger
{
private string sLogFormat;
public void ErrorLog(string sErrMsg)
{
try
{
string LogDirectory = "C:\LogFiles\";
CheckCreateLogDirectory(LogDirectory);
LogDirectory = (LogDirectory + "Log_" + DateTime.Now.ToString("dd_MM_yyyy", new CultureInfo("en-us")) + ".txt");
sLogFormat = DateTime.Now.ToString("dd/MM/yyyy", new CultureInfo("en-us")) + " " + DateTime.Now.ToString("HH:mm:ss", new CultureInfo("en-us")) + " ==> ";
StreamWriter sw = new StreamWriter(LogDirectory, true);
sw.WriteLine(sLogFormat + sErrMsg);
sw.Flush();
sw.Close();
}
catch (Exception e) {
}
}
private bool CheckCreateLogDirectory(string LogPath)
{
bool loggingDirectoryExists = false;
DirectoryInfo oDirectoryInfo = new DirectoryInfo(LogPath);
if (oDirectoryInfo.Exists)
{
loggingDirectoryExists = true;
}
else
{
try
{
Directory.CreateDirectory(LogPath);
loggingDirectoryExists = true;
}
catch
{
throw new Exception();
// Logging failure
}
}
return loggingDirectoryExists;
}
}
Then in your controller or repository where errors may happen do the following:
a- add this code in top:
ExceptionLogger Err = new ExceptionLogger();
//you need to write "using" in top to refactor the import error
// something like this: using YourProjectName.Models;
b- in your code blocks add try catch block
try{
//your code
}catch(Exception ex){
Err.ErrorLog(ex.Message + " --- , ---- " + ex.InnerException);
}
another way is to add OnException event on your BaseController which will detect any error or exception, hence you can log it without try-catch blocks, do it as following:
define this in your baseController: ExceptionLogger Err = new ExceptionLogger(); with its using then add the event:
protected override void OnException(ExceptionContext filterContext)
{
var isSent = false;
if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
{
return;
}
if (new HttpException(null, filterContext.Exception).GetHttpCode() != 500)
{
return;
}
if (filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
filterContext.Result = new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new
{
error = true,
message = filterContext.Exception.Message
}
};
LogError("Controller: AjaxCall" + " Action: AjaxCall" + filterContext.Exception.Message, filterContext.Exception);
}
else if (filterContext.Exception is HttpAntiForgeryException)
{
Response.Clear();
Server.ClearError(); //make sure you log the exception first
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(new { action = "Logout", controller = "Account" }));
}
else
{
var controllerName = (string)filterContext.RouteData.Values["controller"];
var actionName = (string)filterContext.RouteData.Values["action"];
var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
if (actionName == "_Menu")
{
isSent = true;
Response.Redirect("~/Account/Logout");
}
filterContext.Result = new ViewResult
{
ViewName = "~/Views/Error/Error.cshtml",
MasterName = null,
ViewData = new ViewDataDictionary(model),
TempData = filterContext.Controller.TempData
};
////Redirect or return a view, but not both.
LogError("Controller: " + controllerName + " Action: " + actionName + filterContext.Exception.Message, filterContext.Exception);
}
// log the error by using your own method
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
if (isSent == false)
{
filterContext.HttpContext.Response.StatusCode = 500;
}
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
private void LogError(string message, Exception exception)
{
Err.ErrorLog(message + " && " + exception.Message);
}
now when errors happen then you will go to c:/logfiles folder in the server and find the exact error happened

Related

Exception Logging Without using try catch - ASP.NET WEB API

I need to log exceptions and bad requests in my API. Currently I am using try catch to catch the exception and add to my logs in the catch block. Is this the right way? I read about Global Error Handling in ASP.NET. How can I implement that approach for this case?
Below is my API Controller example:
[HttpPost]
[Authorize]
[ValidateModel]
[Route("CheckProgramOwner")]
public async Task<IHttpActionResult> CheckProgramOwner([FromBody] CheckProgramOwner _data)
{
try
{
using (var db = new VisualVoiceFlowEntities())
{
var Result= await db.VVF_ScriptFlow.Where(s => s.ProgramId == _data.ProgramId).OrderByDescending(s => s.ID).FirstOrDefaultAsync();
if(Result== null)
{
Log.Error("Error in CheckProgramOwner POST Request - " + "ProgramId not found");
return Content(HttpStatusCode.BadRequest, "ProgramId not found");
}
string CurrentOwner = Result.ReadBy.ToString();
return Ok(CurrentOwner);
}
}
catch (Exception ex)
{
Log.Error("Error in CheckProgramOwner POST Request - " + ex.Message, ex);
NewRelic.Api.Agent.NewRelic.NoticeError("Error in CheckProgramOwner POST Request - " + ex.Message, null);
return Content(HttpStatusCode.InternalServerError, "Internal Server Error. Please Contact Admin.");
}
}
If you read the document previously posted by Casey, you will find a link to the following document, which explains how to implement and register an exception filter globally:
https://learn.microsoft.com/en-us/aspnet/web-api/overview/error-handling/exception-handling#registering_exception_filters
You could then implement your logging logic in the filter's body thus avoiding having to repetitively log errors on each try/catch. I would suggest logging the more obvious errors using your original approach and use the filter to log any other errors (that you might not expect.)
I did it using ExceptionFilter.
I created Exception Filter Class as below -
public class MyExceptionFilter : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
log4net.ThreadContext.Properties["addr"] = HttpContext.Current.Request.UserHostAddress;
log4net.ThreadContext.Properties["Hostname"] = Dns.GetHostName().ToString();
log4net.ThreadContext.Properties["PCName"] = Dns.GetHostAddresses(Environment.MachineName)[0].ToString();
string RequestMethod = context.Request.Method.Method;
dynamic ControllerInfo = context.ActionContext.ControllerContext.Controller;
string RequestName = ControllerInfo.Url.Request.RequestUri.LocalPath.ToString().Replace("/api/", "").Replace("/VVFAPI", "");
Log.Error("Error in " + RequestName +" "+ RequestMethod+ " Request - " + context.Exception.Message, context.Exception);
NewRelic.Api.Agent.NewRelic.NoticeError("Error in " + RequestName + " " + RequestMethod + " Request - " + context.Exception.Message, null);
HttpResponseMessage msg = new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent("Internal Server Error. Please Contact Admin."),
ReasonPhrase = "Critical Exception."
};
context.Response = msg;
}
}
Also, I changed my controller accordingly
[HttpPost]
[Authorize]
[ValidateModel]
[MyExceptionFilter]
[Route("CheckProgramOwner")]
public async Task<IHttpActionResult> CheckProgramOwner([FromBody] CheckProgramOwner _data)
{
Log.Info("CheckProgramOwner POST Request");
using (var db = new VisualVoiceFlowEntities())
{
var Result = await db.VVF_ScriptFlow.Where(s => s.ProgramId == _data.ProgramId).OrderByDescending(s => s.ID).FirstOrDefaultAsync();
if (Result == null)
{
Log.Error("Error in CheckProgramOwner POST Request - " + "ProgramId not found");
return Content(HttpStatusCode.BadRequest, "ProgramId not found");
}
string CurrentOwner = Result.ReadBy.ToString();
return Ok(CurrentOwner);
}
}

Kendo Grid duplication message

I am using Kendo grid and I have stopped the grid from saving duplicate values as follows in create method:
var results = new List<ProviderTypeMasterViewModel>();
try
{
_logger.LogInformation("ProviderTypeMastersController ProviderType_Create Start");
foreach (var ProviderTypeMaster in ProviderTypeMasterList)
{
TblProviderTypeMaster ptm = new ProviderTypeMasterViewModel().ToModel(ProviderTypeMaster);
var provd = _context.TblProviderTypeMasters.Where(p => p.ProviderTypeName == ProviderTypeMaster.ProviderTypeName).ToList();
if (provd != null && provd.Count() == 0)
{
if (ProviderTypeMasterList != null && ModelState.IsValid)
{
string userID = GetUserID();
providerTypeMasterService.SaveProviderTypeMaster(ProviderTypeMaster, userID);
}
}
else
{
duplicate = true;
//Session["ErrMsg"] = "Already Exists";
//return RedirectToAction("ProviderType_Read", "ProviderTypeMasters");
}
}
_logger.LogInformation("ProviderTypeMastersController ProviderType_Create Complete");
}
catch (Exception e)
{
_logger.LogError("ProviderTypeMastersController ProviderType_Create Failed - " + e.Message);
}
return Json(results.ToDataSourceResult(request, ModelState));
And in the read method I have displayed the error message to the user as follows
try
{
if (duplicate == true)
{
TempData["ErroMsg"] = "Already Exists";
}
_logger.LogInformation("In ProviderTypeMastersController ProviderType_Read");
return Json(providerTypeMasterService.ListProviderTypeMaster().ToDataSourceResult(request));
}
catch (Exception e)
{
_logger.LogError("ProviderTypeMastersController ProviderType_Read Failed - " + e.Message);
}
return View();
The duplication process has stopped. But I am unable to show the error message to the user. Can anyone let me know what I should do where I have gone wrong. I have tried using ViewBag,ViewData,TempData.
This is my View
<div>
if (TempData["ErroMsg"] != null)
{
<p>#TempData["ErroMsg"].ToString()</p>
}
you can use DataBinding() and DataBound() function of kendo grid...these functions call in client side after Read method on server side..for example you can set a field and decision with this field

Task<T>.Factory.StartNew in ASP.NET MVC

I'm stuck with a problem. I need help...
In general, I have an ASP.NET MVC 5 project. When a user clicks on "Save" button, I run some code in a new created task. I need to know the result of operation, so I return the instance of my class ChangesMade. Then I serialze the object to JSON format and pass to a view. Then I check if result is true, I open an url in a new window.
So, in my controller I have the following:
public async Task<ActionResult> Save(here some parameters)
{
var changes = await _model.SaveAsync(some parameters);
return NewtownJson(changes);
}
The main saving logic is the following:
public async Task<ChangesMade> SaveAsync(some parameters here)
{
var data = (await _model.GetData(some parameter)).ToList();
// create a task of ChangesMade that contains public bool property MemoAdded
// that I need to pass to a view to know the result of operation
var task = Task<ChangesMade>.Factory.StartNew(() =>
{
ChangesMade changes = new ChangesMade();
try
{
using (var tr = new TransactionScope())
{
// some code here omitted for simplicity…
// if (someCondition == true) changes.MemoAdded = true;
tr.Complete();
}
return changes;
}
catch (Exception ex)
{
throw ex;
}
});
try
{
task.Wait();
}
catch (AggregateException ex)
{
string msg = "";
msg= ex.Flatten().InnerExceptions
.Where(e => e != null)
.Select(e => e.Message)
.Aggregate(msg, (current, message) => current + " " + message + ";")
.TrimEnd(';');
throw new Exception(msg);
}
return task.Result;
}
I publish the project on two sites on IIS. The first works fine. But the second doesn't - by some reason, it always returns changes.MemoAdded false to the view.
I can't find out a reason of that. I don't have a clue what to do ...

LiveConect Auth (for SkyDrive) NullReferenceException (WTH)?

I followed a 43 minute video tutorial on the Channel 9 site and read the LiveConnect page where it shows code and I don't see what I'm doing wrong. It keeps giving me a NullReferenceException error and it doesn't even bring up the "Do you want to allow app X to access skydrive" thing, it just breaks immediately. I've set breakpoints everywhere but there is nothing. Just null, null everywhere.
OnNavigatedTo event:
LoadProfile();
private async void LoadProfile()
{
try
{
LiveAuthClient auth = new LiveAuthClient();
LiveLoginResult loginResult = await auth.LoginAsync(new string[] { "wl.basic" });
if (loginResult.Status == LiveConnectSessionStatus.Connected)
{
this.pageTitle.Text = "Signed in.";
}
}
catch (LiveAuthException exception)
{
this.pageTitle.Text = "Error signing in: " + exception.Message;
}
}
And the exception says:
I finally found a solution.
Subscribe to a button-click event or whatever, then use this code:
LoadProfile();
which calls this method:
public async void LoadProfile()
{
try
{
LiveAuthClient auth = new LiveAuthClient();
LiveLoginResult initializeResult = await auth.InitializeAsync();
try
{
LiveLoginResult loginResult = await auth.LoginAsync(new string[] { "wl.basic" });
if (loginResult.Status == LiveConnectSessionStatus.Connected)
{
LiveConnectClient connect = new LiveConnectClient(auth.Session);
LiveOperationResult operationResult = await connect.GetAsync("me");
dynamic result = operationResult.Result;
if (result != null)
{
this.pageTitle.Text = string.Join(" ", "Hello", result.name, "!");
}
else
{
this.pageTitle.Text = "Error getting name.";
}
}
}
catch (LiveAuthException exception)
{
this.pageTitle.Text = "Error signing in: " + exception.Message;
}
catch (LiveConnectException exception)
{
this.pageTitle.Text = "Error calling API: " + exception.Message;
}
}
catch (LiveAuthException exception)
{
this.pageTitle.Text = "Error initializing: " + exception.Message;
}
}
Before you debug, add your app to the Windows Store Dashboard. Then go back to Visual Studio, find Package.appxmanifest in Solution Explorer and add the Internet Capability. Then go to the Project menu > Store > Associate App with the Store.
Find your app's name in the list of apps that appears, select it and click Next/Finish and then debug. It should now be working.
Please try this code instead of yours:
LiveAuthClient auth = new LiveAuthClient();
LiveLoginResult loginResult = await auth.InitializeAsync(new string[] { "wl.basic" });
if ( loginResult.Status == LiveConnectSessionStatus.Connected )
{
LiveConnectClient connect = new LiveConnectClient( auth.Session );
...

FacebookOAuthException was unhandled

I'm new in these things and I've been testing the api ...
and came to me a situation that is:
if the user changes the password of Facebook
the Access token is renewed ... and try to post the API Launches
an exception and the application crashes...
how to resolve this situation?
try {
FacebookApp app = new FacebookApp(FacebookToken);
var args = new Dictionary<string, object>();
args["message"] = "hi";
args["caption"] = "appcaption";
args["description"] = "appdescription";
args["name"] = "appname";
args["picture"] = "apppicture";
args["link"] = "applink";
app.ApiAsync((X) => { calback(X); }, null, "/me/feed", args, HttpMethod.Post);
}
catch (Exception ex) {
Uri url = new Uri("/MyFacebook.xaml", UriKind.Relative);
NavigationService.Navigate(url);
}
this is Api code, and it's crashing when throwing the OAuthExcepion at the line marked with "Exception HERE"
private static void ResponseCallback(IAsyncResult asyncResult, FacebookAsyncCallback callback, object state)
{
object result = null;
FacebookApiException exception = null;
try
{
var request = (HttpWebRequest)asyncResult.AsyncState;
var response = (HttpWebResponse)request.EndGetResponse(asyncResult);
using (Stream responseStream = response.GetResponseStream())
{
result = JsonSerializer.DeserializeObject(responseStream);
}
}
catch (FacebookApiException)
{
// Rest API Errors
throw;
}
catch (WebException ex)
{
// Graph API Errors or general web exceptions
exception = ExceptionFactory.GetGraphException(ex);
if (exception != null)
{
// Thow the FacebookApiException
throw exception;
}
throw; //Exception HERE
}
finally
{
// Check to make sure there hasn't been an exception.
// If there has, we want to pass null to the callback.
object data = null;
if (exception == null)
{
data = result;
}
#if SILVERLIGHT
callback(new FacebookAsyncResult(data, state, null, asyncResult.CompletedSynchronously, asyncResult.IsCompleted, exception));
#else
callback(new FacebookAsyncResult(data, state, asyncResult.AsyncWaitHandle, asyncResult.CompletedSynchronously, asyncResult.IsCompleted, exception));
#endif
}
}
thanks
The behavior of the SDK is intended. An exception is not "crashing" the application, but rather telling you when an error state has occurred. You are basically doing it correctly, but instead of catching Exception you should only catch FacebookOAuthException like this:
try {
FacebookApp app = new FacebookApp(FacebookToken);
var args = new Dictionary<string, object>();
args["message"] = "hi";
args["caption"] = "appcaption";
args["description"] = "appdescription";
args["name"] = "appname";
args["picture"] = "apppicture";
args["link"] = "applink";
app.ApiAsync("/me/feed", args, (X) => { calback(X); }, HttpMethod.Post);
}
catch (FacebookOAuthException) {
// This is where you would reauthorize the user or send them to a 'login' page
Uri url = new Uri("/MyFacebook.xaml", UriKind.Relative);
NavigationService.Navigate(url);
}
I would also suggest reading up on .Net exception handling to give you a better understanding of when and why they are used. http://msdn.microsoft.com/en-us/library/ms229005.aspx
Using the FacebookAuthenticationResult you can check if there was an error and then avoid to do the request:
private void FacebookLoginBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
FacebookAuthenticationResult authResult;
if (FacebookAuthenticationResult.TryParse(e.Uri, out authResult))
{
if (authResult.ErrorReason == "user_denied")
{
// Do something knowing that this failed (cancel). }
else
{
fbApp.Session = authResult.ToSession();
loginSucceeded();
}
}
}
Have you seen this post? http://dotnetslackers.com/articles/net/wFace-windows-phone-7-facebook-integration-part-1.aspx
Specifically, take a look at part 3 - http://dotnetslackers.com/articles/net/wp7Gesicht-windows-phone-7-facebook-integration-part-3.aspx
Could you store the access token, and then on error, show the login page again?

Categories

Resources