Reference updates conflics with contentrules - plone

I created a content rule with the "Object modified" trigger.
The rule has a "Workflow state" condition (but it might have a "Content type" one or any context-based condition).
The rule works fine BUT when the object's references are changed. This may happen when adding internal links or images in TinyMCE or when modifying the "related content" field for instance.
When updating references, a new object (the reference) is created (or deleted) in a special at_references folder associated with the original object.
Unfortunately, this creation fires the content rule, but in the context of the references folder. So the condition expression is not true and the action isn't executed.
Apparently, the rule is fired just once per request so it's not fired again for the original object that was modified.
Is this a bug or a feature?
Is there any workaround for this?
Do you have any suggestion of how to get my rule working?

Related

HTML Select Not Showing Selected Option After Refresh in Firefox

TL,DR: Firefox (and only Firefox) fails to display the right select child element as marked with selected="selected" upon clean refresh of a page, even though it is correct in DOM (but only under certain conditions).
(I do not believe this is a duplicate of HTML select, correct option selected in DOM, but wrong item shown in firefox as I am not using ember.js.)
Background
I'm building a "software management/update server" in ASP.NET WebForms. It stores master copies of applications and serves downloads and updates via a simple API. Each application (or "App" as they're referred to in-code) has a DeptID and a GroupID, which are GUIDs, relating to respective Dept and Group tables. Each Group has a DeptID field also.
On one particular page, used for editing a chosen software application's details, NON-postback requests (.e.g., http://localhost/admin/app/edit.aspx?id=guid-here) will result in calls to the database to populate field data on the page.
In brief, the ASP.net runtime Page_Load event does the following:
Ensures that this load is not a Postback
Verifies than an id parameter was provided in the query string
Populates options in the ddlDept DropdownList (renders as HTML select element) from the Dept table
Pulls all fields from the App record from DB as matched by id into a DataSet
Populates options in the ddlGroup DropdownList (another select) from the Group table, matching the DeptID pulled from the App dataset
Populates the data for all form fields from the App dataset
Important to Note: When you click Save, the page is posted back to the server and field data dumped into the database. If the save operation is successful, the browser is instructed to redirect to the current page's URL using Response.Redirect(Request.Url.ToString), resulting in a "clean load" (non-postback load) of the page.
Expected Behavior:
After the page has been successfully saved, hitting F5 or clicking refresh should result in another clean load (non-postback) of the page, and all fields should be populated just like a direct URL hit on the page.
Actual Behavior:
After the page has been successfully saved, hitting F5 or clicking refresh reloads the page as a non-postback (verified in VS debug), but the ddlGroup select element renders the "default" / first item ("Select One") instead of the item marked selected="selected" in the DOM.
I have stepped through every single line of VB code in debug — and when the server sends the page back after this "post-save" and supposedly "clean" load, the ddlGroup value is correct in code all the way out the door. Only in the browser, and only Firefox specifically, is the displayed value set to the wrong item, even though it's right in the DOM. Refreshing again doesn't help at all. When I try to save again, the RequiredField validator for ddlGroup complains that the field isn't valid, even though, again, it's supposedly right in DOM.
This seems to me to be a very bad Firefox bug.
Thoughts?
So, this isn't really what I consider a proper "solution," but rather more of a stable work-around.
Adding autocomplete="off" to the offending select (DropDownList in the aspx markup) magically prevents Firefox from messing up the displayed element within the select, thus always showing the correct one that is marked selected="selected".
I've gone ahead and added it (and will add it) to all of my DropDownLists / selects from now on... thanks Firefox.

What is the most correct asp.net page lifecycle event to change a label's text?

Joined a company that use Asp.Net, a tech that I had never worked with before. I have a very simple task to do which is to change a label's text depending on a value that is included in the logged in user's session.
I considered Init, Page Load and PreRender and ended up placing my code in the PreRender event and got a comment in a code review from the main code reviewer saying "this does not belong here, go and investigate the page lifecycle to figure out why"
According to the docs:
Init should be used to "initialize control properties" (which seems to be about right for this case).
Page Load should be used to "set properties in controls and to establish DB connections".
PreRender should be used to "make the final changes to the page or its controls"
I can't see an obvious event that should be used instead of the others. I wrote above that Asp.Net is new to me so I may be missing something.
Which event should be used in this particular case, and in general, to change properties of controls?

How to perform web service call after updating a content part in Orchard?

I have a Web API service that I have managed to use to pull values into a ContentPart by using the method outlined here: How to change Orchard record repository.
Now, what I want to do is update the values of the properties on my ContentPart and have the update performed via a Web API call. I think I'm close, but just can't get an update method to fire.
In my Handler, I have added a handler for OnUpdate. I can see my OnUpdate method get registered, but it never executes.
So my question is: Is this the correct handler event to use? And if so, how can I get it to trigger?
I should add that I am accessing the ContentPart through a Controller, as opposed to a Driver.
OnUpdating / OnUpdated get fired whenever you call IContentManager.UpdateEditor(item). In the default scenario this happens when you hit "Save" button when editing your content item.
I don't quite get what you mean by "accessing the ContentPart through a Controller"?
Do you have a custom controller that handles the item editor rendering and it's postback?
Or are you creating and updating some items in code, without using the built-in editors at all?
In the former case, you need to ensure that
IContentEditor.UpdateEditor(item) gets called for the whole content
item inside the POST action (same way it does in the default
controller - Core\Contents\Controllers\AdminController.cs).
In the latter, which I guess might be the case here, OnUpdating /
OnUpdated won't be fired and you need to call the web service on
your own from the controller action, as Bertrand pointed out in the comments.
There is also a third option available and I found it particularly useful in similar cases:
Use LazyField<T> as a backing field for those part properties you need to push to web service after update.
Put the code that calls web service inside that lazy field's setter (set this up during handler OnActivated event).
Now, whenever your property gets updated, a call to web service will be made, ie. the lazy field will act a a transparent proxy between your web service and current code.
For examples how to work with lazy fields take a look into CommonPartHandler class and methods LazyLoadHandlers and PropertySetHandlers.

RegisterExpandoAttribute - Throwing Error

Recently, I discovered that using: someControl.Attributes.Add("customAttr", "customVal") is not compatible with all web browsers. The recommended registration for custom attributes is:
Page.ClientScript.RegisterExpandoAttribute(someControl.ClientID, "customAttr", "customVal")
Okay, here's the problem. I am using a ListView to generate a custom control. In certain scenarios, the ListView must be refreshed/recreated. When this happens, and a ListView item attempts the register (in this case, re-register) the expando attribute, the page throws the following error:
An entry with the same key already exists.
Obviously RegisterExpandoAttribute() does not behave like the Page.Cache object where if a key already exists, the current value is overwritten. I can easily hack my way past this problem but I wonder if there is a more elegant solution to this. For example, there is no method like: Page.ClientScript.IsExpandoAttributeRegistered(...)
Any ideas?
If you're creating a custom control, try doing the RegisterExpandoAttribute call during the control PreRender. I was having issues with the attribute still being registered if the control had been removed and doing that fixed my issue. I would imagine that if you're calling RegisterExpandoAttribute in the PreRender for the control then it shouldn't be called more than once per page load.

Why is ASP.net MVC putting the following in Form.Request

I have a line of code in my view which looks like the following:
<button id="show-Lookup" class="inithide" name="show-Lookup">Lookup</button>
It crashes when it gets sent back to the controller on form submit with the following error:
"A potentially dangerous Request.Form value was detected from the client show-Lookup="
When I analyze the the value of show-Lookup in the debugger I see the following:
Request.Form["show-Lookup"]
Lookup
Where is ASP.net MVC getting this from? This shouldn't have a value?
This has nothing to do with MVC; it's basic HTML. Anything with a name can be considered for inclusion in your form, subject to certain restrictions (see the spec). If you don't want it in the form, get rid of the name.
A <button></button> is submitted with the form. Different browsers treat this slightly differently - IE sends the value of whatever is between the opening and closing tags (the button "content") while other browsers send the value attribute.
Note too that the behavior of your button will vary by browser unless you specify it. In IE (prior to 9?) a <button> element is type "button", while in other browsers it is "submit". (This is the W3C spec, too.)
on contoller add this attribute
[ValidateInput(false)]
One thing i would like to suggest, just dont use above code if you are not sure of what you are doing. The above code wont let server validate the input it received from form.
That means, if a user in ur form types his name like "alert('hacked')", your controller will receive that value as it is. And if you just add it in DB and displays it some where then its disaster. User may type fully qualified javascript to make ajax requests.
Another way to solve this problem is just remove the attribute name from button, as its not solving any purpose.
Question:
When I analyze the the value of show-Lookup in the debugger I see the following: Request.Form["show-Lookup"] Lookup
Where is ASP.net MVC getting this from? This shouldn't have a value?
You are seeing this value as you have added the attribute name to button, since you have added the attribute, browser is sending that property too to server.

Resources