I'm developing ASP.NET application and I need to calculate maths expressions like
16+25*(15.38-12.16)
which is entered in a text box control and to get result in other text box or label or wherever.
I tried some of these, but not of much help https://stackoverflow.com/questions/tagged/equation+c%23
Is there a possible way to do it?
You might be able to use DataTable.Compute() but it can only handle simple equations.
This should work:
C#
private double CalcEquation(string equation)
{
DataTable tempTable = new DataTable();
var result = tempTable.Compute(equation, "");
}
VB.Net
Private Sub CalcEquation(ByVal equation As String)
Dim tempTable As New DataTable()
Dim result As Object = tempTable.Compute(equation, "")
End Sub
You could use the NCalc library. It can handle more complex functions.
using System;
using NCalc;
namespace NCalcExample
{
class Program
{
static void Main(string[] args)
{
string evalString = "sin(2.0)+3";
Expression e = new Expression(evalString, EvaluateOptions.IgnoreCase);
Console.WriteLine(e.Evaluate());
}
}
}
Related
I want to parse the data from a URL query string and store it. Given below is my sample URL. From this I want to parse the data and store somewhere
http://www.example.com/default.aspx?VN=919999999999&Rawmessage=urlTest&Time=2013-04-08 12:32:04&Send=919000000002&MID=101878052
I want to store VN and Rawmessage into these strings,
string x = Request.QueryString["VN"]
string y = Request.QueryString["Rawmessage"]
Please help me find a solution.
Place this code in the Page_Load() function in Default.aspx.cs file.
protected void Page_Load(object sender, EventArgs e)
{
string x = Request.QueryString["VN"];
string y = Request.QueryString["Rawmessage"];
}
With reference to the discussion we had, I think you want to parse the query string key-value pair and use the values somewhere else.
Also, ASP.Net doesn't have to do anything with parsing, It's a pure C# problem.
I'm giving the sample solution to the problem in the context of a Console App, you're free to reuse the codes as per your taste.
var inputUrl =
#"http://www.example.com/default.aspx?VN=919999999999&Rawmessage=urlTest&Time=2013-04-08 12:32:04&Send=919000000002&MID=101878052";
int index = inputUrl.IndexOf("?");
var queryString = inputUrl
.Substring(index + 1)
.Split('&');
foreach (var strKeyValuePair in queryString)
{
var keyValPair = strKeyValuePair.Split('=');
Console.WriteLine("Key: {0}, Value:
{1}",keyValPair[0],keyValPair[1]);
}
Console.WriteLine("\n============================================\n\n");
string VN = queryString.FirstOrDefault(x => x.StartsWith("VN"));
string RawMessage = queryString.FirstOrDefault(x =>
x.StartsWith("Rawmessage"));
Console.WriteLine("VN: {0}",VN.Split('=')[1]);
Console.WriteLine("RawMessage: {0}", RawMessage.Split('=')[1]);
Console.ReadLine(); // just to halt the console
There are tables with over 50 columns, I am using following code to loop through the dataReader for column existence.
If HasColumn(reader, "EmpCode") Then obj.OwningOfficeID = CType(reader("EmpCode"), Int32)
Protected Function HasColumn(ByRef reader As SqlDataReader, ByVal columnName As String) As Boolean
For i As Integer = 0 To reader.FieldCount - 1
If reader.GetName(i).Equals(columnName) Then
Return Not IsDBNull(reader(columnName))
End If
Next
Return False
End Function
I am wondering if there is any better way of checking the columns in the DataReader instead of looping through the DataReader each time i bind the object property?
SqlDataReader.GetSchemaTable Method will give the DataTable of the executed query, from there you can get all the columns
Returns a DataTable that describes the column metadata.
MSDN http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.getschematable.aspx
currently I am using this extension method for this purpose
public static bool TryGetOrdinal(this IDataRecord dr, string column, out int ordinal)
{
try
{
ordinal = dr.GetOrdinal(column);
}
catch(Exception ex)
{
ordinal = -1; //Just setting a value that GetOrdinal doesn't return
return false;
}
return true;
}
so you use it as follows
int ordinal = 0;
if(dr.TryGetOrdinal("column",out ordinal))
string val = dr.GetValue(ordinal).ToString();
My VB is not so good. Sorry couldn't convert it to VB for you. But I think you get the basic idea and can recode it in VB.
I have a .NET class which holds a simple array of strings available via an accessor method, which looks like this;
namespace Foo.Bar {
[ComVisible(true)]
[Guid("642279A0-85D4-4c7a-AEF5-A9FAA4BE85E5")]
public class MyClass {
private string[] _myArray;
public MyClass() { }
public MyClass(string[] myArray) {
_myArray = myArray;
}
public string[] MyArray {
get { return _myArray; }
}
}
}
I consume this class using Classic ASP;
Dim foo
Set foo = Server.CreateObject("Foo.Bar.MyClass")
if IsArray(foo.MyArray) then Response.Write("IsArray") & "<br />"
Response.Write(typename(foo.MyArray)) & "<br />"
Response.Write(UBound(foo.MyArray)) & "<br />"
This results in;
IsArray
String()
1
However, when I try to access the contents of the array using;
Response.Write(foo.MyArray(0)) & "<br />"
I get;
Microsoft VBScript runtime (0x800A01C2) Wrong number of arguments or
invalid property assignment: 'MyArray'
Any help is much appreciated.
Edit This is to provide more information after digesting the answers given (thanks)
When changing the implementation of the MyArray property to;
public object[] MyArray {
get { return (object[])_myArray; }
}
I then get the following error,
Microsoft VBScript runtime (0x800A000D) Type mismatch: 'MyArray'
So I tried individually casting each string to an object;
public object[] MyArray {
get {
object[] tmp = new object[_myArray.Count()];
for (int x = 0; x < _myArray.Count(); x++) {
tmp[x] = (object)_myArray[x];
}
return tmp;
}
}
Then I'm back to,
Microsoft VBScript runtime (0x800A01C2) Wrong number of arguments or
invalid property assignment: 'MyArray'
Edit Final solution with help from How to correctly marshal VB-Script arrays to and from a COM component written in C#
C#
public object MyArray {
get { return _myArray.Cast<object>().ToArray(); }
}
VBScript
Dim foo
Set foo = Server.CreateObject("Foo.Bar.MyClass")
bar = foo.MyArray
Response.Write bar(0)
The key was to expose object rather than object[] and as AnthonyWJones suggested, assign the array to a variable before using it.
Thanks again.
The problem is VBScript cannot actually use an array of String. It can only use an array of Variant.
Try changing MyClass to expose an object[] instead.
In addition to Anthony's suggestion I'm not sure is it the best way but in the past I used a code similar to the following to handle one dimensional arrays.
public object MyArray(int ix = -1){
string[] tmp = new string[] {"one", "two", "3", "4"};
return (ix == -1) ? (object)tmp : tmp[ix];
}
In ASP:
Response.Write(TypeName(foo.MyArray)) 'string()
Response.Write(TypeName(foo.MyArray(0))) 'string
VBScript doesn't understand generic collections such as List<string> and it doesn't understand string arrays either.
I wrote a public function into my Interface class to convert any generic collections into an ArrayList
public ArrayList toArrayList(IEnumerable collection)
{
var arrayList = new ArrayList();
foreach (object element in collection)
{
arrayList.Add(element);
}
return arrayList;
}
This code can then be used in VBScript like this
dim connector
set connector = model.getRelationByID(connectorID)
'get the related elements
dim relatedElements
set relatedElements = model.toArrayList(connector.relatedElements)
addRelatedElementoAutoDiagram relatedElements(0), relatedElements(1), model
The advantage of this approach is that I don't need to change the signature of any of the methods or properties in C#, but I can still use them in VBScript
This code demonstrates how to handle arrays between COM and ASP:
<% #Language="VBScript" %>
<% Option Explicit %>
<%
Dim tcs
Dim rc
Dim vntInput(0,4)
Dim i
vntInput(0,0) = Request.QueryString("strUser")
vntInput(0,1) = Request.QueryString("intCreate")
vntInput(0,2) = Request.QueryString("intDelete")
vntInput(0,3) = Request.QueryString("intModify")
vntInput(0,4) = Request.QueryString("intView")
Set tcs = Server.CreateObject("TestCases.ArrayFailure")
rc = tcs.AcceptArray(vntInput)
For i = 0 to UBound(vntInput, 2)
Response.write "Loop Count " & i & " " & vntInput(0,i) & "<BR>"
Next
%>
Here's a link to the article where I found this code:
http://202.102.233.250/b2000/ASP/articles/component/pv990826.htm
I have a value I am pulling into a string that looks like this:
M'arta
I need to have it to translate the numeric value into an actual value so that the string looks like this:
M'arta
Any ideas on how to accomplish this in VB.NET? Here is the relevant line of code that returns this result:
Dim occupant as String = GridView1.Rows(e.RowIndex).Cells(2).Text
Below is the VB (& C#) version to what you're asking. Basically, use the MatchEvaluator argument in the Regex method to allow custom parsing of the matches. In this case, we find any instances of #<1-3_digit_number> we want to strip the `# symbol, and convert the decimal code.
I added a second conversion in your string (#116) just for testing purposes. You could refactor this in to a custom method and (not sure if VB has it) lambda expression to make it universal, but I'll leave that up to you.
VB.NET Version (DEMO)
Imports System.Text.RegularExpressions
Public Class Test
Public Shared Sub Main()
Dim sample As [String] = "M#39ar#116a"
Dim reg As New Regex("\x23\d{1,3}")
Console.WriteLine(reg.Replace(sample, New MatchEvaluator(AddressOf ReplaceASCIICode)))
End Sub
Public Shared Function ReplaceASCIICode(m As Match) As [String]
Dim code As Int32 = Int32.Parse(m.Value.Substring(1))
Return Convert.ToString(ChrW(code))
End Function
End Class
C# Version (DEMO)
using System;
using System.Text.RegularExpressions;
public class Test
{
public static void Main()
{
String sample = "M#39ar#116a";
Regex reg = new Regex(#"\x23\d{1,3}");
Console.WriteLine(reg.Replace(sample, new MatchEvaluator(ReplaceASCIICode)));
}
public static String ReplaceASCIICode(Match m)
{
Int32 code = Int32.Parse(m.Value.Substring(1));
return Convert.ToString((char)code);
}
}
For archival purposes, here are the versions that support &#___; below:
VB.NET (DEMO)
Imports System.Text.RegularExpressions
Public Class Test
Public Shared Sub Main()
Dim sample As [String] = "M'arta"
Dim reg As New Regex("&#(\d{1,3});")
Console.WriteLine(reg.Replace(sample, New MatchEvaluator(AddressOf ReplaceASCIICode)))
End Sub
Public Shared Function ReplaceASCIICode(m As Match) As [String]
Dim code As Int32 = Int32.Parse(m.Groups(1).Value)
Return Convert.ToString(ChrW(code))
End Function
End Class
C# (DEMO)
using System;
using System.Text.RegularExpressions;
public class Test
{
public static void Main()
{
String sample = "M'arta";
Regex reg = new Regex(#"&#(\d{1,3});");
Console.WriteLine(reg.Replace(sample, new MatchEvaluator(ReplaceASCIICode)));
}
public static String ReplaceASCIICode(Match m)
{
Int32 code = Int32.Parse(m.Groups[1].Value);
return Convert.ToString((char)code);
}
}
You can parse the string looking for the #digits and then put the found code through the ChrW .NET function.
If you don't know regex then something like this
Dim idx As Integer = occupant.IndexOf("#")
If idx <> -1 Then
idx += 1
Do While idx < occupant.Length
If IsNumeric(occupant(idx)) Then
s &= occupant(idx)
Else
Exit Do
End If
idx += 1
Loop
If s.Length > 0 Then
s = Convert.ToChar(CInt(s))
End If
Stop
End If
It would need slight modification to handle multiple instances of #.
I don't know VB.NET, but here is a C# solution. I am pretty sure you can handle the conversion to Visual Basic.
using System;
using System.Text.RegularExpressions;
class Program {
static void Main(string[] args) {
String input = "M#39arta";
String output = Regex.Replace(input, #"#\d\d", Replace);
Console.WriteLine(output);
Console.ReadLine();
}
static String Replace(Match match) {
int charCode = int.Parse(match.Value.Substring(1));
return ""+ (char)charCode;
}
}
Hi
i need to validate a textbox value in order to accept only values that are in the completion list of the associated autocompleteextender control.
I'm using ajaxtoolkit (version 20229) on asp.net 2.0.
For now i use the code below to validate the textbox ; as you can see i had a hiddenfield that keep the selected key. The hiddenfield is set to 0 if the user enter a value without selecting it from the list.
Do you have any idea?
Thanks
/**** Javascript code
function AutoCompleteItemPopulated(source, eventArgs)
{
var assocHiddenField = document.getElementById( source.get_element().id+'_hidden');
assocHiddenField.value=0;
}
function AutoCompleteItemSelected(source, eventArgs)
{
var assocHiddenField = document.getElementById( source.get_element().id+'_hidden');
assocHiddenField.value = eventArgs.get_value();
}
/*****CODEBEHIND code used to populate the autocompletion list
[System.Web.Services.WebMethodAttribute(), System.Web.Script.Services.ScriptMethodAttribute()]
public static string[] getStrada(string prefixText, int count, string contextKey)
{
System.Collections.Generic.List<string> items = new System.Collections.Generic.List<string>();
DataSetIncidentiTableAdapters.StradarioTableAdapter adapter = new DataSetIncidentiTableAdapters.StradarioTableAdapter();
DataSetIncidenti.StradarioDataTable dtStrade = adapter.GetStrade(contextKey, prefixText);
foreach (DataSetIncidenti.StradarioRow strada in dtStrade.Rows)
{
items.Add(AjaxControlToolkit.AutoCompleteExtender.CreateAutoCompleteItem(strada.DenominazioneCompletaVia, strada.IdStrada.ToString()));
}
return items.ToArray();
}
Yes this can be validated; you need to use a CustomValidator to do this, which you can setup both a client and server validation function, and then check the hidden field for its value.
This works great for us.
HTH.