Replacing VAR datatype in .NET 2.0 - linq

I am using .NET 2.0, need to implement VAR datatype in here:
var doc = XDocument.Parse(result);
var sw = doc.Descendants("viewport").Elements("southwest").SingleOrDefault();
if (sw != null)
{
var lat = (double)sw.Element("lat");
var lng = (double)sw.Element("lng");
// do stuff
}
I used STRING instead
public string getLatLang(string address)
{
string latlang = "";
string url = "http://maps.googleapis.com/maps/api/geocode/xml?address=" + address + "&sensor=false";
System.Net.WebClient client = new System.Net.WebClient();
string result = client.DownloadString(url);
string doc = System.Xml.Linq.XDocument.Parse(result).ToString();
string sw = doc.Descendants("viewport").Elements("southwest").SingleOrDefault();
if (sw != null)
{
string lat = (double)sw.Element("lat");
string lng = (double)sw.Element("lng");
latlang = lat + "," + lang;
// do stuff
}
return latlang;
}
But I get an error :
'string' does not contain a definition for 'Descendants'
Please help me to replace VAR here.

To replace var, research the actual return type of the method and change it to that. For example, XDocument.Parse can be found on MSDN here In the documentation, it states "Creates a new XDocument from a string", therefore, the return type must be XDocument. And if you drill down into one of the method overloads (like this one), you'll see the actual method's signature which confirms that it does indeed return an XDocument.
Also, Visual Studio has intellisense, so if you hover over something you can generally get details about it. Try typing System.Xml.Linq.XDocument.Parse(, When you type the first paren, you should see a popup in Visual Studio that tells you what the return type is for the method you're using. If intellisense is not working, then check to make sure you have a reference to the DLL.
Also note that Visual Studio has what is known as Object Explorer. This will allow you to see the method signatures of each object you're working with which includes the return types. Simply right click on any object or method and select "Go To Definition". Hopefully, the Visual Studio version you're using has this, if not, consider upgrading because it's extremely useful.
public string getLatLang(string address)
{
string latlang = "";
string url = "http://maps.googleapis.com/maps/api/geocode/xml?address=" + address + "&sensor=false";
System.Net.WebClient client = new System.Net.WebClient();
string result = client.DownloadString(url);
XDocument doc = System.Xml.Linq.XDocument.Parse(result);
XElement sw = doc.Descendants("viewport").Elements("southwest").SingleOrDefault();
if (sw != null)
{
string lat = sw.Element("lat").Value;
string lng = sw.Element("lng").Value;
latlang = String.Format("{0},{1}", lat, lng);
// do stuff
}
return latlang;
}
Edit: Please note that this solution will not work in .NET 2.0 without some hacks due to LINQ and redistributing System.Core is against the EULA, so you'll likely have to change XDocument to XmlDocument and figure out how to integrate it with Google's return value. I believe it has a Load method, or LoadXml method, can't remember which one does which.

var in itself isnt a data type it just takes the data type from the other side of the equality operator. read more about it here
therefore replacing every var with string wont help you will have to use the correct data type instead of var if you cannot use a var.
error in your case is originating because you i think on this line string doc = System.Xml.Linq.XDocument.Parse(result).ToString(); when replacing var you should have used XDocument but instead you used a string to accomodate errors used a ToString() function.
Edit:- after the comment
public string getLatLang(string address)
{
string latlang = "";
string url = "http://maps.googleapis.com/maps/api/geocode/xml?address=" + address + "&sensor=false";
System.Net.WebClient client = new System.Net.WebClient();
string result = client.DownloadString(url);
XDocument doc = System.Xml.Linq.XDocument.Parse(result);
XElement sw = doc.Descendants("viewport").Elements("southwest").SingleOrDefault();
if (sw != null)
{
string lat = (double)sw.Element("lat").Value;
string lng = (double)sw.Element("lng").Value;
latlang = lat + "," + lang;
// do stuff
}
return latlang;
}

The var keyword is used to implicitly type variables. You're letting the compiler infer the type of your variables. But under the covers, once compilation occurs, variables are still assigned specific types.
What you've done wrong is call .ToString() on your XDocument. Now you just have one big string and you're attempting to treat it like it's still an XDocument.
Try this instead.
XDocument doc = System.Xml.Linq.XDocument.Parse(result);
XElement = doc.Descendants("viewport").Elements("southwest").SingleOrDefault();
Edit
Finally got in front of a computer with Visual Studio on it. You have a few more problems.
The following will compile in .NET 3.5+.
public string getLatLang(string address)
{
string latlang = "";
string url = "http://maps.googleapis.com/maps/api/geocode/xml?address=" + address + "&sensor=false";
System.Net.WebClient client = new System.Net.WebClient();
string result = client.DownloadString(url);
XDocument doc = System.Xml.Linq.XDocument.Parse(result);
XElement sw = doc.Descendants("viewport").Elements("southwest").SingleOrDefault();
if (sw != null)
{
string lat = sw.Element("lat").ToString();
string lng = sw.Element("lng").ToString();
latlang = lat + "," + lng;
// do stuff
}
return latlang;
}
(Notice that you were later explicitly casting values to double and still defining their types as string).
As for the error you mention in your comment, I'm not sure... the Elements<T>(IEnumerable<T>, XName) member is included in the extensions class of System.Xml.Linq (MSDN), so it should work. Make sure that you have also included the System.Linq directive with your other using directives:
using System.Linq;
As an aside, I actually don't see how a lot of the code you have written will work in .NET 2.0. The System.Xml.Linq and System.Linq namespaces weren't introduced until .NET 3.5. If you're really using .NET 2.0, then you may want to reference this thread for a work-around for the framework version you're using.

Ok ,Now I tried everything possible with .NET 2.0 ,I came up with this solution which I know is very low level coding but is the only possible solution with 2.0 , this works EXCELLENT FOR .NET 2.0 !!
public string getLatLang(string address)
{
string latlang = "";
string url = "http://maps.googleapis.com/maps/api/geocode/xml?address=" + address + "&sensor=false";
System.Net.WebClient client = new System.Net.WebClient();
string result = client.DownloadString(url);
int firstlat = result.IndexOf("<lat>");
int lastlat = result.IndexOf("</lat>");
int firstlng = result.IndexOf("<lng>");
int lastlng = result.IndexOf("</lng>");
string _latitude = result.Substring(firstlat+5, (lastlat-5) - firstlat);
string _longitude = result.Substring(firstlng+5, (lastlng-5) - firstlng);
latlang = _latitude + "," + _longitude;
return latlang;
}

Related

Access to wwwroot - Asp.Net Core MVC working well on local host but not in published app

I'm having a lot of trouble trying to get my App to work when
published. Basically, the code is supposed to create a doc from
template using Open XML sdk, then save to wwwroot and then upload to
blob storage.
It's working fine using local host. Have read and tried some stuff re
accessing static files - but nothing seems to work. Any help would be
very much appreciated. Relevant code is below:
[HttpGet]
public IActionResult GenerateDocxBrowser(MemoryStream mem, string filepath, string inputLastName, string inputTitle, string requestID, string dateReceived, string complaintType, string complaintDetails, string nameString, string no, string street, string town, string postcode)
{
var list = _context.Complaints.Where(s => s.ComplaintId.ToString().Contains(requestID)).ToList();
using (mem = new MemoryStream())
{
filepath = #"wwwroot\RequestTemplate.docx";
nameString = list.Select(s => s.NameString).FirstOrDefault();
complaintDetails = list.Select(s => s.Complaint).FirstOrDefault();
street = list.Select(s => s.AddressStreet).FirstOrDefault();
town = list.Select(s => s.AddressTown).FirstOrDefault();
using (WordprocessingDocument document = WordprocessingDocument.Open(filepath,true))
{
document.GetMergeFields("LastName").ReplaceWithText(inputLastName);
document.GetMergeFields("Title").ReplaceWithText(inputTitle);
document.GetMergeFields("ComplaintID").ReplaceWithText(requestID);
document.GetMergeFields("DateReceived").ReplaceWithText(dateReceived);
document.GetMergeFields("ComplaintType").ReplaceWithText(complaintType);
document.GetMergeFields("ComplaintDetails").ReplaceWithText(complaintDetails);
document.GetMergeFields("NameString").ReplaceWithText(nameString);
document.GetMergeFields("AddressLn1").ReplaceWithText(no + " " + street);
document.GetMergeFields("AddressLn2").ReplaceWithText(town + " TAS " + postcode);
document.SaveAs(#"wwwroot\" + requestID + ".docx");
document.MainDocumentPart.Document.Save();
document.Close();
}
}
const string StorageAccountName = "xxx";
const string StorageAccountKey = "xxxxxx";
var storageAccount = new CloudStorageAccount(
new StorageCredentials(StorageAccountName, StorageAccountKey), true);
var blobClient = storageAccount.CreateCloudBlobClient();
var container = blobClient.GetContainerReference("tasman/Request Images");
CloudBlockBlob blockBlob = container.GetBlockBlobReference(requestID + ".docx");
blockBlob.UploadFromFileAsync(#"wwwroot\" + requestID + ".docx");
return View();
}
Your .SaveAs() field should be relative, currently its literally saving to wwwroot somewhere on the drive. You can specify the relative path a few different ways - one of them is below:
var saveToFolder = Path.Combine(Environment.CurrentDirectory, $"/wwwroot/{requestID}.docx");

Connecting xamarin to woocommerce api

I'm trying to create my first app that will connect to a woocommerce api.
Has anyone any experience in this or can point me in the direction as to how to create a connection to pull in the product list?
Thanks
Since WooCommerce has a REST API, it should be fairly simple to connect using a plain HTTP request, or a library like RestSharp.
There is also a C# client for WooCommerce - I don't know if it plays well with Xamarin, you might need to modify it a bit to get it to build.
var api = new WoocommerceApiClient(StoreUrl, ConsumerKey, ConsumerSecret);
var result = await api.Products.Get();
It's an old post but I had faced a similar issue. I had tries WoocommerceSharp with Xamarin Studio 6.1.1 (mac version); I opened the .sln file, added the missing reference to system.net.http and it worked perfectly.
If you want make it work in PCL you have to use PCLCrypto in WoocommerceApiUrlGenerator.cs , here the updated version:
namespace SharpCommerce.Web
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using PCLCrypto;
internal class WoocommerceApiUrlGenerator
{
private const string SignatureMethod = "HMAC-SHA1";
private const string ApiV3RootEndpoint = "wc-api/v3/";
private readonly string baseURI;
private readonly string consumerKey;
private readonly string consumerSecret;
internal WoocommerceApiUrlGenerator(string storeUrl, string consumerKey, string consumerSecret)
{
if (
string.IsNullOrEmpty(consumerKey) ||
string.IsNullOrEmpty(consumerSecret) ||
string.IsNullOrEmpty(storeUrl))
{
throw new ArgumentException("ConsumerKey, consumerSecret and storeUrl are required");
}
this.consumerKey = consumerKey;
this.consumerSecret = consumerSecret;
// Need 'http://www.example.com' to be 'http://www.example.com/wc-api/v3/'
this.baseURI = String.Format("{0}/{1}", storeUrl.TrimEnd('/'), ApiV3RootEndpoint);
}
internal string GenerateRequestUrl(HttpMethod httpMethod, string apiEndpoint, Dictionary<string, string> parameters = null)
{
parameters = parameters ?? new Dictionary<string, string>();
parameters["oauth_consumer_key"] = this.consumerKey;
// oauth_timestamp = number of seconds since 1/1/1970 00:00:00 GMT
// must be a positive integer
// must be greater than timestamp of previous requests
parameters["oauth_timestamp"] =
Math.Round(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds).ToString(CultureInfo.InvariantCulture);
// oauth_nonce = a unique random string for the timestamp.
// defends against replay attacks
// service provide will know that this request has never been made before.
// Just going to hash the time stamp.
//parameters["oauth_nonce"] = GenerateNonce(parameters["oauth_timestamp"]);
// Create random 32 char alphnumeric to avoid reused nonces
parameters["oauth_nonce"] = GenerateNonce();
// Declare the hashing method your using
parameters["oauth_signature_method"] = SignatureMethod;
//parameters["oauth_version"] = "1.0";
parameters["oauth_signature"] = UpperCaseUrlEncode(this.GenerateSignature(httpMethod, apiEndpoint, parameters));
var sb = new StringBuilder();
foreach (var pair in parameters)
{
sb.AppendFormat("&{0}={1}", SafeUpperCaseUrlEncode(pair.Key), SafeUpperCaseUrlEncode(pair.Value));
}
// Substring removes first '&'
var queryString = sb.ToString().Substring(1);
var url = this.baseURI + apiEndpoint + "?" + queryString;
return url;
}
private string GenerateSignature(HttpMethod httpMethod, string apiEndpoint, Dictionary<string, string> parameters)
{
// 1) Set the HTTP method for the request.
// set through 'method'
//2) Set your base request URI – this is the full request URI without query string parameters – and URL encode according to RFC 3986:
// need 'http://www.example.com/wc-api/v3/orders'
// to become: 'http%3A%2F%2Fwww.example.com%2Fwc-api%2Fv1%2Forders'
var encodedBaseRequestURI = SafeUpperCaseUrlEncode(this.baseURI + apiEndpoint);
// 3) Collect and normalize your query string parameters
// percent(%) characters should be double-encoded (e.g. % becomes %25.
var normalizedParameters = NormalizeParameters(parameters);
// 4) Sort the parameters in byte-order
var orderedNormalizedParameters = normalizedParameters.OrderBy(x => x.Key).ToList();
// 5) Join each parameter with an encoded equals sign (%3D):
//var joinedOrderedNormalizedParameters = orderedNormalizedParameters.ConvertAll(x => x.Key + "%3D" + x.Value);
var joinedOrderedNormalizedParameters = new List<string>();
foreach (var x in orderedNormalizedParameters)
{
joinedOrderedNormalizedParameters.Add(x.Key + "%3D" + x.Value);
}
// 6) Join each parameter key/value pair with an encoded ampersand (%26):
var joinedParameterPairs = String.Join("%26", joinedOrderedNormalizedParameters);
// 7) Form the string to sign by joining the HTTP method, encoded base request URI, and encoded parameter string with an unencoded ampersand symbol (&):
var stringToSign = string.Format("{0}&{1}&{2}", httpMethod.ToString().ToUpper(), encodedBaseRequestURI, joinedParameterPairs);
// 8) Generate the signature using the string to key and your consumer secret key
var preparedStringToSign = Encoding.UTF8.GetBytes(stringToSign);
var secret = this.consumerSecret + "&";
var preparedConsumerKey = Encoding.UTF8.GetBytes(secret);
var signatureHash = Sha1(preparedConsumerKey, preparedStringToSign);
var signatureString = Convert.ToBase64String(signatureHash);
return signatureString;
}
private static byte[] Sha1(byte[] key, byte[] message)
{
var mac = WinRTCrypto.MacAlgorithmProvider.OpenAlgorithm(MacAlgorithm.HmacSha1);
//var keyMaterial = WinRTCrypto.CryptographicBuffer.ConvertStringToBinary(key, Encoding.UTF8);
var cryptoKey = mac.CreateKey(key);
var hash = WinRTCrypto.CryptographicEngine.Sign(cryptoKey, message);
return hash;
//return WinRTCrypto.CryptographicBuffer.CreateFromByteArraymessage);
}
private static Dictionary<string, string> NormalizeParameters(Dictionary<string, string> parameters)
{
var result = new Dictionary<string, string>();
foreach (var pair in parameters)
{
var upperCaseUrlEncodedKey = SafeUpperCaseUrlEncode(pair.Key);
var normalizedKey = upperCaseUrlEncodedKey.Replace("%", "%25");
var upperCaseUrlEncodedValue = SafeUpperCaseUrlEncode(pair.Value);
var normalizedValue = upperCaseUrlEncodedValue.Replace("%", "%25");
result.Add(normalizedKey, normalizedValue);
}
return result;
}
private static string SafeUpperCaseUrlEncode(string stringToEncode)
{
return UpperCaseUrlEncode(System.Net.WebUtility.UrlDecode(stringToEncode));
}
private static string UpperCaseUrlEncode(string stringToEncode)
{
var basicUrlEncodedString = System.Net.WebUtility.UrlEncode(stringToEncode);
if (String.IsNullOrEmpty(basicUrlEncodedString)) return String.Empty;
var upperCaseUrlEncodedString = Regex.Replace(
basicUrlEncodedString,
"(%[0-9a-f][0-9a-f])",
c => c.Value.ToUpper());
return upperCaseUrlEncodedString;
}
private static string GenerateNonce()
{
const string ValidChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var random = new Random();
var nonceString = new StringBuilder();
for (var i = 0; i < 32; i++)
{
nonceString.Append(ValidChars[random.Next(0, ValidChars.Length - 1)]);
}
return nonceString.ToString();
}
}
}
and in WoocommerceApiDriver.cs you will have to replace
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
return await client.GetStringAsync(url);
}
by
using (var client = new HttpClient()) // must use to avoid Android freezes after repeated calls
{
Task<HttpResponseMessage> r = client.GetAsync(url);
HttpResponseMessage m = r.Result;
return await m.Content.ReadAsStringAsync();
}
Et voila ! ca marche ;)

HtmlAgility Pack get single node get null value

I am trying to get a single node with an XPath, but i am getting a null value on the node, don' t know why
WebClient wc = new WebClient();
string nodeValue;
string htmlCode = wc.DownloadString("http://www.freeproxylists.net/fr/?c=&pt=&pr=&a%5B%5D=0&a%5B%5D=1&a%5B%5D=2&u=50");
HtmlAgilityPack.HtmlDocument html = new HtmlAgilityPack.HtmlDocument();
html.LoadHtml(htmlCode);
HtmlNode node = html.DocumentNode.SelectSingleNode("//table[#class='DataGrid']/tbody/tr[#class='Odd']/td/a");
nodeValue = (node.InnerHtml);
I see at least 2 mistakes in your xpath compared to the html you're trying to get information from.
There are no <a> that has <tr class=Odd"> as an ancestor.
Even if your Xpath had worked then you would only have gotten one <td> since you have decided to SelectSingleNode instead of SelectNodes
It looks like the are doing some kind of lazy protection from what you're trying to do. Since the a-tag is just represented in hexadecimal enclosed in IPDecode. So really it is no problem to extract the link. But the least you could have done was to look at the html before posting. You clearly have not tried at all. Since the html you're getting from your current code is not the <body> of the link you gave us - meaning you have to get the htmlpage from the absolute url or just use Selenium.
But since I am such a swell guy I will make your entire solution for you using Xpath, Html Agility Pack and Selenium. The following solutions gets the html of the site. then reads only the <tr> that has class="Odd". After that it finds all the "encrypted" <a> and decodes them into a string and writes them into an array. After that there is a small example of how to get an attribute value from one anchor.
private void HtmlParser(string url)
{
HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
htmlDoc.OptionFixNestedTags=true;
GetHTML(url);
htmlDoc.Load("x.html", Encoding.ASCII, true);
HtmlNodeCollection nodes = htmlDoc.DocumentNode.SelectNodes("//table[#class='DataGrid']/descendant::*/tr[#class='Odd']/td/script");
List<string> urls = new List<string>();
foreach(HtmlNode x in nodes)
{
urls.Add(ConvertStringToUrl(x.InnerText));
}
Console.WriteLine(ReadingTheAnchor(urls[0]));
}
private string ConvertStringToUrl(string octUrl)
{
octUrl = octUrl.Replace("IPDecode(\"", "");
octUrl = octUrl.Remove(octUrl.Length -2);
octUrl = octUrl.Replace("%", "");
string ascii = string.Empty;
for (int i = 0; i < octUrl.Length; i += 2)
{
String hs = string.Empty;
hs = octUrl.Substring(i,2);
uint decval = System.Convert.ToUInt32(hs, 16);
char character = System.Convert.ToChar(decval);
ascii += character;
}
//Now you get the <a> containing the links. which all can be read as seperate html files containing just a <a>
Console.WriteLine(ascii);
return ascii;
}
private string ReadingTheAnchor(string anchor)
{
//returns url of anchor
HtmlDocument anchorHtml = new HtmlAgilityPack.HtmlDocument();
anchorHtml.LoadHtml(anchor);
HtmlNode h = anchorHtml.DocumentNode.SelectSingleNode("a");
return h.GetAttributeValue("href", "");
}
//using OpenQA.Selenium; using OpenQA.Selenium.Firefox;
private void GetHTML(string url)
{
using (var driver = new FirefoxDriver())
{
driver.Navigate().GoToUrl(url);
Console.Clear();
System.IO.File.WriteAllText("x.html", driver.PageSource);
}
}

What exactly am I sending through the parameters?

When doing a XMLHttpRequest and using POST as the form method, what exactly am I sending? I know it should be like send(parameters), parameters = "variable1=Hello", for example. But what if I want to do this:
parameters = "variable1=" + encodeURIComponent(document.getElementById("variable1").value);
variable1 being the id of the HTML form input.
Can I do it like this or do I need to assign the encodeURIComponent value to a javascript variable and send that variable:
var variable2;
parameters = "variable2=" + encodeURIComponent(document.getElementById("variable1").value);
You're suppose to send the object and it's value, but, is it an object from the HTML form, a javascript object or a php object? The problem is I already tried it and I still can't get the encoded input in my database, all I get is the raw input from the user.
BTW, I know it's a pretty dull question, but I feel the need to understand exactly what I'm doing if I want to come up with a solution.
g
function createObject()
{
var request_type;
var browser = navigator.appName;
if(browser == "Microsoft Internet Explorer")
{
request_type = new ActiveXObject("Microsoft.XMLHTTP");
}
else
{
request_type = new XMLHttpRequest();
}
return request_type;
}
var http = createObject();
//INSERT
function insert()
{
var Faculty2 = encodeURIComponent(document.getElementById("Faculty").value);
var Major2 = encodeURIComponent(document.getElementById("Major").value);
var Professor2 = encodeURIComponent(document.getElementById("Professor").value);
var Lastname2 = encodeURIComponent(document.getElementById("Lastname").value);
var Course2 = encodeURIComponent(document.getElementById("Course").value);
var Comments2 = encodeURIComponent(document.getElementById("Comments").value);
var Grade2 = encodeURIComponent(document.getElementById("Grade").value);
var Redflag2 = encodeURIComponent(document.getElementById("Redflag").value);
var Owner2 = encodeURIComponent(document.getElementById("Owner").value);
//Location and parameters of data about to be sent are defined
//Required: verify that all fields are not empty. Use encode URI() to solve some issues about character encoding.
var params = "Faculty=" + Faculty2 + "&Major=" + Major2 + "&Professor=" + Professor2 + "&Lastname=" + Lastname2 + "&Course=" + Course2 + "&Comments=" + Comments2 + "&Grade=" + Grade2 + "&Redflag=" + Redflag2 + "&Owner=" + Owner2;
var url = "prehp/insert.php";
http.open("POST", url, true);
//Technical information about the data
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
//Now, we send the data
http.onreadystatechange = function()
{
if(http.readyState == 4)
{ var answer = http.responseText;
document.getElementById('insert_response').innerHTML = "Ready!" + answer;
}
else
{document.getElementById('insert_response').innerHTML = "Error";
}}
http.send(params);
}
PHP code:
$insertAccounts_sql = "INSERT INTO Information (Faculty, Major, Professor, Lastname, Course, Comments, Grade, Redflag, Owner)
VALUES('$_POST[Faculty]','$_POST[Major]','$_POST[Professor]','$_POST[Lastname]','$_POST[Course]','$_POST[Comments]','$_POST[Grade]','$_POST[Redflag]','$_POST[Owner]')";
$dbq = mysql_query($insertAccounts_sql, $dbc);
if($dbq)
{
print "1 record added: Works very well!";
}
else
if(!$dbq)
{
die('Error: ' . mysql_error());
}
$dbk = mysql_close($dbc);
if($dbk)
{
print "Database closed!";
}
else
if(!$dbk)
{
print "Database not closed!";
}
I did that but the value that the database got was the raw input and not the encoded input. I'm running out of ideas, don't know what else to try. Could it be the settings of the database, can the database be decoding the input before storing it? That seems far-fetched to me, but I've been looking at this from all angles and still can't come up with a fresh answer.
PS: Sorry for posting my comments on the answer area, first timer here.
when creating query strings, it has really nothing to do with objects or anything like that. All you want to be sending is key/value pairs. how you construct that is up to you, but it often neater and more manageable to assign your values to variables first. i.e.
var myVar1Value = encodeURIComponent(document.getElementById('variable1').value);
var myVar2Value = encodeURIComponent(document.getElementById('variable2').value);
var url = "http://www.mydomain.com?" + "var1=" + myVar1Value + "&var2=" + myVar2Value;
It's called a query string, so it's just a string. what you do with it on the server side is what makes the 'magic' happen.
edit: If you're having problems with values, then you should print them to console to verify you are getting what you expect.

Linq to Sql - Repository Pattern - Dynamic OrderBy

Ok, I found this, which will allow me to do this:
public IList<Item> GetItems(string orderbyColumn)
{
return _repository.GetItems().OrderBy(orderByColumn).ToList();
}
Is this the best way to do "dynamic" ordering? I want to be able to pass the column name as a string (and the sort direction) to my Service, and have it order the correct way.
That's certainly a viable way of doing dynamic sorting. Ch00k provided another option in his answer to this question about "Strongly typed dynamic Linq sorting". I personally prefer Ch00k's method, as there's some compile-time checking involved and there's very little extra code involved.
If you've already decided that it must be a string, then your options are somewhat limited. The Dynamic LINQ library would indeed do the job, or if you want t know how it all works, look at this previous answer which builds an Expression from the string at runtime.
At the moment the code only accepts a single member and has separate methods for ascending / descending, but from this example it should be fairly simple to pass a more complex string and split it; essentially as:
IQueryable<T> query = ...
string[] portions = orderBy.Split(' '); // split on space, arbitrarily
if(portions.Length == 0) throw new ArgumentException();
IOrderedQueryable<T> orderedQuery = query.OrderBy(portions[0]);
for(int i = 1 ; i < portions.Length ; i++) { // note we already did the zeroth
orderedQuery = orderedQuery.ThenBy(portions[i]);
}
return orderedQuery;
If you're just after dynamic sorting without the full Dynamic-Linq stuff you can check out a post I wrote about this a while back: click
EDIT: I don't really blog anymore so here's the actual extension method:
public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string sortExpression) where TEntity : class
{
if (string.IsNullOrEmpty(sortExpression))
return source; // nothing to sort on
var entityType = typeof(TEntity);
string ascSortMethodName = "OrderBy";
string descSortMethodName = "OrderByDescending";
string[] sortExpressionParts = sortExpression.Split(' ');
string sortProperty = sortExpressionParts[0];
string sortMethod = ascSortMethodName;
if (sortExpressionParts.Length > 1 && sortExpressionParts[1] == "DESC")
sortMethod = descSortMethodName;
var property = entityType.GetProperty(sortProperty);
var parameter = Expression.Parameter(entityType, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExp = Expression.Lambda(propertyAccess, parameter);
MethodCallExpression resultExp = Expression.Call(
typeof(Queryable),
sortMethod,
new Type[] { entityType, property.PropertyType },
source.Expression,
Expression.Quote(orderByExp));
return source.Provider.CreateQuery<TEntity>(resultExp);
}

Resources