ActiveCollab /issue-token returns HTML instead of JSON - activecollab

Up until a month or so ago our interface to AC was working just fine. But now whenever our code makes a call to
https://url/public/api/v1/issue-token
we now get back a 700 plus lines of html with the message "Something went wrong. Please contact the technical support.", instead of a json response.
I haven't found anything yet that would explain this error message. The cert is self signed, but has been for quite some time and the interface was working with it previously. This set of code hasn't been changed in over six months, again, working fine previously.
I'm fairly certain that the page itself is returned from AC as the contents of the header section returned by the API and the header section from the standard AC login page are the same. The html element from the API response is below.
<!DOCTYPE html>
<html lang="en-us"
xml:lang="en-us"
xmlns="http://www.w3.org/1999/xhtml"
ng-controller="AngieApplicationController"
class="{{ wireframe.get_theme() }}"
ng-class="{
unauthorized : wireframe.initialized && wireframe.authorized === false,
initialized : wireframe.initialized
}">
<head>
Any thoughts, ideas, suggestions of where to turn next?
AC5TokenRequest tokenRequest = new AC5TokenRequest { username = username, password = password, client_name = clientApp, client_vendor = clientVendor };
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(baseUrl + "/issue-token");
wr.Method = "POST";
wr.ContentType = "application/json;charset=utf-8";
UTF8Encoding encoding = new UTF8Encoding();
string request = SerializationHelper.ToJSON(tokenRequest);
byte[] bytes = encoding.GetBytes(request);
wr.ContentLength = bytes.Length;
using (Stream requestStream = wr.GetRequestStream())
{
requestStream.Write(bytes, 0, bytes.Length);
}
using (Stream response = wr.GetResponse().GetResponseStream())
using (TextReader tr = new StreamReader(response))
{
string responseText = tr.ReadToEnd();
JObject jo = JObject.Parse(responseText);
if((bool)jo["is_ok"] == true )
{
accessToken = (string)jo["token"];
}
}

Related

mailboxUsageDetailsRequest returns exception

Replacing MSOnline cmdlets with Microsoft.Graph V1.12.0.
Report mailboxUsageDetailsReport = null;
IReportRootGetMailboxUsageDetailRequestBuilder mailboxUsageDetailsRequestBuilder = null;
IReportRootGetMailboxUsageDetailRequest mailboxUsageDetailsRequest = null;
mailboxUsageDetailsRequestBuilder = graphServiceClient.Reports.GetMailboxUsageDetail(period);
mailboxUsageDetailsRequest = mailboxUsageDetailsRequestBuilder.Request();
mailboxUsageDetailsReport = await mailboxUsageDetailsRequest.GetAsync();
The last line throws:
Newtonsoft.Json.JsonReaderException
HResult=0x80131500
Message=Unexpected character encountered while parsing value: R. Path '', line 0, position 0.
Source=Newtonsoft.Json
Fiddler shows 302 response with correct file "Location" but body of response contains just a 0,
Work around is
HttpRequestMessage hrm = new HttpRequestMessage(HttpMethod.Get, mailboxUsageDetailsRequest.RequestUrl);
await graphClient.AuthenticationProvider.AuthenticateRequestAsync(hrm);
HttpResponseMessage response = await graphClient.HttpProvider.SendAsync(hrm);
The Microsoft Graph .Net client v1.12.0 does not currently support the Reports API in a first class manner. You are sharing the suggested workaround, we thank you for sharing that. The response is a csv file, that's why you see the JsonReaderException.

JSON - WepAPI - Unexpected character encountered while parsing value

ANY help will be greatly appreciated
I have a Generic class that facilitates WebAPI calls, Its been in place for quite sometime and has had no issue. Today I'm getting an error and not sure where to track the problem. the exact error is
{"Unexpected character encountered while parsing value: [. Path 'PayLoad', line 1, position 12."}
what I'm getting back as the result of the call is
"{\"PayLoad\":[\"file_upload_null20180629155922²AAGUWVP2XUezeM3CiEnSOw.pdf\"],\"Success\":true,\"Message\":\"1 File(s) Uploaded\",\"Exceptions\":[]}"
Which looks right and is what I expect back from the service call
Here is the method that I'm calling that suddenly quit working, and its failing on the last line
public static TR WebApiPost(string serveraddress, string endpoint, object data)
{
HttpResponseMessage msg;
var clienthandler = new HttpClientHandler
{
UseDefaultCredentials = false,
Credentials = new NetworkCredential(user, password, domain)
};
using (var client = new HttpClient(clienthandler) { BaseAddress = new Uri(serveraddress) })
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
msg = client.PostAsync(endpoint, new StringContent(new JavaScriptSerializer().Serialize(data), Encoding.UTF8, "application/json")).Result;
}
var result = msg.Content.ReadAsStringAsync().Result;
return JsonConvert.DeserializeObject<TR>(result);
}
AND finally the line that actually makes the call (which should not matter)
returned = CallHelper<ResultStatus<string>>.WebApiPost(serviceurl, sendFileUrl, model);
It's not clear where your web service is getting the value of PayLoad from, so it is very possible that the value has a Byte Order Mark (BOM) at its beginning. This is especially the case if you are returning the content of what was originally a Unicode encoded file.
Be aware that a BOM is NOT visible when you are viewing a string in the debugger.
On your web service, make sure that you are not returning a BOM in the value of PayLoad. Check for this byte sequence at the beginning of the string:
0xEF,0xBB,0xBF
For more information on Byte Order Mark:
https://en.wikipedia.org/wiki/Byte_order_mark

Bad Request -Post method - JSON DateTime issue

I have a Visual Studio (2015) project that includes a client part (Xamarin.Forms PCL) and a web service part ( WCF Rest). The web services use edmx to communicate with the database ( SQL Server 2016). JSON is used to exchange the data.
I'm new to creating/consuming WCF Rest services. I have no issue using the GET method but I'm stuck with an issue with a POST method.
This method is part of a service that works well: no issue for a GET based method. It works well when I test it from a URL or from my client ( PCL Xamarin.Forms).
The POST method (my first ever) is a bit more problematic.
It's supposed to create a new record in a table in SQL Server (2016).
When I use Postman (https://www.getpostman.com/) to test it, it already has an issue: it creates a record in the table but the object has two dates and the two dates are replaced by 1970-01-01.
When I use my client to contact the web service:I get 'Bad Request'.
I looked for a solution and found that instead of placing the Datetime value, it was best to place the number of milliseconds from 1970-01-01.
I used this advice in Postman and noticed the creation of a new line worked fine.
Body of the Postman request :
{
"Reservation_Utilisateur_Id" : "4",
"Reservation_Velo_Id" : "2",
"Reservation_DateDebut" : "\/Date(1245398693390)\/",
"Reservation_PeriodeDebut" : "matin",
"Reservation_DateFin" :"\/Date(1245398693390)\/",
"Reservation_PeriodeFin" : "matin"
}
Now, I'd like to know how to get that object to send to the server . How can my object be serialized like above?
I looked for a solution unsuccessfully.
I keep on getting "There was an error deserializing the object of type BikeSharingService.Reservation. DateTime content '2016-08-22T00:00:00+02:00' does not start with '/Date(' and end with ')/' as required for JSON."
Could someone please give the newbie that I am an explanation and maybe some code that works?
Here is my code:
My contract:
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "create",
ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
Reservation create(Reservation reservation);
The service method:
public Reservation create(Reservation reservation)
{
using (MyEntities bse = new MyEntities())
{
Reservation re = new Reservation
{
Reservation_Utilisateur_Id = reservation.Reservation_Utilisateur_Id,
Reservation_Velo_Id = reservation.Reservation_Velo_Id,
Reservation_DateDebut = reservation.Reservation_DateDebut,
Reservation_PeriodeDebut = reservation.Reservation_PeriodeDebut,
Reservation_DateFin = reservation.Reservation_DateFin,
Reservation_PeriodeFin = reservation.Reservation_PeriodeFin,
Reservation_DemandeRecupDomCli = reservation.Reservation_DemandeRecupDomCli
};
bse.Reservations.Add(re);
bse.SaveChanges();
return re;
}
}
On the client side :
const string Url1 = "http://localhost:51843/ServiceReservation.svc/create";
public async Task<Reservation> create(Reservation reservation)
{
string json = JsonConvert.SerializeObject(reservation);
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Accept", "application/json");
var response = await client.PostAsync(Url1,
new StringContent(
json,
Encoding.UTF8, "application/json"));
return JsonConvert.DeserializeObject<Reservation>(
await response.Content.ReadAsStringAsync());
}
Then calling the method on the client side :
Reservation re =new Reservation();
re.Reservation_Utilisateur_Id = 4;
re.Reservation_Velo_Id = 2;
re.Reservation_DateDebut = DateTime.Now.Date;
re.Reservation_PeriodeDebut = "matin";
re.Reservation_DateFin = DateTime.Now.Date;
re.Reservation_PeriodeFin = "matin";
re.Reservation_DemandeRecupDomCli = 1;
Reservation resultat = await reManager.create(re);
What I get :
False Bad Request Method: POST, RequestUri:
'http://localhost:51843/ServiceReservation.svc /create', Version: 2.0,
Content: System.Net.Http.StringContent, Headers: { Accept:
application/json Content-Type: application/json; charset=utf-8
Content-Length: 407 } BadRequest
1.1
There was an error deserializing the object of type
BikeSharingService.Reservation. DateTime content
'2016-08-22T00:00:00+02:00' does not start with '/Date(' and end with
')/' as required for JSON.
[Promoted from a comment]
Json doesn't define a standard date format, but it's worth noting that Json.Net (which is used by most of the web-facing parts of the .Net framework) supports multiple formats out of the box (and even custom ones).
If you can decide on a standard which works for all your clients, you can configure the Json (en/de)coding in .Net to use it natively.
See http://newtonsoft.com/json/help/html/datesinjson.htm for more information and details on how to specify a date format handler.
[Example code from link]
public void WriteJsonDates()
{
LogEntry entry = new LogEntry
{
LogDate = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc),
Details = "Application started."
};
// default as of Json.NET 4.5
string isoJson = JsonConvert.SerializeObject(entry);
// {"Details":"Application started.","LogDate":"2009-02-15T00:00:00Z"}
JsonSerializerSettings microsoftDateFormatSettings = new JsonSerializerSettings
{
DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
};
string microsoftJson = JsonConvert.SerializeObject(entry, microsoftDateFormatSettings);
// {"Details":"Application started.","LogDate":"\/Date(1234656000000)\/"}
string javascriptJson = JsonConvert.SerializeObject(entry, new JavaScriptDateTimeConverter());
// {"Details":"Application started.","LogDate":new Date(1234656000000)}
}
What you are trying to use is the Epoch DateTime or Unix DateTime.
To convert the DateTime object to epoch datetime you can create a helper method. It is either milliseconds or seconds from 1/1/1970.
Also if needed you can use the Noda DateTime instead of the .NET which has the method in it to convert.
You can create a New class with string data type for DateTime and have a Casting specified. Or you can write your on custom Serialize method.
By default DateTime format after serialization would be ISO 8601 Format.
Code to convert to Unix or Epoch Date time :
private static readonly DateTime EpochDateTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static long ConvertDateTimeToUnixTime(DateTime date, bool isDatarequiredInMilliSeconds = false, DateTimeKind dateTimeKind = DateTimeKind.Local)
{
return Convert.ToInt64((DateTime.SpecifyKind(date.Value, dateTimeKind).ToUniversalTime() - EpochDateTime).TotalSeconds) * (isDatarequiredInMilliSeconds ? 1000 : 1);
}
You can use the following if you need to convert back(source):
var milliseconds = "/Date(1245398693390)/".replace(/\/Date\((-?\d+)\)\//, '$1');
var actualDate = new Date(parseInt(milliseconds));

Sending a json serialized object containing a escaped string using HttpWebRequest on mono

The requirement serialize a class and send it to the server.
Dev environment:
MonoDevelop 3.0.6
Runtime:
Mono 2.10.9 (tarball)
GTK 2.24.10
GTK# (2.12.0.0)
Operating System:
Mac OS X 10.7.4
The class contains a string with an escaped double quote in it.
class CustomClass
{
public string foo = "hi!\"";
}
The issue is that when I serialize it, encode it and create a URI object, the backslash used to escape double quote in the variable foo is converted into a forward slash, thus breaking the json.
Below are values of the different variables of the URI instance
Uri:
http://myserver/hello_world/0/{"foo":"hi!/""}
AbsoluteUri:
http://myserver/hello_world/0/%7B%22foo%22%3A%22hi%21/%22%22%7D
OriginalString:
http://myserver/hello_world/0/%7B%22foo%22%3A%22hi%21%5C%22%22%7D
The HttpWebRequest send the value "http://myserver/hello_world/0/{"foo":"hi!/""}" to the server, but for my requirement it should use the OriginalString to get a valid response from the server.
If i test the code on .NET the OriginalString is being sent to the server by the HttpWebRequest class, but there is additional code (hack) which doesn't work on mono mac
string paq = requestUri.PathAndQuery;
FieldInfo flagsFieldInfo = typeof(Uri).GetField("m_Flags", BindingFlags.Instance | BindingFlags.NonPublic);
ulong flags = (ulong)flagsFieldInfo.GetValue(requestUri);
flags &= ~((ulong)0x30); // Flags.PathNotCanonical|Flags.QueryNotCanonical
flagsFieldInfo.SetValue(requestUri, flags);
The code :
object messageObject = new CustomClass();
//try 1
//string jsonString = Uri.EscapeUriString(JsonConvert.SerializeObject(message2));
//try 2
//string jsonString = Uri.EscapeDataString(JsonConvert.SerializeObject(message2));
//try 3
string jsonString = System.Web.HttpUtility.UrlEncode(JsonConvert.SerializeObject(messageObject));
Uri uri = new Uri(string.Format("http://myserver/hello_world/0/{0}", jsonString));
//try 4:
//HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri.AbsoluteUri);
//try 5
//HttpWebRequest request =(HttpWebRequest)WebRequest.Create(string.Format("http://myserver/hello_world/0/{0}",jsonString));
//try 6
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri.OriginalString);
try
{
using (HttpWebResponse resp = request.GetResponse() as HttpWebResponse)
{
var reader = new StreamReader(resp.GetResponseStream());
string jsonResponse = reader.ReadToEnd();
}
}
catch (WebException wex)
{
Debug.WriteLine(wex.ToString());
}
As you can see I have tried using Uri.EscapeUriString, Uri.EscapeDataString and System.Web.HttpUtility.UrlEncode and using the AbsouluteUri and OriginalString to create the WebRequest instance and also creating it using a string.
I have also tried using the following code in the config.
<uri>
<schemeSettings>
<clear/>
<add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes"/>
</schemeSettings>
</uri>
But none of the methods work and the encoding is lost when the request in created.
Any ideas to get this to work will be appreciated.
Update:
I have tried a lot of things including testing with some 3rd party open source code, but still faced the same issue when sending in an encoded url.
I modified the code to use WebClient instead of WebRequest but still no luck.
So the solution that worked for me on both MonoMac an MonoTouch(simulator, i haven't tested it on the device) was to create the request using TcpClient.
using (TcpClient tc = new TcpClient()) {
tc.Connect ("myserver", 80);
using (NetworkStream ns = tc.GetStream()) {
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(ns)) {
using (System.IO.StreamReader sr = new System.IO.StreamReader(ns)) {
sw.Write("GET /hello_world/0/%7B%22foo%22:%22hi!%5C%22%22%7D HTTP/1.1 Host:myserver \r\n\r\n");
sw.Flush ();
string line;
while ((line=sr.ReadLine())!=null)
Console.Write (line);
}
}
}
}
I have tried a lot of things including testing with some 3rd party open source code, but still faced the same issue when sending in an encoded url.
I modified the code to use WebClient instead of WebRequest but still no luck.
So the solution that worked for me on both MonoMac an MonoTouch(simulator, i haven't tested it on the device) was to create the request using TcpClient.
using (TcpClient tc = new TcpClient()) {
tc.Connect ("myserver", 80);
using (NetworkStream ns = tc.GetStream()) {
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(ns)) {
using (System.IO.StreamReader sr = new System.IO.StreamReader(ns)) {
sw.Write("GET /hello_world/0/%7B%22foo%22:%22hi!%5C%22%22%7D HTTP/1.1 Host:myserver \r\n\r\n");
sw.Flush ();
string line;
while ((line=sr.ReadLine())!=null)
Console.Write (line);
}
}
}
}

Reasons why Browser asks to Save file instead of updating page with JSON result

Does anybody have a list of reasons why a browser would ask to save a file of JSON data instead of using it to update the page according to functions already present? I had this working for a while, but all of a sudden, I did something that caused that to not work anymore. I am using asp.net MVC4.
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
As you see I have included the appropriate scripts.
#using (Ajax.BeginForm("SearchByDemographic", "SearchPatients", null, new AjaxOptions { HttpMethod = "POST", LoadingElementId = Url.Content("~/Images/ajax-loader.gif"), OnSuccess = "binddata", OnFailure = "FailAlert" }, new { id = "searchByDemographics" }))
I use Ajax.BeginForm() as you can see.
Here is the function that I use to return the JSON result
[HttpPost]
public ActionResult SearchByDemographic(SearchByDemographicModel SearchByDemo)
{
string UID = HttpContext.User.Identity.Name;
DataRepository dr = new DataRepository();
List<SelectListItem> retVal = dr.SearchByDemographic(SearchByDemo, UID);
if ((retVal == null) || (retVal.Count < 1))
return Json("Empty Record: No Patient Found", JsonRequestBehavior.AllowGet);
else
if(retVal[0].Text.Contains("Error")){
return Json(new {success = false, nameError = "General Return Exception"}, DataRepository.searchPatientJSonStr(retVal), JsonRequestBehavior.AllowGet);
}
else{
return Json(DataRepository.searchPatientJSonStr(retVal), JsonRequestBehavior.AllowGet);
}//return PartialView("_RetTable", Json(DataRepository.searchPatientJSonStr(retVal), JsonRequestBehavior.AllowGet));
}
This keeps happening to me. I am ignorant of the reasons why this could happen. If I could figure out why this keeps happening I would be in a better position to fix it in the future.
From my knowledge, The browser is expecting JSON data, and somehow or the other, it is not getting it?
Also, Here is JSON of test data being passed back... If it is a little off forgive me, I tried to get a single result out of a list of 20...
"{\"total\":1,\"page\":1,\"records\":1,\"rows\":[{\"id\":11248971,\"cell\":[\"CRAYON \",\" RED \",\" 1956-03-04 \",\" M \",\" 11248971 \",\" 840006723 \",\" 737452545\"]}]}
I still always just get a prompt to open the file.
This behaviour is only present in IE due to a configuration option named "Show friendly JSON errrors" which makes ie ask to save your json if it's smaller than a certain size ( i seem to remember 200 characters) instead of consuming it normally
A possible solution is to use
return Json(result, "text/html");
which will make IE behave correctly
public JsonResult Index()
{
Models.MyEntities Object = new Models.MyEntities();
var vperson = Object.Person;
return Json(vperson, "text/html", behavior:JsonRequestBehavior.AllowGet);
}