In the Resharper API, JetBrains.Resharper.Psi.Csharp.Tree.AddAttributeBefore takes an IAttribute param, and an IAttribute anchor. How are these arguments different, and how can they be constructed?
Have a peek at the working with XML document inside it shows use of the AddAttributeBefore call the first is the attribute you wish to insert. The second one is a attribute that already exists that you wish to insert before. If the second attribute is NULL the new attribute is inserted after the last attribute.
basically, the param is what you want to add, and anchor is the element before which you want to add something. Keep in mind that you can, in most cases, have anchor == null, which would cause the element to be added last.
Related
It seems like someXml.CreateElement("abc"); does only one thing: create the element. It does not add it as a child as I expected, nor does it seem to do anything else.
But that doesn't make much sense. Why create an element with an instance method instead of with a static method? That would indicate that it does have some relationship to the instance. But I couldn't find anything and hence my question.
The remarks in Microsoft's Documentation mentions that default attributes are created on the returned object. Namespaces come to mind as they may be automatically applied to the new element based on the XmlDocument's schema/defaults.
It also states that it must be manually added to the desired parent node.
From https://msdn.microsoft.com/en-us/library/fw1ys7w6(v=vs.110).aspx
Note that the instance returned implements the XmlElement interface, so default attributes would be created directly on the returned object.
Although this method creates the new object in the context of the document, it does not automatically add the new object to the document tree. To add the new object, you must explicitly call one of the node insert methods.
I think the reason that the method doesn't automatically add the element as a child like you were expecting is because there would be no way to know where the element should be added. The document could have many children and there is nothing to specify which element the created element should be added to. It can't just add it by default to the root element, because there's a good chance that isn't always going to be the desired location.
As previously mentioned, the perks of having it be an instance method rather than a static method would be to automatically create the default attributes (such as namespace) on the newly created element. That way once it is created it should just need to be added to the proper location in the document.
Is there any way to remove attribute after the attribute was added by AddAttribute (msdn)?
Example:
public static void GenerateFieldInput(HtmlTextWriter writer)
{
writer.RenderBeginTag(HtmlTextWriterTag.Input);
writer.AddAttribute("placeholder", "some value");
// some code logic
writer.RemoveAttribute("placeholder"); // there isn't such method in HtmlTextWriter
}
HtmlTextWriter, like many other TextWriters, only writes stuff into a stream. There isn't an official way to delete stuff from it.
And why do you want to remove the attribute in the first place? Did you find that later on in the code, that the attribute is not needed anymore? If that's the case, try determining whether the tag is actually needed before you write it.
If you can't do that, you can put all the attributes you want to add in a List<T>, which allows you to add and delete elements. After you are absolutely sure that that is what you are going to write, do a foreach loop and write each attribute.
I'm trying to programmatically create indexes corresponding to several types, so I can search through items of specific types in my controllers. (I tried using the type keyword in Lucene, but that seems to not work at all no matter what I do, so I changed my approach.)
However, I can't figure out how to tell Orchard to include a specific type in an index in a migration. I tried using:
var typeIndexing = ContentDefinitionManager.GetTypeDefinition(contentType)
.Settings.GetModel<TypeIndexing>();
typeIndexing.List = typeIndexing.List.Concat(indexName.Yield()).ToArray();
but that just returns null as the result of GetTypeDefinition().
I'm looking at using:
ContentDefinitionManager.AlterTypeDefinition(contentType, builder => {
builder.WithSetting("TypeIndexing.Indexes", indexName);
});
but that seems like it replaces the previous configured index, if it works at all (EDIT: nope), and I don't want to clobber the existing setting. (A different person on the team is handling our setup recipe.)
Is there any place where I could touch that setting and have it be stored and actually used by Orchard outside the recipe file?
To illustrate what I'm trying to accomplish using the analogous admin UI changes, under Content Definition > [Content Type Name] > Edit:
Before:
After:
What you're looking for is the Indexed() extension method. It accepts the indexes you want to use on the content type.
ContentDefinitionManager.AlterTypeDefinition(nameof(contentType),type =>
type
.Indexed("FirstIndex", "SecondIndex"));
I need to create a few tests for the user roles in a web application. To minimize the description, one of the tests involves checking if a menu entry is displayed or not for an user.
For this test, I use a table called UserRoles, that looks like this:
sUserName bDoesntHaveMenuX
User1 1
User2 0
User3 1
bDoesntHaveMenuX is of type bit.
I have a class derived from ValidationRule that checks if a certain text is present in a page, based on a XPath expression to locate the node where to look for the text.
The public properties of this class are:
string XPathExpression
string Text
bool FailIfFound
The last one dictates if the rule should fail if the text is found or not found.
In the test I added a datasource for the table mentioned in the beginning, called DS.
For the request I'm interested in I added a new instance of my validation rule class, with the following values:
Text=MenuX
XPathExpression=//div[#id='menu']//td
FailIfFound={{DS.UserRoles.bDoesntHaveMenuX}}
Unfortunately, this doesn't work.
The reason seems to be that the data binding process creates a context variable
DS.UserRoles.bDoesntHaveMenuX has the value "False" or "True". The value is a string, so the binding results in a casting error.
My options, as far as I can think of, are:
Change the validation rule to accept strings for FailIfFound. Not a valid
option, for 2 reasons: it's a hack and the same rule is used in
other places.
Make a new validation rule that will use the above mentioned one,
and implement the FailIfFound as string. I also don't like this, for
the same reason as above. It's a hack.
Make the test coded and do the proper cast before passing the data
to the validation rule. I don't like this one because I prefer to
have the test as coded only if there is no other way.
Which brings me to the question. Is there another way?
Thank you.
So the fundamental issue is that you have no control over how the data-binding treats the 'bit' data type, and it's getting converted to string instead of bool.
The only solution I can think of (which is sadly still a bit of a hack, but not so egregious as changing FailIfFound to string) is to create a WebTestPlugin, and in the PreRequestDataBinding or PreRequest event, convert the value from string to bool. Don't forget to add the plugin to your test(s) (easy mistake I have made).
Then when the validation rule is created it should pick up the nice new bool value and work correctly.
e.g.
string val = e.WebTest.Context["DS.UserRoles.bDoesntHaveMenuX"].ToString();
e.WebTest.Context["DS.UserRoles.bDoesntHaveMenuX"] = (val == "True");
I didn't actually try this... hope it works.
EDIT: round two... a better solution
Change the FailIfFound property to string (in a subclass as you mentioned), so it can work properly with data-binding.
Implement a TypeConverter that provides a dropdown list of valid values for the property in the rule's PropertyGrid (True, False), so in the GUI it looks identical to the rule having FailIfFound as a bool. You can still type your own value into the box when necessary (e.g. for data-binding).
Add the path of the .dll containing the TypeConverter code to your test project's References section.
This is what I have started doing and it is much more satisfying than having to type 'True' or 'False' in the property's edit box.
How can I force the framework to validate a specific field?
I saw somewhere that I can call $("form").validate().form() to force the entire form to validate, but I only want to check just the one field.
You can use the element method of the Validator object:
element( element ) Returns: Boolean
Validates a single element, returns true if it is valid, false otherwise.
Example:
$("#myform").validate().element( "#myselect" );
Another way:
$("#myElement").valid();