mirror of
https://github.com/danieleteti/delphimvcframework.git
synced 2024-11-15 15:55:54 +01:00
Filters (WIP) - improved exception handling separation between router filter and action filter
This commit is contained in:
parent
4e380e6ebd
commit
d76c07ece0
@ -365,6 +365,10 @@ type
|
|||||||
class function ReasonStringFor(const HTTPStatusCode: Integer): String; static;
|
class function ReasonStringFor(const HTTPStatusCode: Integer): String; static;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
EMVCRouteNotFound = class(Exception)
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
EMVCException = class(Exception)
|
EMVCException = class(Exception)
|
||||||
protected
|
protected
|
||||||
FHttpErrorCode: UInt16;
|
FHttpErrorCode: UInt16;
|
||||||
|
@ -105,378 +105,97 @@ end;
|
|||||||
|
|
||||||
procedure TMVCRouterFilter.DoFilter(Context: TWebContext);
|
procedure TMVCRouterFilter.DoFilter(Context: TWebContext);
|
||||||
var
|
var
|
||||||
lSelectedController: TMVCController;
|
|
||||||
lRouter: IMVCRouter;
|
lRouter: IMVCRouter;
|
||||||
lParamsTable: TMVCRequestParamsTable;
|
lParamsTable: TMVCRequestParamsTable;
|
||||||
begin
|
begin
|
||||||
lParamsTable := TMVCRequestParamsTable.Create;
|
lParamsTable := TMVCRequestParamsTable.Create;
|
||||||
try
|
try
|
||||||
lRouter := TMVCRouter.Create(FConfig, fEngine.gMVCGlobalActionParamsCache);
|
lRouter := TMVCRouter.Create(FConfig, fEngine.gMVCGlobalActionParamsCache);
|
||||||
lSelectedController := nil;
|
try
|
||||||
try // only for lSelectedController
|
if lRouter.TryFindRoute(
|
||||||
try // global exception handler
|
Context.Request.PathInfo,
|
||||||
if lRouter.TryFindRoute(
|
Context.Request.GetOverwrittenHTTPMethod,
|
||||||
Context.Request.PathInfo,
|
Context.Request.ContentType,
|
||||||
Context.Request.GetOverwrittenHTTPMethod { lContext.Request.HTTPMethod } ,
|
Context.Request.Accept,
|
||||||
Context.Request.ContentType,
|
fControllers,
|
||||||
Context.Request.Accept,
|
fConfigCache_DefaultContentType,
|
||||||
fControllers,
|
fConfigCache_DefaultContentCharset,
|
||||||
fConfigCache_DefaultContentType,
|
fConfigCache_PathPrefix,
|
||||||
fConfigCache_DefaultContentCharset,
|
lParamsTable) then
|
||||||
fConfigCache_PathPrefix,
|
|
||||||
lParamsTable) then
|
|
||||||
begin
|
|
||||||
// lRouterMethodToCallName := lRouter.ActionMethod.Name;
|
|
||||||
// lRouterControllerClazzQualifiedClassName := lRouter.ControllerClazz.QualifiedClassName;
|
|
||||||
MVCFramework.Logger.InitThreadVars;
|
|
||||||
Context.ParamsTable := lParamsTable;
|
|
||||||
fControllerFilterChain.Execute(Context, lRouter);
|
|
||||||
end
|
|
||||||
else // execute-routing
|
|
||||||
begin
|
|
||||||
if fConfig[TMVCConfigKey.AllowUnhandledAction] = 'false' then
|
|
||||||
begin
|
|
||||||
Context.Response.StatusCode := http_status.NotFound;
|
|
||||||
Context.Response.ReasonString := 'Not Found';
|
|
||||||
//fOnRouterLog(lRouter, rlsRouteNotFound, lContext);
|
|
||||||
raise EMVCException.Create(Context.Response.ReasonString, Context.Request.HTTPMethodAsString + ' ' +
|
|
||||||
Context.Request.PathInfo, 0, http_status.NotFound);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
Context.Response.FlushOnDestroy := False;
|
|
||||||
end;
|
|
||||||
end; // end-execute-routing
|
|
||||||
except
|
|
||||||
// on ESess: EMVCSessionExpiredException do
|
|
||||||
// begin
|
|
||||||
// if not fEngine.CustomExceptionHandling(ESess, lSelectedController, Context) then
|
|
||||||
// begin
|
|
||||||
// Log.Error('[%s] %s [PathInfo "%s"] (Custom message: "%s")',
|
|
||||||
// [ESess.Classname, ESess.Message, GetRequestShortDescription(Context.Request.RawWebRequest), ESess.DetailedMessage],
|
|
||||||
// LOGGERPRO_TAG);
|
|
||||||
// Context.SessionStop;
|
|
||||||
// lSelectedController.ResponseStatus(ESess.HTTPErrorCode);
|
|
||||||
// lSelectedController.Render(ESess);
|
|
||||||
// end;
|
|
||||||
// end;
|
|
||||||
// on E: EMVCException do
|
|
||||||
// begin
|
|
||||||
// if not fEngine.CustomExceptionHandling(E, lSelectedController, Context) then
|
|
||||||
// begin
|
|
||||||
// Log.Error('[%s] %s [PathInfo "%s"] (Custom message: "%s")',
|
|
||||||
// [E.Classname, E.Message, GetRequestShortDescription(Context.Request.RawWebRequest), E.DetailedMessage], LOGGERPRO_TAG);
|
|
||||||
// if Assigned(lSelectedController) then
|
|
||||||
// begin
|
|
||||||
// lSelectedController.ResponseStatus(E.HTTPErrorCode);
|
|
||||||
// lSelectedController.Render(E);
|
|
||||||
// end
|
|
||||||
// else
|
|
||||||
// begin
|
|
||||||
// fEngine.SendRawHTTPStatus(Context, E.HTTPErrorCode, Format('[%s] %s', [E.Classname, E.Message]), E.Classname);
|
|
||||||
// end;
|
|
||||||
// end;
|
|
||||||
// end;
|
|
||||||
// on EIO: EInvalidOp do
|
|
||||||
// begin
|
|
||||||
// if not fEngine.CustomExceptionHandling(EIO, lSelectedController, Context) then
|
|
||||||
// begin
|
|
||||||
// Log.Error('[%s] %s [PathInfo "%s"] (Custom message: "%s")',
|
|
||||||
// [EIO.Classname, EIO.Message, GetRequestShortDescription(Context.Request.RawWebRequest), 'Invalid Op'], LOGGERPRO_TAG);
|
|
||||||
// if Assigned(lSelectedController) then
|
|
||||||
// begin
|
|
||||||
// lSelectedController.ResponseStatus(http_status.InternalServerError);
|
|
||||||
// lSelectedController.Render(EIO);
|
|
||||||
// end
|
|
||||||
// else
|
|
||||||
// begin
|
|
||||||
// fEngine.SendRawHTTPStatus(Context, http_status.InternalServerError,
|
|
||||||
// Format('[%s] %s', [EIO.Classname, EIO.Message]), EIO.Classname);
|
|
||||||
// end;
|
|
||||||
// end;
|
|
||||||
// end;
|
|
||||||
on Ex: Exception do
|
|
||||||
begin
|
begin
|
||||||
if not fEngine.CustomExceptionHandling(Ex, lSelectedController, Context) then
|
MVCFramework.Logger.InitThreadVars;
|
||||||
|
Context.ParamsTable := lParamsTable;
|
||||||
|
fControllerFilterChain.Execute(Context, lRouter);
|
||||||
|
end
|
||||||
|
else // execute-routing
|
||||||
|
begin
|
||||||
|
if fConfig[TMVCConfigKey.AllowUnhandledAction] = 'false' then
|
||||||
begin
|
begin
|
||||||
Log.Error('[%s] %s [PathInfo "%s"] (Custom message: "%s")',
|
Context.Response.StatusCode := http_status.NotFound;
|
||||||
[Ex.Classname, Ex.Message, GetRequestShortDescription(Context.Request.RawWebRequest), 'Global Action Exception Handler'],
|
Context.Response.ReasonString := 'Not Found';
|
||||||
LOGGERPRO_TAG);
|
//fOnRouterLog(lRouter, rlsRouteNotFound, lContext);
|
||||||
if Assigned(lSelectedController) then
|
raise EMVCRouteNotFound.CreateFmt('"%s %s" - not found',[Context.Request.HTTPMethodAsString, Context.Request.PathInfo]);
|
||||||
begin
|
end
|
||||||
lSelectedController.ResponseStatus(http_status.InternalServerError);
|
else
|
||||||
lSelectedController.Render(Ex);
|
begin
|
||||||
end
|
Context.Response.FlushOnDestroy := False;
|
||||||
else
|
|
||||||
begin
|
|
||||||
fEngine.SendRawHTTPStatus(Context, http_status.InternalServerError,
|
|
||||||
Format('[%s] %s', [Ex.Classname, Ex.Message]), Ex.Classname);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
end; // end-execute-routing
|
||||||
|
except
|
||||||
|
on Ex: EMVCException do
|
||||||
|
begin
|
||||||
|
if not fEngine.CustomExceptionHandling(Ex, nil, Context) then
|
||||||
|
begin
|
||||||
|
Log.Error('[%s] %s [PathInfo "%s"] [%s]',
|
||||||
|
[
|
||||||
|
Ex.Classname,
|
||||||
|
Ex.Message,
|
||||||
|
GetRequestShortDescription(Context.Request.RawWebRequest),
|
||||||
|
ClassName
|
||||||
|
],
|
||||||
|
LOGGERPRO_TAG);
|
||||||
|
fEngine.SendRawHTTPStatus(Context, Ex.HttpErrorCode,
|
||||||
|
Format('[%s] %s', [Ex.Classname, Ex.Message]), Ex.Classname);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
on Ex: EMVCRouteNotFound do
|
||||||
|
begin
|
||||||
|
if not fEngine.CustomExceptionHandling(Ex, nil, Context) then
|
||||||
|
begin
|
||||||
|
Log.Error('[%s] %s [PathInfo "%s"] [%s]',
|
||||||
|
[
|
||||||
|
Ex.Classname,
|
||||||
|
Ex.Message,
|
||||||
|
GetRequestShortDescription(Context.Request.RawWebRequest),
|
||||||
|
ClassName
|
||||||
|
],
|
||||||
|
LOGGERPRO_TAG);
|
||||||
|
fEngine.SendRawHTTPStatus(
|
||||||
|
Context,
|
||||||
|
HTTP_STATUS.NotFound,
|
||||||
|
Format('[%s] %s', [Ex.Classname, Ex.Message]), Ex.Classname);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
on Ex: Exception do
|
||||||
|
begin
|
||||||
|
if not fEngine.CustomExceptionHandling(Ex, nil, Context) then
|
||||||
|
begin
|
||||||
|
Log.Error('[%s] %s [PathInfo "%s"] [%s]',
|
||||||
|
[
|
||||||
|
Ex.Classname,
|
||||||
|
Ex.Message,
|
||||||
|
GetRequestShortDescription(Context.Request.RawWebRequest),
|
||||||
|
ClassName
|
||||||
|
],
|
||||||
|
LOGGERPRO_TAG);
|
||||||
|
fEngine.SendRawHTTPStatus(Context, http_status.InternalServerError,
|
||||||
|
Format('[%s] %s', [Ex.Classname, Ex.Message]), Ex.Classname);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
finally
|
|
||||||
FreeAndNil(lSelectedController);
|
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
lParamsTable.Free;
|
lParamsTable.Free;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
//procedure TMVCRouterFilter.FillActualParamsForAction(
|
|
||||||
// const ASelectedController: TMVCController; const AContext: TWebContext;
|
|
||||||
// const AActionFormalParams: TArray<TRttiParameter>; const AActionName: string;
|
|
||||||
// var AActualParams: TArray<TValue>; out ABodyParameter: TObject);
|
|
||||||
//var
|
|
||||||
// lParamName: string;
|
|
||||||
// I: Integer;
|
|
||||||
// lStrValue: string;
|
|
||||||
// lFromBodyAttribute: MVCFromBodyAttribute;
|
|
||||||
// lFromQueryStringAttribute: MVCFromQueryStringAttribute;
|
|
||||||
// lFromHeaderAttribute: MVCFromHeaderAttribute;
|
|
||||||
// lFromCookieAttribute: MVCFromCookieAttribute;
|
|
||||||
// lAttributeInjectedParamCount: Integer;
|
|
||||||
// lInjectedParamValue: string;
|
|
||||||
// lList: IMVCList;
|
|
||||||
// lItemClass: TClass;
|
|
||||||
//begin
|
|
||||||
// ABodyParameter := nil;
|
|
||||||
// lAttributeInjectedParamCount := 0;
|
|
||||||
// SetLength(AActualParams, Length(AActionFormalParams));
|
|
||||||
// for I := 0 to Length(AActionFormalParams) - 1 do
|
|
||||||
// begin
|
|
||||||
// lParamName := AActionFormalParams[I].name;
|
|
||||||
// if Length(AActionFormalParams[I].GetAttributes) > 0 then
|
|
||||||
// begin
|
|
||||||
// // Let's check how to inject this parameter
|
|
||||||
// if TRttiUtils.HasAttribute<MVCFromBodyAttribute>(AActionFormalParams[I], lFromBodyAttribute)
|
|
||||||
// then
|
|
||||||
// begin
|
|
||||||
// Inc(lAttributeInjectedParamCount, 1);
|
|
||||||
// if AActionFormalParams[I].ParamType.QualifiedName <> 'System.string' then
|
|
||||||
// begin
|
|
||||||
// ABodyParameter := TRttiUtils.CreateObject(AActionFormalParams[I].ParamType.QualifiedName);
|
|
||||||
// if TDuckTypedList.CanBeWrappedAsList(ABodyParameter, lList) then
|
|
||||||
// begin
|
|
||||||
// lItemClass := TMVCAbstractSerializer(ASelectedController.Serializer).GetObjectTypeOfGenericList(ABodyParameter.ClassInfo);
|
|
||||||
// ASelectedController.Serializer.DeserializeCollection(AContext.Request.Body,
|
|
||||||
// ABodyParameter, lItemClass, stDefault, [], lFromBodyAttribute.RootNode);
|
|
||||||
// end
|
|
||||||
// else
|
|
||||||
// begin
|
|
||||||
// ASelectedController.Serializer.DeserializeObject(AContext.Request.Body,
|
|
||||||
// ABodyParameter, stDefault, [], lFromBodyAttribute.RootNode);
|
|
||||||
// end;
|
|
||||||
// AActualParams[I] := ABodyParameter;
|
|
||||||
// end
|
|
||||||
// else
|
|
||||||
// begin
|
|
||||||
// AActualParams[I] := AContext.Request.Body;
|
|
||||||
// Continue;
|
|
||||||
// end;
|
|
||||||
// end
|
|
||||||
// else if TRttiUtils.HasAttribute<MVCFromQueryStringAttribute>(AActionFormalParams[I],
|
|
||||||
// lFromQueryStringAttribute) then
|
|
||||||
// begin
|
|
||||||
// Inc(lAttributeInjectedParamCount, 1);
|
|
||||||
// lInjectedParamValue := AContext.Request.QueryStringParam
|
|
||||||
// (lFromQueryStringAttribute.ParamName);
|
|
||||||
// HandleDefaultValueForInjectedParameter(lInjectedParamValue, lFromQueryStringAttribute);
|
|
||||||
// AActualParams[I] := GetActualParam(AActionFormalParams[I], lInjectedParamValue);
|
|
||||||
// end
|
|
||||||
// else if TRttiUtils.HasAttribute<MVCFromHeaderAttribute>(AActionFormalParams[I],
|
|
||||||
// lFromHeaderAttribute) then
|
|
||||||
// begin
|
|
||||||
// Inc(lAttributeInjectedParamCount, 1);
|
|
||||||
// lInjectedParamValue := AContext.Request.GetHeader(lFromHeaderAttribute.ParamName);
|
|
||||||
// HandleDefaultValueForInjectedParameter(lInjectedParamValue, lFromHeaderAttribute);
|
|
||||||
// AActualParams[I] := GetActualParam(AActionFormalParams[I], lInjectedParamValue);
|
|
||||||
// end
|
|
||||||
// else if TRttiUtils.HasAttribute<MVCFromCookieAttribute>(AActionFormalParams[I],
|
|
||||||
// lFromCookieAttribute) then
|
|
||||||
// begin
|
|
||||||
// Inc(lAttributeInjectedParamCount, 1);
|
|
||||||
// lInjectedParamValue := AContext.Request.Cookie(lFromCookieAttribute.ParamName);
|
|
||||||
// HandleDefaultValueForInjectedParameter(lInjectedParamValue, lFromCookieAttribute);
|
|
||||||
// AActualParams[I] := GetActualParam(AActionFormalParams[I], lInjectedParamValue);
|
|
||||||
// end
|
|
||||||
// else
|
|
||||||
// begin
|
|
||||||
// raise EMVCException.Create(http_status.InternalServerError,
|
|
||||||
// 'Unknown custom attribute on action parameter: ' + AActionFormalParams[I].name +
|
|
||||||
// '. [HINT: Allowed attributes are MVCFromBody, MVCFromQueryString, MVCFromHeader, MVCFromCookie]');
|
|
||||||
// end;
|
|
||||||
// Continue;
|
|
||||||
// end;
|
|
||||||
//
|
|
||||||
// // From now on we'll check for url mapped parameters
|
|
||||||
// if not AContext.Request.SegmentParam(lParamName, lStrValue) then
|
|
||||||
// raise EMVCException.CreateFmt(http_status.BadRequest,
|
|
||||||
// 'Invalid parameter %s for action %s (Hint: Here parameters names are case-sensitive)',
|
|
||||||
// [lParamName, AActionName]);
|
|
||||||
// AActualParams[I] := GetActualParam(AActionFormalParams[I], lStrValue);
|
|
||||||
// end;
|
|
||||||
//
|
|
||||||
// if (AContext.Request.SegmentParamsCount + lAttributeInjectedParamCount) <>
|
|
||||||
// Length(AActionFormalParams) then
|
|
||||||
// raise EMVCException.CreateFmt(http_status.BadRequest,
|
|
||||||
// 'Parameters count mismatch (expected %d actual %d) for action "%s"',
|
|
||||||
// [Length(AActionFormalParams), AContext.Request.SegmentParamsCount, AActionName]);
|
|
||||||
//end;
|
|
||||||
|
|
||||||
//procedure TMVCRouterFilter.HandleDefaultValueForInjectedParameter(var InjectedParamValue: String;
|
|
||||||
// const InjectableParamAttribute: MVCInjectableParamAttribute);
|
|
||||||
//begin
|
|
||||||
// if InjectedParamValue.IsEmpty then
|
|
||||||
// begin
|
|
||||||
// if InjectableParamAttribute.CanBeUsedADefaultValue then
|
|
||||||
// begin
|
|
||||||
// InjectedParamValue := InjectableParamAttribute.DefaultValueAsString;
|
|
||||||
// end
|
|
||||||
// else
|
|
||||||
// begin
|
|
||||||
// raise EMVCException.CreateFmt
|
|
||||||
// ('Required parameter "%s" injected using "%s" has not provided and cannot be used a default value for it',
|
|
||||||
// [InjectableParamAttribute.ParamName, InjectableParamAttribute.Classname]);
|
|
||||||
// end;
|
|
||||||
// end;
|
|
||||||
//end;
|
|
||||||
|
|
||||||
//function TMVCRouterFilter.GetActualParam(const AFormalParam: TRttiParameter;
|
|
||||||
// const AStringValue: String): TValue;
|
|
||||||
// var lWasDateTime: Boolean; lQualifiedName: String;
|
|
||||||
// lFormatSettings: TFormatSettings;
|
|
||||||
//begin
|
|
||||||
// case AFormalParam.ParamType.TypeKind of
|
|
||||||
// tkInteger:
|
|
||||||
// try
|
|
||||||
// Result := StrToInt(AStringValue);
|
|
||||||
// except
|
|
||||||
// on E: Exception do
|
|
||||||
// begin
|
|
||||||
// raise EMVCException.CreateFmt(http_status.BadRequest,
|
|
||||||
// 'Invalid Integer value for param [%s] - [CLASS: %s][MSG: %s]',
|
|
||||||
// [AFormalParam.name, E.Classname, E.Message]);
|
|
||||||
// end;
|
|
||||||
// end;
|
|
||||||
// tkInt64:
|
|
||||||
// try
|
|
||||||
// Result := StrToInt64(AStringValue);
|
|
||||||
// except
|
|
||||||
// on E: Exception do
|
|
||||||
// begin
|
|
||||||
// raise EMVCException.CreateFmt(http_status.BadRequest,
|
|
||||||
// 'Invalid Int64 value for param [%s] - [CLASS: %s][MSG: %s]',
|
|
||||||
// [AFormalParam.name, E.Classname, E.Message]);
|
|
||||||
// end;
|
|
||||||
// end;
|
|
||||||
// tkUString:
|
|
||||||
// begin
|
|
||||||
// Result := AStringValue;
|
|
||||||
// end;
|
|
||||||
// tkFloat:
|
|
||||||
// begin
|
|
||||||
// lWasDateTime := False;
|
|
||||||
// lQualifiedName := AFormalParam.ParamType.QualifiedName;
|
|
||||||
// if lQualifiedName = 'System.TDate' then
|
|
||||||
// begin
|
|
||||||
// try
|
|
||||||
// lWasDateTime := True;
|
|
||||||
// Result := ISODateToDate(AStringValue);
|
|
||||||
// except
|
|
||||||
// on E: Exception do
|
|
||||||
// begin
|
|
||||||
// raise EMVCException.CreateFmt(http_status.BadRequest,
|
|
||||||
// 'Invalid TDate value for param [%s] - [CLASS: %s][MSG: %s]',
|
|
||||||
// [AFormalParam.name, E.Classname, E.Message]);
|
|
||||||
// end;
|
|
||||||
// end;
|
|
||||||
// end
|
|
||||||
// else if lQualifiedName = 'System.TDateTime' then
|
|
||||||
// begin
|
|
||||||
// try
|
|
||||||
// lWasDateTime := True;
|
|
||||||
// Result := ISOTimeStampToDateTime(AStringValue);
|
|
||||||
// except
|
|
||||||
// on E: Exception do
|
|
||||||
// begin
|
|
||||||
// raise EMVCException.CreateFmt(http_status.BadRequest,
|
|
||||||
// 'Invalid TDateTime value for param [%s] - [CLASS: %s][MSG: %s]',
|
|
||||||
// [AFormalParam.name, E.Classname, E.Message]);
|
|
||||||
// end;
|
|
||||||
// end;
|
|
||||||
// end
|
|
||||||
// else if lQualifiedName = 'System.TTime' then
|
|
||||||
// begin
|
|
||||||
// try
|
|
||||||
// lWasDateTime := True;
|
|
||||||
// Result := ISOTimeToTime(AStringValue);
|
|
||||||
// except
|
|
||||||
// on E: Exception do
|
|
||||||
// begin
|
|
||||||
// raise EMVCException.CreateFmt(http_status.BadRequest,
|
|
||||||
// 'Invalid TTime value for param [%s] - [CLASS: %s][MSG: %s]',
|
|
||||||
// [AFormalParam.name, E.Classname, E.Message]);
|
|
||||||
// end;
|
|
||||||
// end;
|
|
||||||
// end;
|
|
||||||
// if not lWasDateTime then
|
|
||||||
// try
|
|
||||||
// lFormatSettings.DecimalSeparator := '.';
|
|
||||||
// Result := StrToFloat(AStringValue, lFormatSettings);
|
|
||||||
// except
|
|
||||||
// on E: Exception do
|
|
||||||
// begin
|
|
||||||
// raise EMVCException.CreateFmt(http_status.BadRequest,
|
|
||||||
// 'Invalid Float value for param [%s] - [CLASS: %s][MSG: %s]',
|
|
||||||
// [AFormalParam.name, E.Classname, E.Message]);
|
|
||||||
// end;
|
|
||||||
// end;
|
|
||||||
// end;
|
|
||||||
// tkEnumeration:
|
|
||||||
// begin
|
|
||||||
// if AFormalParam.ParamType.QualifiedName = 'System.Boolean' then
|
|
||||||
// begin
|
|
||||||
// if SameText(AStringValue, 'true') or SameText(AStringValue, '1') then
|
|
||||||
// Result := True
|
|
||||||
// else if SameText(AStringValue, 'false') or SameText(AStringValue, '0') then
|
|
||||||
// Result := False
|
|
||||||
// else
|
|
||||||
// begin
|
|
||||||
// raise EMVCException.CreateFmt(http_status.BadRequest,
|
|
||||||
// 'Invalid boolean value for parameter %s. Boolean parameters accepts only "true"/"false" or "1"/"0".',
|
|
||||||
// [AFormalParam.name]);
|
|
||||||
// end;
|
|
||||||
// end
|
|
||||||
// else
|
|
||||||
// begin
|
|
||||||
// raise EMVCException.CreateFmt(http_status.BadRequest,
|
|
||||||
// 'Invalid type for parameter %s. Allowed types are ' +
|
|
||||||
// ALLOWED_TYPED_ACTION_PARAMETERS_TYPES, [AFormalParam.name]);
|
|
||||||
// end;
|
|
||||||
// end;
|
|
||||||
// tkRecord:
|
|
||||||
// begin
|
|
||||||
// if AFormalParam.ParamType.QualifiedName = 'System.TGUID' then
|
|
||||||
// begin
|
|
||||||
// try
|
|
||||||
// Result := TValue.From<TGUID>(TMVCGuidHelper.StringToGUIDEx(AStringValue));
|
|
||||||
// except
|
|
||||||
// raise EMVCException.CreateFmt('Invalid Guid value for param [%s]', [AFormalParam.name]);
|
|
||||||
// end;
|
|
||||||
// end
|
|
||||||
// else
|
|
||||||
// raise EMVCException.CreateFmt('Invalid type for parameter %s. Allowed types are ' +
|
|
||||||
// ALLOWED_TYPED_ACTION_PARAMETERS_TYPES, [AFormalParam.name]);
|
|
||||||
// end
|
|
||||||
// else
|
|
||||||
// begin
|
|
||||||
// raise EMVCException.CreateFmt(http_status.BadRequest,
|
|
||||||
// 'Invalid type for parameter %s. Allowed types are ' + ALLOWED_TYPED_ACTION_PARAMETERS_TYPES,
|
|
||||||
// [AFormalParam.name]);
|
|
||||||
// end;
|
|
||||||
// end;
|
|
||||||
//end;
|
|
||||||
|
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -1079,7 +1079,7 @@ type
|
|||||||
function ExecuteAction(const ASender: TObject; const ARequest: TWebRequest;
|
function ExecuteAction(const ASender: TObject; const ARequest: TWebRequest;
|
||||||
const AResponse: TWebResponse): Boolean; virtual;
|
const AResponse: TWebResponse): Boolean; virtual;
|
||||||
public
|
public
|
||||||
function CustomExceptionHandling(const Ex: Exception; const ASelectedController: TMVCController;
|
function CustomExceptionHandling(const Ex: Exception; const AController: TMVCController;
|
||||||
const AContext: TWebContext): Boolean;
|
const AContext: TWebContext): Boolean;
|
||||||
class function GetCurrentSession(const ASessionId: string;
|
class function GetCurrentSession(const ASessionId: string;
|
||||||
const ARaiseExceptionIfExpired: Boolean = True): TWebSession; static;
|
const ARaiseExceptionIfExpired: Boolean = True): TWebSession; static;
|
||||||
@ -2452,12 +2452,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TMVCEngine.CustomExceptionHandling(const Ex: Exception;
|
function TMVCEngine.CustomExceptionHandling(const Ex: Exception;
|
||||||
const ASelectedController: TMVCController; const AContext: TWebContext): Boolean;
|
const AController: TMVCController; const AContext: TWebContext): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
if Assigned(FOnException) then
|
if Assigned(FOnException) then
|
||||||
begin
|
begin
|
||||||
FOnException(Ex, ASelectedController, AContext, Result);
|
FOnException(Ex, AController, AContext, Result);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -2659,7 +2659,7 @@ var
|
|||||||
res: IMVCRESTResponse;
|
res: IMVCRESTResponse;
|
||||||
begin
|
begin
|
||||||
res := RESTClient.Get('/typed/integer1/boom');
|
res := RESTClient.Get('/typed/integer1/boom');
|
||||||
Assert.isTrue(res.StatusCode = HTTP_STATUS.BadRequest, 'Cannot route');
|
Assert.AreEqual(HTTP_STATUS.BadRequest, res.StatusCode, 'Cannot route');
|
||||||
Assert.Contains(res.Content, 'EConvertError');
|
Assert.Contains(res.Content, 'EConvertError');
|
||||||
Assert.Contains(res.Content, '''boom'' is not a valid');
|
Assert.Contains(res.Content, '''boom'' is not a valid');
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user