Как обработка исключений работает с jquery и asp.net mvc? - PullRequest
0 голосов
/ 13 сентября 2009

Я играл с моим кодом и хотел посмотреть, что произойдет, если я сделаю это.

Я загружаю свою страницу mvc asp.net, затем захожу в базу данных mssql 2005 и нажимаю pause. Затем я нажимаю на ссылку с запросом jquery ajax.

Это относится к методу в моем контроллере (скажем, это тип JsonResult), для него установлен ActionVerb с атрибутом «Post» и атрибутом Authentication.

Теперь в моем коде у меня есть оператор catch SqlExpection, который должен перехватить все исключения SqlException, а затем вернуть результат json с общим сообщением с надписью «database down».

Таким образом, пользователь знает, что происходит, но не выдается потенциальное сообщение об ошибке, которое может дать хакеру информацию о том, почему база данных вышла из строя.

Итак, я ожидал, что появится мое сообщение об ошибке. но вместо этого я смотрю в ответ и получаю это огромное длинное сообщение: «База данных приостановлена, и это, и это не удалось».

Так что в основном все, о чем я не хочу, чтобы пользователь знал. К счастью, он не отображается в моем контейнере сообщений, поскольку он не выглядит как JsonResult, но любой, у кого есть firebug, увидит его.

Так что это даже не входит в мой метод. Так что должно быть какое-то другое место, где происходит эта ошибка.

Так почему мое исключение не уловило это? Это из-за моих атрибутов? Поскольку, похоже, он никогда не входит в метод вообще.

Спасибо

Вот часть трассировки стека того, что возвращается.

<code> <b>Stack Trace:</b> <br><br>

            <table width=100% bgcolor="#ffffcc">
               <tr>
                  <td>
                      <code><pre>

[SqlException (0x80131904): SQL Server service has been paused. No new connections will be allowed. To resume the service, use SQL Computer Manager or the Services application in Control Panel.
Login failed for user 'myPc'.
A severe error occurred on the current command.  The results, if any, should be discarded.]
   System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) +1951450
   System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) +4849003
   System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) +194
   System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +2394
   System.Data.SqlClient.SqlDataReader.ConsumeMetaData() +33
   System.Data.SqlClient.SqlDataReader.get_MetaData() +83
   System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +297
   System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +954
   System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +162
   System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) +32
   System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) +141
   System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior) +70
   System.Web.Security.SqlRoleProvider.GetRolesForUser(String username) +760
   System.Web.Security.RolePrincipal.IsInRole(String role) +164
   System.Linq.Enumerable.Any(IEnumerable`1 source, Func`2 predicate) +159
   System.Web.Mvc.AuthorizeAttribute.AuthorizeCore(HttpContextBase httpContext) +218
   System.Web.Mvc.AuthorizeAttribute.OnAuthorization(AuthorizationContext filterContext) +35
   System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor) +99
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +399
   System.Web.Mvc.Controller.ExecuteCore() +126
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +27
   System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +7
   System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext) +151
   System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext httpContext) +57
   System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext) +7
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously) +75

Ответы [ 2 ]

1 голос
/ 13 сентября 2009

Я полагаю, что ваш блок try / catch находится в методе действия, но сбой происходит до того, как действие выполнится. В частности, я думаю, что ошибка в методе AuthorizeCore, где вы делаете вызов GetRolesForUser.

Этот код может быть предоставлен MVC, и меня не удивит, если не будут приняты адекватные меры безопасности для доступа к данным. В худшем случае: вам может понадобиться создать собственный атрибут Authorize и переопределить его метод AuthorizeCore или переопределить метод OnAuthorization для расширяемого контроллера.

Чтобы создать собственный атрибут авторизации:

public class MyAuthorizeAttribute: AuthorizeAttribute
{
  protected override bool AuthorizeCore(HttContextBase httpContext)
  {
    var isAuthorized = //your code here;
    return isAuthorized;
  }
}

Теперь вы можете использовать этот атрибут вместо Авторизации, например:

[MyAuthorize(Roles = "Admin")]
public ViewResult MyAction()
{
  ...
}

Чтобы переопределить метод OnAuthorization контроллера:

protected void OnAuthorization(AuthorizationContext filterContext)
{
  var isAuthorized = //your code here;

  if(!isAuthorized) 
  {
    filterContext.Result = new HttpUnauthorizedResult();
  }
}

РЕДАКТИРОВАТЬ : Это устраняет проблему грязного исключения, отправляемого обратно клиенту. Что не помогает, так это ваша способность перехватить это исключение и вернуть что-то значимое обратно (например, база данных не работает). Проблема в том, что мы можем зафиксировать тот факт, что база данных не работает в методе Authorize, и именно здесь мы должны указать, что пользователь не авторизован. Однако из-за того, что пользователь не авторизован, метод действия не сработает, и поэтому ваша возможность вернуть что-либо клиенту ограничена.

Из-за отсутствия лучшего способа обработки этого, вы можете разрешить пользователю вход через OnAuthorizationMethod, но когда вы делаете это, вы можете установить для свойства класса известное значение. Когда вы вводите метод действия, вы можете проверить это значение и действовать в этой точке. Это взлом, и ваш пробег будет варьироваться ...

Кроме того, вы можете добавить атрибут [HandleError (View = "...")] к вашему методу действия. Я не знаю, срабатывает ли это при запуске в результате ошибки на этапе Авторизации, и это не вернет JSONResult, и вы намеревались.

1 голос
/ 13 сентября 2009

Звучит так, как будто вы видите исключение, которое идет с помощью stracktrace (установите для debug значение true в web.config), оно должно указать тип исключения (возможно, вы перехватываете неправильный тип, как предлагает Дэвид Андрес), и оно будет также содержат номера строк из стека, указывающие, куда они выбрасываются.

p.s. в вашем "вопросе" нет вопросов или даже вопросительных знаков, поэтому я предполагаю, что это то, что вы ищете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...