Webmatrix - including int's in my search page - list

i have built a fully working search page for my WebMatrix property site. To summarize, it checks the query string, and if any of the defined values are present, it adds it to a list so it can iterate through them.
The problem, as you will see, if that it currently adds everything to the list as a string. This causes problems when i need to use the value as an INT (PropertyType and NumBedrooms should be int's). is there a way i can use both strings and int's in this scenario? can i add ints AND strings to the same list?
here's the code:
var db = Database.Open("StayInFlorida");
var proptype = db.Query("SELECT * FROM Property_Type");
IEnumerable<dynamic> queryResults;
//Search Variables
string searchTerm = "";
string resortID = "";
string propertyType = "";
string numBedrooms = "";
List<string> argList = new List<string>();
//Paging Variables
var pageSize = 6;
var totalPages = 0;
var count = 0;
var page = UrlData[0].IsInt() ? UrlData[0].AsInt() : 1;
var offset = (page -1) * pageSize;
//Request querystrings from URL
if (!String.IsNullOrWhiteSpace(Request.QueryString["searchTerm"]))
{
searchTerm = Request.QueryString["searchTerm"];
}
if (!String.IsNullOrWhiteSpace(Request.QueryString["resortID"]))
{
resortID = Request.QueryString["resortID"];
}
if (!String.IsNullOrWhiteSpace(Request.QueryString["propertyType"]))
{
propertyType = Request.QueryString["propertyType"];
}
if (!String.IsNullOrWhiteSpace(Request.QueryString["numBedrooms"]))
{
numBedrooms = Request.QueryString["numBedrooms"];
}
int numOfArguments = 0;
string selectQueryString = "SELECT * FROM Property_Info ";
if (searchTerm != "")
{
argList.Add(searchTerm);
selectQueryString += "WHERE FullDescription LIKE '%' + #0 + '%' OR BriefDescription LIKE '%' + #0 + '%' ";
numOfArguments++; //increment numOfArguments by 1
}
if (resortID != "")
{
argList.Add(resortID);
if (numOfArguments == 0)
{
selectQueryString += "WHERE ResortID = #0 ";
}
else
{
selectQueryString += "AND ResortID = #" + numOfArguments + " ";
}
numOfArguments++;
}
if (propertyType != "")
{
argList.Add(propertyType);
if (numOfArguments == 0)
{
selectQueryString += "WHERE PropertyTypeID = #0 ";
}
else
{
selectQueryString += "AND PropertyTypeID = #" + numOfArguments + " ";
}
numOfArguments++;
}
if (numBedrooms != "")
{
argList.Add(numBedrooms);
if (numOfArguments == 0)
{
selectQueryString += "WHERE NumBedrooms = #0 ";
}
else
{
selectQueryString += "AND NumBedrooms = #" + numOfArguments + " ";
}
numOfArguments++;
}
selectQueryString += "ORDER BY CreatedDate DESC";
string[] argArray = argList.ToArray();
queryResults = db.Query(selectQueryString, argArray);
count = queryResults.Count();
totalPages = count/pageSize;
if(count % pageSize > 0){
totalPages += 1;
}
Edited code after Polynomial's suggestion:
#{
Layout = "~/_SiteLayout.cshtml";
Page.Title = "Search Page";
var db = Database.Open("StayInFlorida");
var proptype = db.Query("SELECT * FROM Property_Type");
//Paging Variables
var pageSize = 6;
var totalPages = 0;
var count = 0;
var page = UrlData[0].IsInt() ? UrlData[0].AsInt() : 1;
var offset = (page -1) * pageSize;
IEnumerable<dynamic> queryResults;
//Request querystrings from URL
string selectQueryString = "SELECT * FROM Property_Info WHERE 0 = 0 AND NumBedrooms = #0 AND NumBathrooms = #1 ";
selectQueryString += "ORDER BY CreatedDate DESC";
queryResults = db.Query(selectQueryString, Request.QueryString["NumBedrooms"], Request.QueryString["NumBathrooms"]);
count = queryResults.Count();
totalPages = count/pageSize;
if(count % pageSize > 0){
totalPages += 1;
}
}

Well, there are lots of ways around the problem, I'm thinking the easiest one that doesn't involve not using named ordinal parameterization would be to use fixed ordinals for each search criteria and just not use the ones you don't need in the SQL statement. Your code is very long so I don't really want to try and rewrite the whole thing here, but basically if your db.Query() call has all of the potential arguments passed as parameters like this:
queryResults = db.Query(selectQueryString, Request.QueryString["searchTerm"], Request.QueryString["resortId"]).AsInt(), Request.QueryString["propertyType"].AsInt() /* etc etc */);
Then your ordinals are always the same number. searchTerm is always #0, resortId is always #1 etc, etc. You then don't need the array at all and just need to build up an appropriate SQL statement for what the user specified, for example some WHERE clauses that would all fit with the code above could be:
"WHERE ResortID = #1"
"WHERE PropertyType = #2"
"WHERE ResortID = #1 AND PropertyType = #2"
"WHERE Name = #0"
"WHERE Name = #0 AND ResortID = #1 AND PropertyType = #2"
In the case of the clauses that only use one or two of the parameters, the others are just ignored and hopefully everything will work as you intend.
Edit to show code:
// Basic beginning of the select statement
string selectQueryString = "SELECT * FROM Property_Info WHERE 0 = 0 ";
// Check to see if the user specified bedrooms, if they did add to the select statement
if (Request.QueryString["NumBedrooms"].AsInt() > 0)
{
selectQueryString += "AND NumBedrooms = #0 ";
}
// Same for the number of bathrooms
if (Request.QueryString["NumBathrooms"].AsInt() > 0)
{
selectQueryString += "AND NumBathrooms = #1 ";
}
// ** Add more criteria to your select list here by checking for valid values and concatenating your string **
// Finally add the order by on the end
selectQueryString += "ORDER BY CreatedDate DESC";
// Execute the statement
queryResults = db.Query(selectQueryString, Request.QueryString["NumBedrooms"].AsInt(), Request.QueryString["NumBathrooms"].AsInt());
This should give you a very flexible and expandable search criteria system that is happy with zero, one or many criteria.

Related

How to parse a valid JSON file that has non valid field inside?

I know that this may seem a strange question, but, the input of my algorithm is a stream of JSON strings composed by syntactically correct JSON blocks, at least for all blocks but this. A block in the stream has this structure:
{
"comment",
{
"author":"X",
"body":"Hello world",
"json_metadata":"{\"tags\":[\"hello, world\"],\"community\":\"programming\",\"app\":\"application_for_publish\"}",
"parent_author":"waggy6",
"parent_permlink":"programming_in_c",
"permlink":"re-author-programming_in_c-20180916t035418244z",
"title":"some_title"
}
}
So, everything works fine, up to arriving to this block, that I don't know how to parse. The field that gives me troubles is the "json_metadata" one:
{
"comment",
{
"author": "Y",
"body": "Hello another world!",
"json_metadata": "\"{\\\"tags\\\":[\\\"hello\\\",\\\"world\\\"],\\\"app\\\":\\\"application_for_publish_content\\\",\\\"format\\\":\\\"markdown+html\\\",\\\"pollid\\\":\\\"p_id\\\",\\\"image\\\":[\\\"https://un.useful.url/path/image.png\\\"]}\"",
"parent_author": "",
"parent_permlink": "helloworld",
"permlink": "hello_world_programming_in_c-2017319t94958596z",
"title": "Hello World in C!"
}
}
It's like this field has been parsed twice, when the data has been acquired.
I'm using rapidjson as parsing tool, in C++.
The piece of code related to this problem is the following:
static std::string parseNode(const Value &node){
string toret = "";
if (node.IsBool()) toret = toret + to_string(node.GetBool());
else if (node.IsInt()) toret = toret + to_string(node.GetInt());
else if (node.IsUint()) toret = toret + to_string(node.GetUint());
else if (node.IsInt64()) toret = toret + to_string(node.GetInt64());
else if (node.IsUint64()) toret = toret + to_string(node.GetUint64());
else if (node.IsDouble()) toret = toret + to_string(node.GetDouble());
else if (node.IsString()) toret = toret + node.GetString();
else if (node.IsArray()) toret = toret + parseArray(node); // parse the given array
else if (node.IsObject()) toret = toret + parseObject(node); // parse the given object
return toret;
}
...
std::string search_member(Value& js, std::string member){
Value::ConstMemberIterator itr = js.FindMember(member.c_str());
std::string els = "";
if(itr != js.MemberEnd())
els = parseNode(itr->value) + " ";
return els;
}
...
// op_struct type is Value*; it is the Value* that refers to all the fields of the block
std::string json_m = (*op_struct)["json_metadata"];
std::string elements = "";
if((json_m.compare("") != 0) && (json_m.compare("{}") != 0) && (json_m.compare("\"\"") != 0)){
Document js;
js.Parse<0>(json_m.c_str());
elements = elements + search_member(js, "community") + search_member(js, "tags") + search_member(js, "app");
}
Comment * comment = new Comment(title + " " + body + " " + elements, auth);
...
The problem occurs in the js.FindMember(member.c_str()); row, in the search_member() function, because js.Parse<0>(json_m.c_str()); recognizes that the input is a valid JSON, and indeed it is valid, it refers to:
"\"{\\\"tags\\\":[\\\"hello\\\",\\\"world\\\"],\\\"app\\\":\\\"application_for_publish_content\\\",\\\"format\\\":\\\"markdown+html\\\",\\\"pollid\\\":\\\"p_id\\\",\\\"image\\\":[\\\"https://un.useful.url/path/image.png\\\"]}\""
But, then, the result of this computation, is the string:
"{\"tags\":[\"hello\",\"world\"],\"app\":\"application_for_publish_content\",\"format\":\"markdown+html\",\"pollid\":\"p_id\",\"image\"
And for this reason, the FindMember() function can not find any tags, community or app field, since it is recognized as a string.
My question is: is there any way (different by just skipping this block) with which I can recognize such special cases?

Creating SO via Webservice says customerID does not exist

Hello I have created a routine to connect two Systems: XXXXWIN10 that is a local system with Acumatica. XXXWIN10 system have to send information about sales order to Acumatica. I'm using screen webservice in order to create a Sales Order. When I execute to test my code, each time I receive that customerID could not be empty but I'm sending all the information and also the customer exist. Do you see something wrong in my code:
using System;
using System.Net.Security;
using System.Net;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Conexionspa.apitest;
using System.Globalization;
namespace Conexionspa
{
class Program
{
static void Main(string[] args)
{
string CVECLI = "";
string CVEORDEN = "";
string FEC_ORDEN = "";
string DESCUENTO = "";
string CVESERVI = "";
string CANTIDAD = "";
decimal QTY = 0;
string PIEZAS = "";
string CAPA_REQ = "";
string CAPA_OBT = "";
string KILOS = "";
string TIPO_ACERO = "";
string RECIPIENTE = "";
string DUREZA_OBT = "";
string FEC_PROMES = "";
string PRECIOME = "";
decimal PRECIO = 0;
string IMPORTE = "";
string PORPIEZA = "";
string MONEDA = "";
string TIPOCAMBIO = "";
string PLANTA = "";
string conexion = #"Data Source = XXXXWIN10,2433; Initial Catalog = SYSXXXX; User ID = sa; Password = XXXYYYZZZ";
string queryString = "SELECT CVECLI, CVEORDEN, FEC_ORDEN, DESCUENTO, CVESERVI, CANTIDAD, PIEZAS, CAPA_REQ, CAPA_OBT, KILOS, TIPO_ACERO, RECIPIENTE, DUREZA_OBT, FEC_PROMES, PRECIOME, IMPORTE, PORPIEZA, MONEDA, TIPOCAMBIO, PLANTA FROM [Ordenes de Trabajo] WHERE STATUS = 2";
SqlConnection conection = new SqlConnection(conexion);
try
{
conection.Open();
SqlDataReader leeordenes = null;
SqlCommand Command = new SqlCommand(queryString, conection);
leeordenes = Command.ExecuteReader();
while (leeordenes.Read())
{
CVECLI = leeordenes["CVECLI"].ToString();
CVEORDEN = leeordenes["CVEORDEN"].ToString();
FEC_ORDEN = leeordenes["FEC_ORDEN"].ToString();
DateTime FECORDEN = DateTime.Parse(FEC_ORDEN);
DESCUENTO = leeordenes["DESCUENTO"].ToString();
CVESERVI = leeordenes["CVESERVI"].ToString();
CANTIDAD = leeordenes["CANTIDAD"].ToString();
decimal.TryParse(CANTIDAD, out QTY);
PIEZAS = leeordenes["PIEZAS"].ToString();
CAPA_REQ = leeordenes["CAPA_REQ"].ToString();
CAPA_OBT = leeordenes["CAPA_OBT"].ToString();
KILOS = leeordenes["KILOS"].ToString();
TIPO_ACERO = leeordenes["TIPO_ACERO"].ToString();
RECIPIENTE = leeordenes["RECIPIENTE"].ToString();
DUREZA_OBT = leeordenes["DUREZA_OBT"].ToString();
FEC_PROMES = leeordenes["FEC_PROMES"].ToString();
DateTime FECPROMES = DateTime.Parse(FEC_PROMES);
PRECIOME = leeordenes["PRECIOME"].ToString();
decimal.TryParse(PRECIOME, out PRECIO);
IMPORTE = leeordenes["IMPORTE"].ToString();
PORPIEZA = leeordenes["PORPIEZA"].ToString();
MONEDA = leeordenes["MONEDA"].ToString();
TIPOCAMBIO = leeordenes["TIPOCAMBIO"].ToString();
PLANTA = leeordenes["PLANTA"].ToString();
apitest.Screen context = new apitest.Screen();
context.CookieContainer = new CookieContainer();
context.AllowAutoRedirect = true;
context.EnableDecompression = true;
context.Timeout = 1000000;
context.Url = "http://localhost/XXXYYY/Soap/APITEST.asmx";
try
{
LoginResult result = context.Login("Admin#XXXYYY:P000", "AdminXXX");
}
catch(Exception ep)
{
Console.WriteLine("Error en las credenciales" + ep.Message );
}
try
{
SO301000Content SO301000 = context.SO301000GetSchema();
context.SO301000Clear();
SO301000Content[] SO301000result = context.SO301000Submit
(
new Command[]
{
new Value { Value = "SO", LinkedCommand = SO301000.OrderSummary.OrderType },
new Value { Value = "TADEO", LinkedCommand = SO301000.OrderSummary.Customer },
new Value { Value = "0000007", LinkedCommand = SO301000.OrderSummary.OrderNbr },
new Value { Value = CVEORDEN, LinkedCommand = SO301000.OrderSummary.ExternalReference },
new Value { Value = FEC_ORDEN, LinkedCommand = SO301000.OrderSummary.Date },
new Value { Value = CVESERVI, LinkedCommand = SO301000.DocumentDetails.InventoryID },
new Value { Value = CANTIDAD, LinkedCommand = SO301000.DocumentDetails.Quantity },
new Value { Value = PIEZAS, LinkedCommand = SO301000.OrderSummary.Description },
new Value { Value = CAPA_REQ + " " + CAPA_OBT + " " + KILOS + " " + TIPO_ACERO + " " + RECIPIENTE + " " + DUREZA_OBT, LinkedCommand = SO301000.DocumentDetails.LineDescription },
new Value { Value = FEC_ORDEN, LinkedCommand = SO301000.OrderSummary.RequestedOn },
new Value { Value = PRECIOME, LinkedCommand = SO301000.DocumentDetails.UnitPrice, Commit = true },
new Value { Value = "NA", LinkedCommand = SO301000.DocumentDetails.UOM },
new Value { Value = "USD", LinkedCommand = SO301000.OrderSummary.Currency },
new Value { Value = "AP3", LinkedCommand = SO301000.DocumentDetails.Warehouse },
SO301000.Actions.Save,
}
);
Console.WriteLine("Orden registrada");
Thread.Sleep(9000);
}
catch(Exception ex)
{
Console.WriteLine("Error al insertar O.T en Acumatica: " + ex.Message);
Thread.Sleep(5000);
}
}
}
catch (Exception mensaje)
{
Console.WriteLine("Error en las credenciales del SPA รณ Acumatica Web Service: " + mensaje);
Thread.Sleep(5000);
}
}
}
}
As far as I know, you should first set Order Type and Order Number, and only then all the other fields, i.e.
new Command[]
{
new Value { Value = "SO", LinkedCommand = SO301000.OrderSummary.OrderType },
new Value { Value = "0000007", LinkedCommand = SO301000.OrderSummary.OrderNbr },
new Value { Value = "TADEO", LinkedCommand = SO301000.OrderSummary.Customer },
//rest of fields
SO301000.Actions.Save,
}

Checking NULL values from Database using POCO

I'm making a query using POCO::Data with ODBC Connector, and I need to check for NULL values from code. In the documentation, the Recordset object is supposed to have the function isNull, but the code I download here does not contains such a method (version 1.4.6p4 right now).
How can I check then if a value is NULL with POCO library? I'm trying to create a JSON string with the data retrieved from database.
My actual code looks like this:
Session session(bdName, conn);
Statement select(session);
select << sSQL;
select.execute();
RecordSet rs(select);
bool more = rs.moveFirst();
std::size_t cols = rs.columnCount();
sResult = "{\"rowsField\":[";
while (more) {
if (sResult.back() != '[') sResult += ','; // Not first time
sResult += "{\"columnsField\":[";
for (std::size_t col = 0; col < cols; ++col) {
std::string cName = rs.columnName (col);
std::string tName = getPocoTypeName(rs.columnType(col));
std::string val = "";
if (!rs[col] || rs.value(col).isEmpty())
val = "NULL"; // DOES NOT WORK
else
val = rs[col].convert<std::string>();
if (col != 0) sResult += ',';
sResult += "\n{\"nameField\":\"" + cName + '\"';
sResult += ",\"typeField\":\"" + tName + '\"';
sResult += ",\"valueField\":\"" + val + '\"';
sResult += "}"; // each JSON column/value
}
sResult += "]}\n"; // columnsField (one per row)
more = rs.moveNext();
}
Use Nullable<std::string> val = std::string("");
isNull is a member of Nullable, so you will be able to check if the return value is null..
I know this is an old question but I have had issues with it. I am also formatting as JSON strings. You can use Poco::Recordset::IsNull(ColumnName) to check if a given column name's value is NULL or not.
The below code will replace NULLS with the empty string to prevent throwing errors:
Poco::Data::Statement statement(session);
statement << query;
statement.execute();
Poco::Data::RecordSet record_set(statement);
bool more = record_set.moveFirst();
while (more)
{
std::map<std::string, std::string> row;
for (std::size_t i = 0; i < record_set.columnCount(); ++i)
{
std::string val = "";
if(!record_set.isNull(record_set.columnName(i)))
val = record_set[i].convert<std::string>();
// print results for testing
cout << "->" << record_set.columnName(i) << ":{" << val << "}";
}
ret.push_back(row);
more = record_set.moveNext();
}
Use record_set[col].isEmpty() for checking NULL.

It's checking only firs row in table. help someone :) C# winForm

SqlConnection con = new SqlConnection(#"Data Source=(local)\SQLEXPRESS; Integrated Security= SSPI;" + "Initial Catalog = CarRent_vaxo;");
con.Open();
string strSQL = "select * from AccesList";
SqlCommand myCommand = new SqlCommand(strSQL, con);
using (SqlDataReader myDataReader = myCommand.ExecuteReader())
{
myDataReader.Read();
{
if (usertextBox.Text == myDataReader["User"].ToString() && paswordTextBox.Text == myDataReader["Password"].ToString())
{
this.Hide();
ResultForm rf = new ResultForm();
rf.Show();
}
else if (usertextBox.Text == "" || paswordTextBox.Text == "")
{
Notificarion2.Text = "PLEASE FILL THE BOXES !!!";
}
else
{
Notificarion2.Text = "WRONG USER OR PASSWORD !!!";
usertextBox.Text = "";
paswordTextBox.Text = "";
}
}
}
You should read from SqlDataReader in a while loop as
while (myDataReader.Read())
{
//your code goes here
}
myDataReader.Close();
http://msdn.microsoft.com/en-us/library/haa3afyz%28v=vs.110%29.aspx

C++ Binding keyboard keys: iterate over all virtual keys?

I'd like to be able to load custom key binds for my application. A configuration file would typically contain a list of keys and associated function names.
When I load this file, is there a way to iterate over all the possible virtual keys that would be listed inside the configuration file in the form:
for(int i = key0; i < keymax; i = i+key){
char key = itoa(i);
if(cfgfile.getfunction(key,function)){
_keyBinds[key] = function;
}
}
Or do I need to manually check for every one of them ?
This is the way I finally proceeded to create a map of the keyboard keys. It covers almost all possibilities: non-mappable keys are stored as a hex string, mappable keys which do not represent themselves as a single caracter need to be added manually. Maybe this can be usefull for someone in the future.
CreateKeyboardMap()
{
string keystring;
char keybuffer;
for(int i = 0; i < 256; ++i){
if(keybuffer = MapVirtualKey(UINT(i),2)){
keystring += keybuffer;
}
else{
keystring = int_to_hex(i);
}
_keyboardMap.insert(_keyboardMap.end(),pair<UINT,string>(i,keystring));
keystring = "";
}
_keyboardMap[0x1B] = "ESCAPE";
_keyboardMap[0x70] = "F1";
_keyboardMap[0x71] = "F2";
_keyboardMap[0x72] = "F3";
_keyboardMap[0x73] = "F4";
_keyboardMap[0x74] = "F5";
_keyboardMap[0x75] = "F6";
_keyboardMap[0x76] = "F7";
_keyboardMap[0x77] = "F8";
_keyboardMap[0x78] = "F9";
_keyboardMap[0x79] = "F10";
_keyboardMap[0x7A] = "F11";
_keyboardMap[0x7B] = "F12";
_keyboardMap[0x2C] = "PRINT SCREEN";
_keyboardMap[0x91] = "SCROLL LOCK";
_keyboardMap[0x08] = "BACKSPACE";
_keyboardMap[0x20] = "SPACE";
_keyboardMap[0x2D] = "INSERT";
_keyboardMap[0x24] = "HOME";
_keyboardMap[0x22] = "PAGE DOWN";
_keyboardMap[0x21] = "PAGE UP";
_keyboardMap[0x2E] = "DELETE";
_keyboardMap[0x90] = "NUMLOCK";
_keyboardMap[0x6F] = "NUMPAD /";
_keyboardMap[0x6A] = "NUMPAD *";
_keyboardMap[0x6D] = "NUMPAD -";
_keyboardMap[0x6B] = "NUMPAD +";
_keyboardMap[0x6E] = "NUMPAD .";
_keyboardMap[0x60] = "NUMPAD 0";
_keyboardMap[0x61] = "NUMPAD 1";
_keyboardMap[0x62] = "NUMPAD 2";
_keyboardMap[0x63] = "NUMPAD 3";
_keyboardMap[0x64] = "NUMPAD 4";
_keyboardMap[0x65] = "NUMPAD 5";
_keyboardMap[0x66] = "NUMPAD 6";
_keyboardMap[0x67] = "NUMPAD 7";
_keyboardMap[0x68] = "NUMPAD 8";
_keyboardMap[0x68] = "NUMPAD 9";
_keyboardMap[0x26] = "ARROW UP";
_keyboardMap[0x28] = "ARROW DOWN";
_keyboardMap[0x25] = "ARROW LEFT";
_keyboardMap[0x27] = "ARROW RIGHT";
_keyboardMap[0x0D] = "ENTER";
_keyboardMap[0xA0] = "LSHIFT";
_keyboardMap[0xA1] = "RSHIFT";
_keyboardMap[0x09] = "TAB";
_keyboardMap[0x14] = "CAPS LOCK";
_keyboardMap[0xA2] = "LCONTROL";
_keyboardMap[0xA3] = "RCONTROL";
_keyboardMap[0xA4] = "LALT";
_keyboardMap[0xA5] = "RALT";
_keyboardMap[0x5B] = "LWIN";
_keyboardMap[0x5C] = "RWIN";
}
In your routine that loads the contents of the file, you'll want to store the data in a map with the keycodes as the keys and function names as the values. Instead of iterating over all possible keycodes, then, just iterate over the entries in the map.