Error on user taks: The type or namespace name 'Linq' does not exist in the namespace 'Newtonsoft.Json'
Hi,
I'm trying to create a user task for getting a Gps from address. I tried this in a business process and all was working, now I tried puting this in a user task and I keep getting the following error:
The type or namespace name 'Linq' does not exist in the namespace 'Newtonsoft.Json' for this line: using Newtonsoft.Json.Linq;
Attached it the full user task code.
namespace Terrasoft.Core.Process.Configuration { using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using Terrasoft.Common; using Terrasoft.Core; using Terrasoft.Core.Configuration; using Terrasoft.Core.DB; using Terrasoft.Core.Entities; using Terrasoft.Core.Process; using Terrasoft.UI.WebControls.Controls; using System.Net; using System.IO; #region Class: UsrGetGpsFromAddressUserTask /// <exclude/> public partial class UsrGetGpsFromAddressUserTask { #region Methods: Protected protected override bool InternalExecute(ProcessExecutingContext context) { string apiKey = "AIzaSyAxzbYu2BXF7bX0Y37H2ofAQmGfz9KNZJA"; string fullAddress = Get<string>("fullAddress"); string encodedAddress = Uri.EscapeDataString(fullAddress); string url = $"https://maps.googleapis.com/maps/api/geocode/json?address={encodedAddress}&key={apiKey}"; var request = WebRequest.Create(url); using (var response = request.GetResponse()) using (var stream = response.GetResponseStream()) using (var reader = new StreamReader(stream)) { var json = reader.ReadToEnd(); // Parse the entire JSON response as JObject var jsonObj = JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(json); // Try to get the "results" array safely var results = jsonObj["results"] as Newtonsoft.Json.Linq.JArray; if (results != null && results.Count > 0) { var location = results[0]["geometry"]["location"]; double lat = location.Value<double>("lat"); double lng = location.Value<double>("lng"); Set<double>("lat", lat); Set<double>("lng", lng); } else { throw new Exception("No results returned from geocoding API."); } } return true; } #endregion #region Methods: Public public override bool CompleteExecuting(params object[] parameters) { return base.CompleteExecuting(parameters); } public override void CancelExecuting(params object[] parameters) { base.CancelExecuting(parameters); } public override string GetExecutionData() { return string.Empty; } public override ProcessElementNotification GetNotificationData() { return base.GetNotificationData(); } #endregion } #endregion }
The package alraedy has the compile into a separate assembly unchecked.
Thanks in advanced,
Chani
Like
Hello Chani,
The reason of this error can be the fact that Newtonsoft.Json version that you use in your package is too old. The Linq namespace (which contains JObject, JArray, etc.) was introduced in Newtonsoft.Json 4.5 and later.
As an alternative solution you can update your code the way that Newtonsoft.Json.Linq will not be necessary for implementing your functionality. You use JObject, JArray from Newtonsoft.Json.Linq to deserialize the response you get from the endpoint. Instead of using them you can create the model to represent the response structure. It will look as following:
public class GeocodeResponse { public List<Result> results { get; set; } public string status { get; set; } } public class Result { public List<AddressComponent> address_components { get; set; } public string formatted_address { get; set; } public Geometry geometry { get; set; } public string place_id { get; set; } public PlusCode plus_code { get; set; } public List<string> types { get; set; } } public class AddressComponent { public string long_name { get; set; } public string short_name { get; set; } public List<string> types { get; set; } } public class Geometry { public Location location { get; set; } public string location_type { get; set; } public Viewport viewport { get; set; } } public class Location { public double lat { get; set; } public double lng { get; set; } } public class Viewport { public Location northeast { get; set; } public Location southwest { get; set; } } public class PlusCode { public string compound_code { get; set; } public string global_code { get; set; } }
Then InternalExecute method in the user task will look like this:
protected override bool InternalExecute(ProcessExecutingContext context) { string apiKey = "AIzaSyAxzbYu2BXF7bX0Y37H2ofAQmGfz9KNZJA"; string fullAddress = Get<string>("fullAddress"); string encodedAddress = Uri.EscapeDataString(fullAddress); string url = $"https://maps.googleapis.com/maps/api/geocode/json?address={encodedAddress}&key={apiKey}"; var request = WebRequest.Create(url); using (var response = request.GetResponse()) using (var stream = response.GetResponseStream()) using (var reader = new StreamReader(stream)) { var json = reader.ReadToEnd(); var jsonObj = JsonConvert.DeserializeObject<GeocodeResponse>(json); var results = jsonObj.results; if (results != null && results.Count > 0) { var location = results[0].geometry.location; double lat = location.lat; double lng = location.lng; Set<double>("lat", lat); Set<double>("lng", lng); } else { throw new Exception("No results returned from geocoding API."); } } return true; }
Iryna Oriyenko,
Thank you for your answer! I'm wondering if that's realt the reason as I used linq in a business process and it was working.
Anyway, where should I add the response structure, can it be added to the user task code itself?