Cant call static list from codebehind - c#

I'm kinda new to programming... And having trouble finding any documentation regarding this eksampel
Ive managed to call this webservice from a console application, with no problem.
I'm now trying to call the same service from รก webformes soulution. Ive placed the classes in the app_code folder.
I have defiend the JobOfferService class.. But when im trying to call the GetJobOffers() in the class, i not finding it ?
JobOfferService js = new JobOfferService();
protected void Page_Load(object sender, EventArgs e)
{
js. ?? - Error right here??
}
public class JobOfferService
{
private const string Url = "https://www.xxx.com/api/v1/xxxxxx/";
public static List<JobOffer> GetJobOffers()
{
using (var client = new WebClient())
{
client.Headers.Add("Accept", "application/json; charset=utf-8");
client.Encoding = Encoding.UTF8;
var response = client.DownloadString(Url);
var jobOffers = JsonConvert.DeserializeObject<List<JobOffer>>(response);
return jobOffers;
}
}
}
public class JobOffer
{
public string Id { get; set; }
public string EmployerName { get; set; }
public string Title { get; set; }
public string Text { get; set; }
public string ContactInfo { get; set; }
public DateTime ValidTo { get; set; }
}

As it's a static method, you should be able to do
var jobOffers = JobOfferService.GetJobOffers();

Make GetJobOffers() method a instance method. Just remove static keyword.
Or make JobOfferService class static too.

Related

Passing json object data from a ListView SelectedItem

I need some help with passing the ListView Tapped Id (which I get from a json).
I populate the listView with an API call to a server:
private async void searchButton_Click(object sender, RoutedEventArgs e)
{
var textFrom = odTextBox.Text;
var textTo = doTextBox.Text;
var searchResult = await PrevoziApi.SearchRidesAsync(textFrom, textTo, datePicker.Date.UtcDateTime);
var array = searchResult.CarshareList
.OrderBy(cs => cs.Time)
.Select(cs => cs.Contact + " " + cs.Time)
.ToArray();
listView.ItemsSource = array;
}
Now, when I click on an item of listView, I want to navigate to another page(CarShareDetailedPage) and make another call to the API, to get more detailed data about that item. So I need to pass the selectedItem id from one page to other. How do I do that ?
I'm navigating to another page like this:
private void listView_Tapped(object sender, TappedRoutedEventArgs e)
{
Frame.Navigate(typeof(CarShareDetailedPage), listView.SelectedIndex);
}
The OnNagiatedMethod on that page is:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var value = e.ToString();
carShareTextBox.Text = value;
}
And my json class is:
public class CarshareList
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("from_id")]
public string FromId { get; set; }
[JsonProperty("from_country")]
public string FromCountry { get; set; }
[JsonProperty("from_country_name")]
public string FromCountryName { get; set; }
[JsonProperty("to_id")]
public string ToId { get; set; }
[JsonProperty("to")]
public string To { get; set; }
[JsonProperty("to_country")]
public string ToCountry { get; set; }
[JsonProperty("to_country_name")]
public string ToCountryName { get; set; }
[JsonProperty("time")]
public string Time { get; set; }
[JsonProperty("date_iso8601")]
public DateTime DateIso8601 { get; set; }
[JsonProperty("added")]
public DateTime Added { get; set; }
[JsonProperty("price")]
public double? Price { get; set; }
[JsonProperty("num_people")]
public double NumPeople { get; set; }
[JsonProperty("author")]
public string Author { get; set; }
[JsonProperty("is_author")]
public string IsAuthor { get; set; }
[JsonProperty("comment")]
public string Comment { get; set; }
[JsonProperty("contact")]
public string Contact { get; set; }
[JsonProperty("date")]
public string Date { get; set; }
[JsonProperty("full")]
public string Full { get; set; }
[JsonProperty("insured")]
public string Insured { get; set; }
[JsonProperty("share_type")]
public string ShareType { get; set; }
[JsonProperty("confirmed_contact")]
public string ConfirmedContact { get; set; }
[JsonProperty("bookmark")]
public object Bookmark { get; set; }
[JsonProperty("from")]
public string From { get; set; }
}
public class CarshareResponse
{
[JsonProperty("search_type")]
public string SearchType { get; set; }
[JsonProperty("carshare_list")]
public IList<CarshareList> CarshareList { get; set; }
}
Let me say this is the first time ever I'm doing any work with Apis and json.
Thanks for your help!
EDIT: I added the code for the API below, so this now should be all the code I have.
public class PrevoziApi
{ public static async Task<CarshareResponse> SearchRidesAsync(
string fromCity,
string toCity,
DateTime date,
string type = "shares",
CancellationToken token = default(CancellationToken))
{
using (var client = new RestClient("https://prevoz.org/api/"))
{
var request = new RestRequest("search/" + type + "/", HttpMethod.Get);
request.AddQueryParameter("f", fromCity);
request.AddQueryParameter("fc", "SI");
request.AddQueryParameter("t", toCity);
request.AddQueryParameter("tc", "SI");
request.AddQueryParameter("d", date.ToString("yyyy-MM-dd"));
request.AddQueryParameter("exact", "true");
return
(await client.Execute<CarshareResponse>(request, token)).Data;
}
}
}
So with this, you are ordering by the time but displaying a string only that says "[Contact] [Time]". This in-and-of-itself does not hold any relation to the JSON that was returned from your search method. What you'll want to do is instead of making it an array, instead making a List<> object that can store some additional "background" data about that request to send off.
This will require a bit more effort though on your end. You will want to create a class
public class CarItemView {
public string DisplayText {get; set;}
public int ID {get; set;}
}
and fill it with whatever data you want to pass along. Then in your filtering you would do:
List<CarItemView> array = searchResult.CarshareList
.OrderBy(cs => cs.Time)
.Select(cs => new { DisplayText = cs.Contact + " " + cs.Time, ID = cs.Id}).ToList();
You will then, in your XAML, have to add a template to your listview for display. (Note, this is a real rough outline for a XAML Template)
<ListView>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding DisplayText}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
NOW when you get your selected item changed event fired, you can handle it and get the ID.
private void listView_Tapped(object sender, TappedRoutedEventArgs e)
{
var obj = (CarItemView) listView.SelectedItem; // convert item to our new class
Frame.Navigate(typeof(CarShareDetailedPage), obj.Id.ToString()); // send ID as string
}
Then for the receiving page:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var value = e.ToString();
carShareTextBox.Text = value; // will show the ID number
var caritemret = /* write a new restful function to return based on ID */
}
UPDATE: This answer was updated from original to reflect the use of an array instead of a list<> object
I hope this helps!
This works:
private async void searchButton_Click(object sender, RoutedEventArgs e)
{
var textFrom = odTextBox.Text;
var textTo = doTextBox.Text;
var searchResult = await PrevoziApi.SearchRidesAsync(textFrom, textTo, datePicker.Date.UtcDateTime);
List<CarItemView> array = searchResult.CarshareList
.OrderBy(cs => cs.Time)
.Select(cs => new CarItemView { DisplayText = cs.Contact + " " + cs.Time, Id = cs.Id })
.ToList();
listView.ItemsSource = array;
}
private void listView_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
{
var obj = (CarItemView)listView.SelectedItem; // convert item to our new class
Frame.Navigate(typeof(CarShareDetailedPage), obj.Id); // send ID as string
}
And on navigated to method on the destination page:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var value = e.Parameter.ToString();
carShareTextBox.Text = value; // will show the ID number
/* write a new restful function to return based on ID */
}
Thanks #daniel, it was mostly as you suggested, with a few errors, but with the help of some guys at the c# chat channel I managed. Thanks to all.

Add root element to json serialization in C#

I am creating a webservice to interact with a JSON API.
This API needs me to set a root element in the string, but I just cannot get this to happen.
The place where it all happens - right now just made to just show me the json output:
public static string CreateServiceChange(ServiceChange change)
{
string json = JsonConvert.SerializeObject(change);
return json;
}
This is the ServiceChange class:
public class ServiceChange
{
[JsonProperty("email")]
public string requesterEmail { get; set; }
[JsonProperty("description_html")]
public string descriptionHtml { get; set; }
[JsonProperty("subject")]
public string subject { get; set; }
[JsonProperty("change_type")]
public int changeType { get; set; }
}
And the method binding those two together:
public string copyTicketToChange(int ticketId)
{
HelpdeskTicket.TicketResponseActual ticket = getHelpdeskTicket(ticketId);
ServiceChange change = new ServiceChange();
change.descriptionHtml = ticket.Response.DescriptionHtml;
change.requesterEmail = ticket.Response.Email;
change.subject = ticket.Response.Subject;
change.changeType = 1;
string Response = Dal.CreateServiceChange(change);
return Response;
}
The json output looks like this right now:
{"email":"test#test.com","description_html":"This is a test","subject":"Testing","change_type":1}
And the expected output:
{ "itil_change": {"email":"test#test.com","description_html":"This is a test","subject":"Testing","change_type":1}}
How can I achieve this?
Wrap your ServiceChange into another object and serialize it:
public class ServiceChangeWrapper
{
public ServiceChange itil_change { get; set; }
}
...
public static string CreateServiceChange(ServiceChange change)
{
ServiceChangeWrapper wrapper = new ServiceChangeWrapper { itil_change = change};
string json = JsonConvert.SerializeObject(wrapper);
return json;
}

Adding model object to list fails

I have a model class like this
namespace ConnectBLL.DTO.Response
{
public class CategorySettings
{
public bool NeedsLoginToViewLongText { get; set; }
public bool NeedsLoginToViewAnyDetails { get; set; }
public bool ShowAttachment { get; set; }
public string CategoryPageID { get; set; }
public string TpUrl { get; set; }
}
public class CategorySettingsListResponse
{
public List<CategorySettings> CategorySettingsList { get; set; }
}
}
And I am trying to add data to it like this
private readonly CategorySettings cs = new CategorySettings();
CategorySettingsListResponse csr=new CategorySettingsListResponse();
public string GetAllCategorySettings()
{
cs.NeedsLoginToViewLongText = true;
cs.NeedsLoginToViewAnyDetails = false;
cs.ShowAttachment = true;
cs.CategoryPageID = "1";
cs.TpUrl = "url";
csr.CategorySettingsList.Add(cs);
}
But this fails and gives an error
Object reference not set to an instance of an object.
Can any one point out what is I am doing wrong?
Somewhere, you need to initialize CategorySettingsList.
public class CategorySettingsListResponse
{
CategorySettingsListResponse() {
CategorySettingsList = new List<CategorySettings>();
}
public List<CategorySettings> CategorySettingsList { get; set; }
}
You are tying to use an instance of List before initializing. Before
csr.CategorySettingsList.Add(cs);
Insert:
if (csr.CategorySettingsList == null) {
csr.CategorySettingsList = new List<CategorySettings>();
}
You are using uncreated objects cs and CategorySettingsList, you should create them before use:
public string GetAllCategorySettings()
{
csr.CategorySettingsList = new ListCategorySettings<>();
var cs = new CategorySettings
{
NeedsLoginToViewLongText = true,
...
What is cs? Something missing?
You forgot to do this:
var cs = new CategorySettings();
Also
You need to instantiate the CategorySettingsList in constructor for CategorySettingsListResponse.

why instance variable returns null in c#? [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I have created a class and a global variable named as telephoneNumber. This variable is set in a method and used in another method. However this variable returns null. All methods and this global variable in the same class. Please help to understand this problem. Thanks a lot. My class is :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Net.Http;
using Newtonsoft.Json;
using System.Collections;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private string telephoneNumber;
private async void GetSingleLocationInfo(string href)
{
var hereNetUrl = string.Format(
href+"&accept=application/json"
);
// get data from HERE.net REST API
var httpClient = new HttpClient();
var hereNetResponse = await httpClient.GetStringAsync(hereNetUrl);
// deseralize JSON from Here.net
using (var tr = new StringReader(hereNetResponse))
using (var jr = new JsonTextReader(tr))
{
var rootObjectResponse = new JsonSerializer().Deserialize<Object>(jr);
String contacts = rootObjectResponse.ToString();
int startIndex = contacts.IndexOf("phone");
if (startIndex != -1)
{
String value = contacts.Substring(startIndex, 50);
telephoneNumber=value.Substring(value.IndexOf("+"));
}
else
{
telephoneNumber="";
}
}
}
private async void GeocodingWin8Query()
{
// build URL for Here.net REST service
string currentgeoLoc = "37.75075,-122.393472";
string queryString = "taxi";
string appID = "dV04O71v5F3f2W"; // MAKE SURE TO GET YOUR OWN from developers.here.net
object appCode = "8QVr5uSXwfcowDrA"; // MAKE SURE TO GET YOUR OWN from developers.here.net
var hereNetUrl = string.Format(
"http://demo.places.nlp.nokia.com/places/v1/discover/search?at={0}&q={1}&app_id={2}&app_code={3}&accept=application/json",
currentgeoLoc, queryString, appID, appCode);
// get data from HERE.net REST API
var httpClient = new HttpClient();
var hereNetResponse = await httpClient.GetStringAsync(hereNetUrl);
// deseralize JSON from Here.net
using (var tr = new StringReader(hereNetResponse))
using (var jr = new JsonTextReader(tr))
{
var rootObjectResponse = new JsonSerializer().Deserialize<RootObject>(jr);
List<Item> items=rootObjectResponse.results.items;
foreach(Item item in items){
string href = item.href;
GetSingleLocationInfo(href);
Console.WriteLine (telephoneNumber);//returns null
}
}
}
private void button1_Click(object sender, EventArgs e)
{
GeocodingWin8Query();
}
}
public class Category
{
public string id { get; set; }
public string title { get; set; }
public string href { get; set; }
public string type { get; set; }
}
public class Item
{
public List<double> position { get; set; }
public int distance { get; set; }
public string title { get; set; }
public Category category { get; set; }
public string icon { get; set; }
public string vicinity { get; set; }
public List<object> having { get; set; }
public string type { get; set; }
public string href { get; set; }
public string id { get; set; }
public double? averageRating { get; set; }
}
public class Context
{
public Location location { get; set; }
public string type { get; set; }
}
public class Search
{
public Context context { get; set; }
}
public class RootObject
{
public Results results { get; set; }
public Search search { get; set; }
}
}
So, where you call GetSingleLocationInfo, you are calling an async method. GetSingleLocationInfo calwill therefore run as far as the await statement then return stright to the caller, before the it httpClient.GetStringAsync(hereNetUrl); has returned.
To fix this, you need to await on your call GetSingleLocationInfo before trying to access the variable.
Since GetSingleLocationInfo is async it will be called asynchronously, so the Console.WriteLine (telephoneNumber); will be called before the GetSingleLocationInfo change it.
I think you should put an await when calling the method.
String.Substring returns NULL when no string found.
It's going to be "returning" null quite simply because telephoneNumber hasn't been set yet.
Your declaration of the variable private string telephoneNumber; doesn't set any value thus it is an empty string or null.
My guess would be your method where you print it out is being called before the method where you actually set telephoneNumber to have a value.

Can't deserialize json using json.net

This is my first time using json.net and I can't figure it out. Here is my code below.
// Constructor
public MainPage()
{
InitializeComponent();
}
private void btnRefreshTweets_Click(object sender, RoutedEventArgs e)
{
string ServerURL = #"http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StateCityHighway_USA/MapServer/1/query?text=e&geometry=&geometryType=esriGeometryPoint&inSR=&spatialRel=esriSpatialRelIntersects&relationParam=&objectIds=&where=&time=&returnCountOnly=false&returnIdsOnly=false&returnGeometry=false&maxAllowableOffset=&outSR=&outFields=&f=json";
WebClient webClient = new WebClient();
webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
webClient.DownloadStringAsync(new Uri(ServerURL));
}
void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error != null)
{
return;
}
List<Attributes> tweets = JsonConvert.DeserializeObject<List<Attributes>>(e.Result);
this.lbTweets.ItemsSource = tweets;
}
public class Attributes
{
public string STATE_NAME { get; set; }
}
I can't deserialize the STATE_NAME attributes. What am I missing?
I keep getting this error
"Cannot deserialize JSON object into type
'System.Collections.Generic.List`1[WPJsonSample.MainPage+Attributes]'.
Line 1, position 20."
Here is your class structure ( I used http://json2csharp.com/)
public class FieldAliases
{
public string STATE_NAME { get; set; }
}
public class Field
{
public string name { get; set; }
public string type { get; set; }
public string alias { get; set; }
public int length { get; set; }
}
public class Attributes
{
public string STATE_NAME { get; set; }
}
public class Feature
{
public Attributes attributes { get; set; }
}
public class RootObject
{
public string displayFieldName { get; set; }
public FieldAliases fieldAliases { get; set; }
public List<Field> fields { get; set; }
public List<Feature> features { get; set; }
}
IF you are trying to hit that endpoint, you should not be manually submitting the query, you should use the ArcGIS WP7 SDK (it's FREE!). Then use the QueryTask.
(if you just need help with parsing JSON, see below)
QueryTask queryTask = new QueryTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StateCityHighway_USA/MapServer/1/");
queryTask.ExecuteCompleted += QueryTask_ExecuteCompleted;
queryTask.Failed += QueryTask_Failed;
ESRI.ArcGIS.Client.Tasks.Query query = new ESRI.ArcGIS.Client.Tasks.Query();
query.Text = "e";
query.ReturnGeometry = false;
queryTask.ExecuteAsync(query);
private void QueryTask_ExecuteCompleted(object sender, ESRI.ArcGIS.Client.Tasks.QueryEventArgs args)
{
FeatureSet featureSet = args.FeatureSet
// use the featureSet to do something. It contains everything you need
}
If for whatever reason, you do not want to use the QueryTask, you can still use the FromJson method of the FeatureSet
void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
var featureSet = ESRI.ArcGIS.Client.Tasks.FeatureSet.FromJson(e.Result);
// Use it
}
If you need help with JSON, here are some key concepts.
1) Curly braces represent an object
2) square brackets represent an array.
3) properties are separated by commas
When using JSON.NET, you should add the JsonProperty attribute to a property. This way you can maintain proper names even if the json sucks
[JsonProperty("STATE_NAME")]
public string StateName { get; set; }
The JSON returned from that url is:
{
"displayFieldName": "STATE_NAME",
"fieldAliases": {
"STATE_NAME": "STATE_NAME"
},
"fields": [
{
"name": "STATE_NAME",
"type": "esriFieldTypeString",
"alias": "STATE_NAME",
"length": 25
}
],
"features": [
{
"attributes": {
"STATE_NAME": "Maine"
}
}
}
So, we can see here the root is an object, not an enumerable like a List<>
You'll have to fix the class structure to match the JSON, or access it with Linq queries (there are some samples of this in the json.net website).

Categories