Grails Hibernate Session or Spring Transaction destroying Domain validation errors - spring

So my problem is that my validation errors are being deleted from my domain object before I can render them on the page. I thought I had fixed this error in the past, but it has crept up on me again.
Here is a look at my original implementation. The errors were being cleared when tripService.stepData(trip) was being called.
Edit- I should not that I only experienced this issue when the page adds to a hasMany relationship.
Controller -
Trip trip = tripService.savePrePaymentInfo(params)
if (trip.hasErrors()) {
render(view: "step4", model: tripService.stepData(trip))
}
else {
redirect(action: trip.status.action, id:trip.id)
}
Service -
Map stepData(Trip trip)
{
Map returnSet = [:]
returnSet.status = Status.findAllByActionNotEqual("review")
returnSet.trip = trip
returnSet
}
So I did some reading online and someone one on a forum post like 2 years ago said there was something in hibernate..possible bug... I don't know, but their suggestion worked. The suggestion was to wrap the controller in a withTransaction:
Trip.withTransaction {
//Controller code here
}
This has been working for me fine. The issue now is that I have a taglib in my view that calls tripService again. When that call is being made it is now clearing my validation errors. This is getting really frustrating. Does anyone have ANY idea on what I can do to resolve this?
Edit: Adding service method being called from taglib:
String findBannerName(Long pidm, String format = 'LFMI')
{
"abc"
//It really doesnt matter what is here - tried just returning this string and it produced the issue
}

Are you sure the trip.errors property is populated in the first place?
Also, which tripService method are you calling in the taglib?

Related

ASP.NET Core API POST parameter is always null from Firefox

In my Angular2 Application, I'm submitting a form and send data through POST API to dotnet core backend. I've created a new form, that is working fine with chrome, but on firefox, I'm receiving null in POST API parameter.
I'm all stuck what to search and how to?? I've checked every possible issue and didn't find anything, because App is working fine with chrome, all data is up to date and correct but a single form is not working on firefox.
Can anyone help me out what to do? because I'm totally stuck and have
no idea what to do??
My Endpoints are;
[HttpPost]
[Route("api/Intimation/SaveIntimation")]
public async Task<ActionResult> SaveIntimation([FromBody] ViewModelCreateIntimation objCreateIntimation)
{
if (objCreateIntimation == null || objCreateIntimation.objIntimation == null)
{
return Ok("null received");
}
// remaining code
}
my service on angular side
saveIntimation(intiModel) {
console.log(intiModel);
return this.httpClient.post<ViewModelResponse>(this.baseUrl + this._SubmitIntimationUrl, JSON.stringify(intiModel), { headers: this.configurations.getHeaderWithAuth() });
}
where this._SubmitIntimationUrl is "/api/Intimation/SaveIntimation", intiModel is object that I'm passing.
Controller function - Angular
this.intimationModel = this.admissionForm.value;
this.adminService.SubmitAdmissionIntimationService(this.createIntimationModel).subscribe(
(response) => {
this.responseModel = response;
// further process
},
(error) => {
this.notification.onClear();
this.notification.onError(this.errorHandler.handleError(error).error, Constants.MESSAGE_ERROR);
}
);
Data that is sending from service (Last place where I can check data)
The problem looks like it's because of the name of the parameter in your controller is different to that being passed up in the request.
In your controller, the parameter the framework is trying to bind to is called objCreateIntimation, but your request shows you're sending up objIntimation instead. As they have different names, the model binder has no idea that objIntimation should be bound to objCreateIntimation.
Give them both the same name, and that should fix it for you.
I went through same issue once, and It took almost a day to figure out the reason behind it,
do check your date pickers and its values, and make sure it is not null and its format is also correct. Because firefox is a bit strict in this matter and a litter change in datepicker makes it null.
hope it helps you.

Laravel Debugger showing duplicated queries

Does any one has an idea about this. I don't know why it is showing duplicated queries. I searched a lot, found one answer on stackoverflow, but didn't get proper answer. If anyone faced the same error then please let me know. Thank you
protected $_param;
public function __construct(Utility $utility)
{
$league = $utility->checkDomainController();
view()->share('league', $league);
$this->league = $league;
}
This is the code in controller. which shares league to all the views. But there is only one query in $league = $utility->checkDomainController();
Here is the checkDomainController
if(\Request::server('HTTP_HOST') == env('MAIN_DOMAIN'))
{
$leagueSlug = Route::current()->getParameter('league');
$league = League::where('url', $leagueSlug)->first();
}
else
{
$league = League::where('custom_domain', \Request::server('HTTP_HOST'))->first();
}
if(!$league)
{
//error page
}
return $league;
Anytime you call a property which relies on a related model in blade, Laravel executes a new query, unless you eager load and pass from the controller to the view the preloaded data.
This example you posted seems to me as a loop somewhere within your blade code. Maybe if you can share a bit more of the code related to the front-end, I can help you figure it out.

jQuery ajax post request doesn't work suddenly,

I have a jQuery ajax call in my ZF2 application. It just worked before. Suddenly it won't work anymore. Even when I put a non-existent action in the request, it doesn't give a server error like it did before. It just seems like it doesn't make the request.
There's absolutely no errors in the console. Everything works up until the point where I make the request. This is the function it's in:
$('.expand').click(function(){
var CCID = $(this).parent().attr('id');
CCID = parseInt(CCID);
console.log(CCID); // Works
if($.inArray(CCID,$expanded) > -1){
foldin(CCID);
} else {
console.log('Works up to here.'); // Works
$.post('admin/expand', {
id: CCID
},function(data){
console.log('Doesn\'t log this.'); // Doesn't work
if(data.hasOwnProperty('info')){
console.log('sup');
expand(data.info);
} else {
console.log('Can\'t find customer info.');
}
},'json');
}
});
Like I said before, absolutely no errors, and logs all the bits that I commented that do. Kind of hoping I made a stupid mistake and you can spot it. Been over it a bunch of times already, can't find it.
I'll add the action in my controller if anyone want to see it, but the post request doesn't even seem to look for it, because it doesn't give an error if I give it a bogus action.
edit: below is some extra information
So I added a failure handler at the request of a commenter, it returned:
failed [Object, "parseerror", SyntaxError]
In SyntaxError it says "unexpected token <", but there's none in the .js file and I can't find where it tells me what line/file it finds it in. That would help, probably.
This is the action I call in my controller. Doesn't seem to find it at all though:
public function expandAction(){
$request = $this->getRequest();
$response = $this->getResponse();
if($request->isPost()){
$post_data = $request->getPost();
$CCID = $post_data['id'];
$customer = $this->getCustomerTable()->getCustomer($CCID);
$response->setContent(\Zend\Json\Json::encode(array(
'info' => $customer,
)));
}
return $response;
}
Arun P Johny taught me to use the Network tab in Google Chrome developer tools to figure out the problem. From there I could see that the path 'admin/expand' should've been 'expand'.
Might be a bit of a localized answer but I feel that his advice to use the network tab was helpful enough to warrant an answer. Maybe it'll be helpful to someone else at some point.

ASP.NET MVC3 Fluent Validation Constructor hit multiple times per request

I have an ASP.NET MVC3 website setup using fluent validation and ninject. The validation code is working. However, I set a break point in the validation class constructor and I noticed that when I request my view that uses the validation the constructor gets hit multiple times. Based on very basic testing it seems that the number of times the constructor is hit is equal to the number of properties that exist on the object. Has anyone else come across something similar? Or can someone shed more insight on how this type of validation works behind the scenes? -Thanks
Here is the constructor...
public class PersonValidator : AbstractValidator<Person> {
public PersonValidator() {
RuleFor(x => x.Id).NotNull();
RuleFor(x => x.Name).Length(0, 10);
RuleFor(x => x.Email).EmailAddress();
RuleFor(x => x.Age).InclusiveBetween(18, 60);
}
}
Here are the libraries/resources that I am using (I just got the NuGet packages and configured everything based on the info from the two links below):
http://fluentvalidation.codeplex.com/wikipage?title=mvc
https://github.com/ninject/ninject.web.mvc.fluentvalidation
I figured out how to prevent this issue. Even though this solves my issue, I would like input from others on whether there are any consequences in doing this?
So on the second link you will see instructions on how to set up Ninject.
On the second step you need to apply the "InRequestScope()" extension method. Then the constructor will only be hit once per http request that uses your validator. That obviously means that only one instance of the validator object is created per http request, which makes sense to me. I don't know if there are any consequences to using this solution?
Bind(match.InterfaceType).To(match.ValidatorType).InRequestScope();
Resurrecting this thread.
I had the same problem with SimpleInjector. My solution was include LifeTime.Scoped on the collection register.
private static void WarmUpMediatrAndFluentValidation(this Container container)
{
var allAssemblies = GetAssemblies();
container.RegisterSingleton<IMediator, Mediator>();
container.Register(typeof(IRequestHandler<,>), allAssemblies);
RegisterHandlers(container, typeof(INotificationHandler<>), allAssemblies);
RegisterHandlers(container, typeof(IRequestExceptionAction<,>), allAssemblies);
RegisterHandlers(container, typeof(IRequestExceptionHandler<,,>), allAssemblies);
//Pipeline
container.Collection.Register(typeof(IPipelineBehavior<,>), new[]
{
typeof(RequestExceptionProcessorBehavior<,>),
typeof(RequestExceptionActionProcessorBehavior<,>),
typeof(RequestPreProcessorBehavior<,>),
typeof(RequestPostProcessorBehavior<,>),
typeof(PipelineBehavior<,>)
});
container.Collection.Register(typeof(IRequestPreProcessor<>), new[] {typeof(EmptyRequestPreProcessor<>)});
container.Collection.Register(typeof(IRequestPostProcessor<,>), new[] {typeof(EmptyRequestPostProcessor<,>)});
container.Register(() => new ServiceFactory(container.GetInstance), Lifestyle.Singleton);
container.Collection.Register(typeof(IValidator<>), allAssemblies, Lifestyle.Scoped);
}
container.Collection.Register(typeof(IValidator<>), allAssemblies, Lifestyle.Scoped); <- Workers fine for me, calling only once per request.

Applying form errors manually

I have a situation where I'm editing a snippet of data within a larger context. The user submits this data to a specialized action for handling and redirects back to the parent page. Because it's a redirection, validation errors aren't getting automagically set, so I'm trying to work around that.
In the event of an error, I'm writing a validation_errors key to the session with a value of $model->validationErrors. In the form, though, I'd like to tell Cake to set each error so I can leverage my existing styles and not have to make a lot of changes to my $this->Form->input() methods.
Is something like this possible? Essentially, I'm looking to manually achieve the same result you'd get if a regular form was submitted and allowed to drop through with validation errors. I was hoping I could loop over each validation error and set the field error, but that's not making any change at all.
Thanks.
This can be achieved in the controller by
$this->Model->invalidate('fieldName', __('ErrorMessage', true));
If the values are available, you can also call
$this->Model->validates();
to validate all values with the validators defined in the model.
Save the data to the session and revalidate it.
function childAction() {
if(isset($this->data)) {
$this->Session->delete('invalid_data');
if($this->Test->save($this->data)) {
// ...
} else {
$this->Session->write('invalid_data', $this->data);
}
$this->redirect(array('action'=>'parentAction'));
}
}
function parentAction() {
if($this->Session->check('invalid_data')) {
// This will cause $this->Test->validationErrors to be populated
// Assuming your parent page has the form set up properly, the
// errors will be automagically filled. ie: $form->input('Test.field1')
$this->Test->set($this->Session->read('invalid_data'));
$this->Test->validates();
}
}
If you want to do the same with CakePHP 3, use the method "errors".

Resources