This code:
<asp:TextBox runat="server" MaxLength="<%=Settings.UsernameMaxLength %>" ID="Username"/>
Throws a parser error.
Is it possible to set properties in any way similar to this without using the code behind?
No, it is not possible. Syntax <%= some code here %> cannot be used with server-side controls. You can either go with <%# some code here %>, but only in case of data binding, or just set this property in code behind, say on Page_Load:
protected void Page_Load(object source, EventArgs e)
{
Username.MaxLength = Settings.UsernameMaxLength;
}
You may try this, which should set the MaxLength value upon rendering :
<%
Username.MaxLength = Settings.UsernameMaxLength;
%>
<asp:TextBox runat="server" ID="Username"/>
I think (not tried) you can also write :
<asp:TextBox runat="server" MaxLength="<%#Settings.UsernameMaxLength %>" ID="Username"/>
But you would then need to call Username.DataBind() somewhere in the codebehind.
I'm late to the party here, but here goes anyway...
You could build your own Expression Builder to handle this case. That would allow you to use syntax like this:
<asp:TextBox
runat="server"
MaxLength="<%$ MySettings: UsernameMaxLength %>"
ID="Username"/>
Note the $ sign.
To learn how to make you own Expression Builder, please go through this old but still relevant tutorial. Don't let the wall of text scare you off because in the end, making an expression builder is easy. It basically consists of deriving a class from System.Web.Compilation.ExpressionBuilder and overriding the GetCodeExpression method. Here is a very simple example (some parts of this code was borrowed from the linked tutorial):
public class SettingsExpressionBuilder : System.Web.Compilation.ExpressionBuilder
{
public override System.CodeDom.CodeExpression GetCodeExpression(System.Web.UI.BoundPropertyEntry entry, object parsedData, System.Web.Compilation.ExpressionBuilderContext context)
{
// here is where the magic happens that tells the compiler
// what to do with the expression it found.
// in this case we return a CodeMethodInvokeExpression that
// makes the compiler insert a call to our custom method
// 'GetValueFromKey'
CodeExpression[] inputParams = new CodeExpression[] {
new CodePrimitiveExpression(entry.Expression.Trim()),
new CodeTypeOfExpression(entry.DeclaringType),
new CodePrimitiveExpression(entry.PropertyInfo.Name)
};
return new CodeMethodInvokeExpression(
new CodeTypeReferenceExpression(
this.GetType()
),
"GetValueFromKey",
inputParams
);
}
public static object GetValueFromKey(string key, Type targetType, string propertyName)
{
// here is where you take the provided key and find the corresponding value to return.
// in this trivial sample, the key itself is returned.
return key;
}
}
In order to use it in your aspx page, you must also register it in web.config:
<configuration>
<system.web>
<compilation ...>
<expressionBuilders>
<add expressionPrefix="MySettings" type="SettingsExpressionBuilder"/>
</expressionBuilders>
</compilation>
</system.web>
</configuration>
This is just to show you that it's not difficult. But please review the tutorial I linked to in order to see an example of how to deal with the expected return type from your method depending on the property being assigned etc.
Related
I am developing a custom tag for asp.net I want to read data from this tag database and return it as a class object and use it on aspx pages.
My code:
private T RenderControl<T>(Control control)
{
T test = (T)Convert.ChangeType(GetType(DataSource), typeof(T));
test = WebFramework.GetSingleData<T>(SQL, SQLParams.ToArray());
return test;
}
protected override void RenderContents(HtmlTextWriter output)
{
output.AddAttribute(HtmlTextWriterAttribute.Id, this.ID);
}
how can I do that? Example:
<a1:SingleOrDefault ID="test" runat="server" DataSource="MyProject.Models.Members" SQL="SELECT * FROM Members WHERE ID=1"></a1:SingleOrDefault>
<%= test.UserName %>
Thank you.
You could use JSON to convert the object to and from strings, and have your asp.net method work with strings rather than object. JSON can be interpreted in any almost language, server side and client side.
Example:
https://stackoverflow.com/a/2246724/8250558
Netwtonsoft is very popular: https://www.newtonsoft.com/json
ObjectDataSource is not recognizing obsolete method and executing it as normal method.
ObjectDataSource is not identifying the obsolete attribute where as the code behind file recognizes the obsolete method and throwing an error during compilation/build.
public class TEST
{
public TEST()
{
//
// TODO: Add constructor logic here
//
}
[Obsolete("Old method", true)]
public DataTable GetData()
{
DataTable dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("Desc");
for (int i = 0; i < 10; i++)
{
DataRow drow = dt.NewRow();
drow[0] = "Name_" + i.ToString();
drow[1] = "Desc_" + i.ToString();
dt.Rows.Add(drow);
}
return dt;
}
}
ASPX
<form id="form1" runat="server">
<div>
<asp:GridView ID="Gridview1" runat="server" DataSourceID="ObjectDataSource1" EnableModelValidation="True"></asp:GridView>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GetData" TypeName="TEST"></asp:ObjectDataSource>
</div>
</form>
ASPX.CS
Am I missing any settings here? Please help and let me know if additional information is required.
Thanks in advance.
The problem is that the markup is not compiled at design time.
<asp:ObjectDataSource ID="ObjectDataSource1"
runat="server"
SelectMethod="GetData"
TypeName="TEST">
</asp:ObjectDataSource>
So no compiler is invoked when you add or edit the value in the SelectMethod attribute, hence no error or warning is raised.
In the description of the ObsolteAttribute we find:
Initializes a new instance of the ObsoleteAttribute class with a workaround message and a Boolean value indicating whether the obsolete element usage is considered an error.
Key is here the word usage. When the method is used in a declarative and/or late bound manner the compiler couldn't detect it's usage hence no error is raised. The method is still compiled and present in the assembly. There will no runtime exception be raised.
An ObjectDataSource instance uses reflection to invoke the method. Deep inside its bowels you'll find this (simplified):
Type type = this.GetType(this.TypeName);
MethodInfo method = type.GetMethod(this.SelectMethod, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);
objectDataSourceResult = method.InvokeMethod(this, null);
Which basically lookups the method at runtime and invokes it. You can even change the value of SelectMethod during runtime and the code will still work. The obsolete attribute is not taken into account once the assemblies are compiled.
Good night-morning-evening-etc ^_^
I'm getting problems while trying to display an image in asp:Image (using Web Forms), stored in a db as byte[] - found a lot of rather clear answers, how to do it, so now I have a handler:
public class ShowImageHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
//creating object, working with db
var core = new CoreHolder();
var picture = core.PictureRepository.Read(Convert.ToInt32(context.Request.QueryString["id"]))
context.Response.Clear();
context.Response.ContentType = picture.PictureMimeType;
//trying to write byte[]
context.Response.BinaryWrite(picture.PictureData);
context.Response.End();
}
public bool IsReusable
{
get
{
return false;
}
}
}
...and such strings in my .aspx page:
<asp:Image ID="Image1" runat="server" ImageUrl="~/ShowImageHandler.ashx?id=<%#:Item.ID %>" />
<asp:Image ID="Image1" runat="server" ImageUrl="~/ShowImageHandler.ashx?id=1>" />
The problems are: ok, the program enters the ProcessRequest with id, and in case of the second asp-image string it finds the pic with data, but even before trying to BinaryWrite I can see, that there are exeptions in context.Response.OutputStream: length,position - System.NotSupportedExeption, Read/WriteTimeout - System.InvalidOperationExeption. In case of the first string (it's used in ListView ItemTemplate) the OutputStream problem stays + all crushes on trying to get the id from the query string.
Help, please)
The errors you see in the debugger for context.Response.OutputStream.Length and Position don't matter. You can only write to that stream so the exceptions you see in the debugger display are expected.
Your code looks fine so my guess is that if you look at the URL, the value for your id querystring argument will not be an integer. You are probably getting a FormatException when you try to convert it to an integer.
You should test the handler by putting the url "ShowImageHandler.ashx?id=1" in your browser's address bar instead of using an <img /> tag. That way if there is an exception you can get a real stack trace instead of just seeing a broken image.
I have a key-value pair defined in the Web.Release.config and Web.Debug.config for a url.
In the C# file I use it like so (key is "Report-URL"):
string reportUrl = System.Configuration.ConfigurationManager.AppSettings["Report-URL"];
CoverSheetReportViewer.ServerReport.ReportServerUrl = new Uri(reportUrl);
This works but now I want to use it in a .ascx file where I currently have the url hardcoded:
<asp:HyperLink ID="HyperLinkReports" runat="server" CssClass="LeftNav"
NavigateUrl="http://mygroup-dev-appsr/ReportServer?%2fASD%2fTransactions%2fCoverSheet&rs:Command=ListChildren" />
How do I do this?
Try this with help of Inline Syntax
NavigateUrl="<%$ AppSettings:Report-URL %>
or
In .ascx
Report
in .ascx.cs
protected string GetReportUrl(){
string reportUrl = System.Configuration.ConfigurationManager
.AppSettings["Report-URL"];
return new Uri(reportUrl).ToString();
}
Another Syntax Reference
I'm trying to work with a class that has a child object, which has a string - and I'm trying to access this with in-line C# code on my aspx page.
More specifically, let's say I'm working with an object of 'Upload' class which has a Title property (String). An Upload object can also have a 'File' property (object). And each File object has a Url property (String).
I can access the Title like so:
<%# ((Upload)Container.DataItem)["Title"] %>
That works fine. But then how do I access a File's Url? Because the following does not work:
<%# ((File)((Upload)Container.DataItem)["File"]).Url %>
As you may be able to guess from the syntax, this is all within an asp repeater.
try this:
<%# ((Upload)Container.DataItem).File.Url %>
You get the container dataitem & cast it. Once you have the object, you can call it's properties & methods like any other object
you might try something like
<%# Bind("File.Url") %>
or
<%# DataBinder.Eval(Container.DataItem, "File.Url") %>
I am just giving you a sample, you can implmement the same on your own:-
First create a server side code to to return a URL of the File.
Then call that function from client side to get the URL of the title passed to the same.
Below is an example which returns the text with the suffix dots
Step 1 : Create server side code to return text with suffix dots
public string ReturnDotSuffix(string strValue, int iFontSize, int iWidth)
{
string strReturnValue = string.Empty;
try
{
CommonLib objCommonLib = new CommonLib();
strReturnValue = objCommonLib.SuffixDots(strValue, iFontSize, iWidth);
}
catch (Exception ex)
{
HandleException.ExceptionLogging(ex.Source, ex.Message, true);
}
return strReturnValue;
}
Step 2: Call this from Client Side.
Text='<%# ReturnDotSuffix((string)DataBinder.Eval(Container.DataItem, "MessageTitle"),8,170) %>'
The same can be done in your case.