Is this a bug in ASP.NET 3.5? - c#

In ASP.NET when I try to add a dynamic control (includes validation) to Placeholder or any other control container, the name of control become an important. For example, this is very normal, easy control adding code.
var control = LoadControl("TestUserControl.ascx");
control.ID = Guid.NewGuid().ToString();
PlaceHolder1.Controls.Add(control);
as you see, I'm giving guid to control's ID. In Runtime, this code fails, and compiler says this is a javascript error, and error message like ';' character expected, missing.. etc..
The problem is very interesting. Dynamically added ASP.NET control (includes validation), causes an error because of " - " character in dynamically named ID property (or anything like '-', '.',etc..).
When I refine my code like:
var control = LoadControl("TestUserControl.ascx");
control.ID = Guid.NewGuid().ToString().Replace("-", string.Empty);
PlaceHolder1.Controls.Add(control);
problem goes away :)
Is this a bug in ASP.NET 3.5? Why its look like a javascript error in page?

It's not a bug so much as misuse. You couldn't give a control an ID that included a - if you did it within the IDE, so it makes sense that attempting to do it dynamically should have unintended results. The math functions are riddled with peculiarities like this that aren't bugs. Sure MS probably could have put in a function in the property that checked for invalid characters in the ID before allowing it to be set, but that would be a runtime error anyway (which is what you have).

Related

Not finding all of the symbols I need,How to find more symbols using the Roslyn API

I am using the roslyn API and ace text editor to create a web IDE.
When i hover over data i need it to find the symbol at the given location. This works in some situations by calling the roslyn method:
var symbol = SymbolFinder.FindSymbolAtPosition(semanticModel, offset, dotNetCodeManager.Solution.Workspace, cancellationToken);
An example of the situations where this works is when i hover my mouse over the word "table" in the below example.
var SchemaName = table.Schema.Name;
However when i hover my mouse over the word Schema or Name SymbolFinder.FindSymbolAtPosition returns null.
However:
If I go to the end of the word table and ask for autocomplete information I do get Schema in the list of recommended symbols
var result = Recommender.GetRecommendedSymbolsAtPosition(semanticModel, offset, solution.Workspace);
How do I get roslyn to find symbols that are properties, methods, or fields of objects?
So FindSymbolAtPosition should work just fine -- it's after all the same API we use for things like go to definition or any other core language feature. What I would guess here is your compilation or semantic model isn't complete, and so when we try to bind Schema or Name we for some reason. The recommendation API might be able to figure out the type of the parent and know it has members, but for some reason those members aren't properly binding.
What I would recommend you try is in your semantic model or compilation, call GetDiagnostics and verify there aren't any unexpected errors there. You might be missing a reference that's causing everything to go sideways, and clearing that will make this work fine.

Find correct object names in server side errors

I just realized if I don't put my asp.net controls inside a form with runtat="server" attribute I will get a error like this:
Control 'ctl25' of type 'Button' must be placed inside a form tag with
runat=server
Although its really easy to debugging this error I'm just curious is it possible to understand which object is ctl25? Because I searched carefully all object attributes, .aspx, .aspx.cs and .aspx.designer.cs files but I couldn't find anything with ctl25 label.
So is it possible to find ctl25 referring to which object?
Actually, setting ID is somewhat optional (server-side-access can be achieved by iterating over Controls-property of parent, and client-side-access just needs ClientID, which is done automatically), by leveraging on the automatic ClientID-setting.
So there's a fairly good chance that you'll never see ID="ctl25" as it might be/is done automagically.
Just give the control in question an explicit ID, and you should be fine.

Parsing what an automatically generated select element in ASPX is doing?

I'm trying to make sense of the following select element :
<select name="ctl00$ctl00$ContentPlaceHolder1$ContentItems$ddlResponseRange id="ctl00_ctl00_ContentPlaceHolder1_ContentItems_ddlResponseRange" class="Content" style="width:11%;">
This is all automatically generated code, correct( ie like ct100 ) ? What are the $ symbols doing - are they for expression bindings? FYI the ddl here means "drop-down list".
$ and _ are used as separators between the server-side ID of the control, ddlResponseRange, and the server-side IDs of its parent controls that are of type INamingContainer (typically <asp:content> controls).
A control by itself on a page, right inside a <form runat="server"> does not have attributes like that. But when you start using master pages, or data binding controls, then you are using controls that implement INamingContainer. This interface is like a marker, and it instructs the ASP.NET runtime to start adding the control's server-side ID to that of its child controls. This is necessary to guarantee unique name and ID attributes in the generated HTML.
Ultimately this infrastructure is what supports ASP.NET Web Forms post back mechanism and client-side scripting.
If you are using ASP.NET 4.0 or later, you can actually influence the way client-side IDs are generated by ASP.NET. See this article for different ways to configure the client-side IDs.
It's all just one big string. From the point of view of HTML, they're all valid characters to make up the value of an attribute, so in that sense it's "correct".
As for trying to use the id/name value yourself, or to rely on assumptions about the name/id based on that structure, I'd suggest avoiding that. I find it preferable to pretend that ASP will generate a random name/ID that I can't use, despite the fact that in reality it's just the IDs of all elements from that item up to the root. If you find yourself writing out ID values like that yourself, you're probably doing something wrong.
As for why it follows that convention instead of just actually assigning a random ID/Name (or none at all) is so that it can re-use it to correlate the HTML response to the structure of of items in memory. It's also important to ensure that IDs are unique per page, and by using this structure it means that APS ID values only need to be unique among sibling elements.

C# ASP.NET GetType() with WebUserControl issue

In the project I have some custom WebUserControls for form elements (they encapsulate some standard validators and other system specific functions). My user controls are "DropDownListField" and "TextBoxField". In the code behind of a page I have this code:
string parameterValue = null;
foreach (object control in myMultiView.Views[myMultiView.ActiveViewIndex].Controls)
{
if (control.GetType() == typeof(DropDownListField))
parameterValue = ((DropDownListField)control).Value;
if (control.GetType() == typeof(TextBoxField))
parameterValue = ((TextBoxField)control).Value;
}
For some reason the "if" statements always return false even when I step through the code and see that "control" is getting assigned my web user control. This code is in another place in the project exactly the same except in the other location the standard .net controls "TextBox" and "DropDownList" are used and in the other location the code works.
Does anybody know why this wouldn't work with web user controls?
UPDATE:
Hmm so in debugging I found this:
?control.GetType();
BaseType: {Name = "DropDownListField" FullName = "WebUI.UserControls.Fields.DropDownListField"}
?typeof(DropDownListField);
BaseType: {Name = "UserControl" FullName = "System.Web.UI.UserControl"}
So typeof is just recognizing they are user controls not the full type it seems.
Does anybody know how I would check for a specific user control type?
I'm guessing they aren't the same type, use debugging to find out the actual type.
Also, try using the 'is' keyword instead.
PS: It might be cleaner for you to say if (control is DropDownListField)
I don't recall if a view directly includes its children in Controls, but I wouldn't be surprised if Controls contained only one element, which would be a container of some sorts. Therefore, your controls are potentially in Controls[0].Controls or even further down. I would advise you create a method that finds the child recursively.
Actually, your controls should all implement a common interface (example:
interface ICustomFieldWithValue { string Value {get; set; }}
). Your resulting code would be much cleaner.
c2.GetType().ToString() == "System.Web.UI.WebControls.Label"

Regular Expression Validate() yields NullReference(ASP.NET)

I am having problems using a ASP.NET Regular Expression Validator on text boxes.
This is a condensed version of my code:
RegularExpressionValidator regex = new RegularExpressionValidator();
regex.ID = "TextBoxRegExValidator" + ((AVPEditControl)avpControl).ThisFieldRID.ToString(); //random name
regex.ControlToValidate = ((AVPEditControl)avpControl).TextControlID; //this is valid.
regex.ValidationExpression = "\d{3}-\d{2}-\d{4}";
regex.Text = "epic fail";
//later, in an event handler
regex.Display = ValidatorDisplay.None;
regex.ErrorMessage = "";
regex.Validate(); //ERROR
bool valid = AVPEdit.Validator.IsValid;
Where I marked "ERROR" Is where I get a NullReferenceException thrown. I do not see what I am missing here, because I confirmed with a debugger that regex is not null in that context, and neither is the control that it validates.
I wish to have more fine grained control over how the error message is displayed,so thats why I chose not to hook regex into any Panels or such.
Why would I possibly be getting a null reference from that? (Is this a bug in .NET?)
Also, note that this works when I set Visible to 0, but that makes it so IsValid is always true.
All the ASP.NET validators must be part of a Page in order to function. You'll note that the Validate method does not return a value; this is because it is not intended to be used the way you're using it.
Inside the Validate method, it is attempting to look up the control by its ID and without a parent naming container, it has no ability to do so. The way you're doing it, it has no value to validate against (because it won't be able to find the control).
I would do one of the following:
1) Put the validator in the ASPX, then use its Validate method and check the IsValid property afterwards. Just set Display to None and it shouldn't show up in your UI.
2) Just run the regex manually. You're writing a lot more code here than would be necessary if you would just use Regex.IsMatch.
(Note that if you use Reflector, browse to RegularExpressionValidator, you'll see where it will attempt to call out to this.NamingContainer among other things that would be null without being part of a control collection)
I think you should add it to your controls collection, maybe inside an invisible div control to make it work.
But If you want to validate your textbox programmatically, why don't you just write a method that uses your pattern to validate control and returns validity ?
I think if you want to use code behind for validation, you can use something like this
Match m = Regex.Match(yourtext,"\d{3}-\d{2}-\d{4}")
if(m.Success)
{
//valid
}
else
{
//invalid
}

Categories

Resources