I am using REST service to get the data from the Db.
In my class, I am having the property "UploadTime" of datatype TimeSpan?.
The time span is calculated based on the difference between dates and in the response,I ma getting response as :
ArrayOfUploadUI xmlns="http://schemas.datacontract.org/2004/07/NMS.ApplicationService.HIM.Objects" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<UploadUI>
<UID>1</UID>
<DateCompleted>2015-01-08T10:46:25.25</DateCompleted>
<DateNotified>2015-01-07T10:46:25.25</DateNotified>
<DateDictationStartTime i:nil="true" />
<DateDictationEndTime i:nil="true" />
<UploadTime>P1D</UploadTime>
<ExistsOnBackend>false</ExistsOnBackend>
</UploadUI>
</ArrayOfUploadUI>
.
I am getting the following exception while trying to get the data:
using (HttpResponseMessage response = await _HttpClient(session).GetAsync(apiUrl))
{
if (response.IsSuccessStatusCode)
result = await response.Content.ReadAsAsync<T>();
else
await _HandleInvalidResponseAsync(response);
}
I am getting issue at the "response.Content.ReadAsAsync();".
Error is:
Error converting value "P1D" to type 'System.Nullable`1[System.TimeSpan]'. Path '[0].UploadTime', line 1, position 518.
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType).
I googled and I came to know that WCF serilaizing the "timeSpan"datatype from "1:0:0:00" to "P1D".
My issue is how to deserialize this on the response level.
I have done formatting for the date at the source level and the issue got resolved.
JsonSerializerSettings dateFormatSettings = new JsonSerializerSettings
{
DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
};
string jsonNMSPlatformObject = JsonConvert.SerializeObject(nmsPlatformObject,dateFormatSettings);
using (HttpContent httpContent = new StringContent(jsonNMSPlatformObject))
{
httpContent.Headers.ContentType = new MediaTypeHeaderValue(JsonMedaType);
var request = new HttpRequestMessage(HttpMethod.Delete, apiUrl);
request.Content = httpContent;
using (HttpResponseMessage response = await _HttpClient(session).SendAsync(request))
{
if (response.IsSuccessStatusCode)
return;
else
await _HandleInvalidResponseAsync(response, jsonNMSPlatformObject);
}
}
Related
I'm trying out things with Flutter right now. But my variables keep getting reinitialised when accessed from another class.
I'm using json parsing and i need two parts of my request. The "Relatorio" part and the "Mensagem" part.
to parse this json i'm doing this:
List<RelatorioProdutos> parseRelatorioPorProduto(String responseBody) {
final parsed = json.decode(responseBody);
var relatorio = parsed['Relatorio'];
var mensagem = parsed['Mensagem'];
print (mensagem); // Here the variable returns well,
//but when i need it in other class i receive null.
return relatorio.map<RelatorioProdutos>((json) => new RelatorioProdutos.fromJson(json)).toList();
}
class RelatorioProdutos {
String CodigoProduto;
var QtdVendida;
var TotalVendas;
String Descricao;
RelatorioProdutos({this.CodigoProduto, this.QtdVendida, this.TotalVendas, this.Descricao,});
factory RelatorioProdutos.fromJson(Map json) {
//returns a List of Maps
return new RelatorioProdutos(
CodigoProduto: json['CodigoProduto'] as String,
QtdVendida: json['QtdVendida'],
TotalVendas: json['TotalVendas'],
Descricao: json['Descricao'] as String,
);
}
}
I want to use this 'mensagem' variable in another class to show the error for user, but i always receive 'null'.
i already tried setState but it reloads my json and i dont want to request the RestServer again.
Thanks from now!
If I understand correctly, you want to access a local variable of a function from another class. I don't think it's possible.
One way to do it, would be to wrap your response in another object containing the response, and this variable:
List<Response<RelatorioProdutos>> parseRelatorioPorProduto(
String responseBody) {
final parsed = json.decode(responseBody);
var relatorio = parsed['Relatorio'];
var mensagem = parsed['Mensagem'];
print(mensagem); // Here the variable returns well,
//but when i need it in other class i receive null.
return relatorio
.map((json) => new Response<RelatorioProdutos>(
new RelatorioProdutos.fromJson(json), mensagem))
.toList();
}
class RelatorioProdutos {
String CodigoProduto;
var QtdVendida;
var TotalVendas;
String Descricao;
RelatorioProdutos({
this.CodigoProduto,
this.QtdVendida,
this.TotalVendas,
this.Descricao,
});
factory RelatorioProdutos.fromJson(Map json) {
//returns a List of Maps
return new RelatorioProdutos(
CodigoProduto: json['CodigoProduto'] as String,
QtdVendida: json['QtdVendida'],
TotalVendas: json['TotalVendas'],
Descricao: json['Descricao'] as String,
);
}
}
class Response<T> {
const Response(
this.value,
this.errorMessage,
);
final T value;
final String errorMessage;
bool get hasError => errorMessage != null;
}
In this example I created a Response object that can contains both the response value and an error message.
In the parseRelatorioPorProduto, instead of returning the relatorio, I changed the return type to Response<RelatorioProdutos> in order to have access to the value and the error message from any class which call this function.
Thanks Letsar, i tried yout ideia but i get a lot of others erros.
To solve this problem i used this:
List<RelatorioProdutos> parseRelatorioPorProduto(String responseBody) {
final parsed = json.decode(responseBody);
var relatorio = parsed['Relatorio'];
var mensagem = parsed['Mensagem'];
if(mensagem[0].toString().substring(16,17) == "0"){
List<RelatorioProdutos> asd = new List();
RelatorioProdutos aimeudeus = new RelatorioProdutos(Descricao: mensagem[0].toString(), CodigoProduto: "a", TotalVendas: 0, QtdVendida: 0);
asd.add(aimeudeus);
return asd;
}else{
return relatorio.map<RelatorioProdutos>((json) => new RelatorioProdutos.fromJson(json)).toList();
}
}
I'm trying to parse JSON string that received from websocket sharp but keep failing.
using (var ws = new WebSocket(WebAddr))
{
ws.Log.Level = LogLevel.Debug;
ws.OnOpen += (ss, ee) =>
{
System.IO.File.WriteAllText(#"C:\log.txt", "connected!");
};
ws.OnMessage += (ss, ee) =>
{
JsonValue jo = JsonValue.Parse(ee.Data);
string value = (string)jo["levelid"];
Console.Write(value + '\n');
};
}
It just threw exception error when reaches string value... part.
I'm using System.Json from nuget.
I think I figured it out. The server will respond with 2 messages, one is Json object and one is Json array.
dynamic jo = JsonConvert.DeserializeObject(ee.Data);
This fixed my problem!
I'm trying to read java generated JSON stream created by out.writeBytes with my Xpage. I can get data like getServerPort and others (listed in code below) but when I'm trying to read context with BufferedReader or ServletInputStream I'm reciving errors.
Any one knows simple way to read stream content like that on Xpage ? readLine method returned null.
var exCon = facesContext.getExternalContext()
var httpRequest:javax.faces.contex.ExternalContext =exCon.getRequest();
print("CallCenter getContext "+String(exCon.getContext()))
print("CallCenter ContentType "+String(httpRequest.getContentType()))
print("CallCenter ContentLength"+String(httpRequest.getContentLength()))
print("CallCenter RemoteAddr "+String(httpRequest.getRemoteAddr() ))
print("CallCenter ServerPort "+String(httpRequest.getServerPort()))
facesContext.responseComplete();
// ONE OF METHODS I've TRIED =============
var stringBuffer:java.lang.StringBuffer = new java.lang.StringBuffer(80);
var line = null;
var reader:java.io.BufferedReader = httpRequest.getReader();
while ((line = reader.readLine()) != null)
{
stringBuffer.append(line);
stringBuffer.append("\n");
}
print("Buffer "+stringBuffer.toString());
// ============================
} catch(e) {
_dump(e);
fdf
There can only be one: the stream or the reader. Instead of getReader() use new InputStreamReader(in); point in to the inputstream of the context
The Nancy documentation seems to say that Pipelines.OnError should return null - as opposed to BeforeResponse which allows both null and a Response object.
All the examples like this one and many code samples here on StackOverflow show a Response being returned in the OnError, just like in the BeforeRequest.
When I attempt to return an HTTPStatus string for the Pipelines.OnError, everything works OK!
But when I attempt to return a Response, I get a compiler error:
Operator '+=' cannot be applied to operands of type 'Nancy.ErrorPipeline' and 'lambda expression'
I'm emulating almost exactly the code in the Nancy example, except for the fact that mine is a TinyIocContainer while the example's is using a StructureMap container and a StructureMap derived bootstrapper
Here's my code:
const string errKey = "My proj error";
const string creationProblem = "Message creation (HTTP-POST)";
const string retrievalProblem = "Message retrieval (HTTP-GET)";
public void Initialize(IPipelines pipelines)
{
string jsonContentType = "application/json";
byte[] jsonFailedCreate = toJsonByteArray(creationProblem);
byte[] jsonFailedRetrieve = toJsonByteArray(retrievalProblem);
Response responseFailedCreate = new Response
{
StatusCode = HttpStatusCode.NotModified,
ContentType = jsonContentType,
Contents = (stream) =>
stream.Write(jsonFailedCreate, 0, jsonFailedCreate.Length)
};
Response responseFailedRetrieve = new Response
{
StatusCode = HttpStatusCode.NotFound,
ContentType = jsonContentType,
Contents = (stream) =>
stream.Write(jsonFailedRetrieve, 0, jsonFailedRetrieve.Length)
};
// POST - error in Create call
pipelines.OnError += (context, exception) =>
{
// POST - error during Create call
if (context.Request.Method == "POST")
return responsefailedCreate;
// GET - error during Retrieve call
else if (context.Request.Method == "GET")
return responseFailedRetrieve;
// All other cases - not supported
else
return HttpStatusCode.InternalServerError;
};
}
private byte[] toJsonByteArray(string plainString)
{
string jsonString = new JObject { { errKey, plainString } }.ToString();
byte[] result = Encoding.UTF8.GetBytes(jsonString);
return result;
}
I had the same problem and I found a nice approach to the problem: http://paulstovell.com/blog/consistent-error-handling-with-nancy.
you should override RequestStartup on the Bootstrapper, here my test code:
protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context)
{
pipelines.OnError.AddItemToEndOfPipeline((ctx, ex) =>
{
DefaultJsonSerializer serializer = new DefaultJsonSerializer();
Response error = new JsonResponse(ex.Message,serializer);
error.StatusCode = HttpStatusCode.InternalServerError;
return error;
});
base.RequestStartup(container, pipelines, context);
}
I have create a one sample WCF rest template WebApi in this i have use Entity Framework to getting the data when i run the service for it return the string value it showing the result but at end of the json value add XML code like below how can i solve this.
[{"AccountId":1,
"AccountNumber":"AC001",
"AccountType":"Restaurant",
"BusinessName":"Red SpiceInc",
"PrimaryContactFirstName":"Varma",
"PrimaryContactLastName":"Bhupatiraju",
"PrimaryContactPhone":"(949) 374 2114",
"PrimaryContactEmail":"redspice#mybusinessapp.com",
"AccountGuid":"918D3E66-CEFE-11E0-8C2F-0C0B4824019B",
"EntityState":1,"EntityKey":null}]
<?xml version="1.0" encoding="utf-8"?><Stream p1:nil="true" xmlns:p1="w3.org/2001/XMLSchema-instance"; />
My code
[WebGet(UriTemplate = "GetSetting({LocationGuid},{settingName})", ResponseFormat = WebMessageFormat.Json)]
public Stream GetSetting(string LocationGuid, string settingName)
{
string str = string.Empty;
string strJSON = string.Empty;
dynamic contactResponse = new JsonObject();
List<setting> Result;
Result = new List<setting>();
var Location = from acc in objEntity.locations where acc.LocationGuid == LocationGuid select acc;
if (Location.Count() > 0)
{
var LocationId = (from acc in objEntity.locations where acc.LocationGuid == LocationGuid select acc).First();
var objSetting = from cat in objEntity.settings where cat.SettingName == settingName & cat.LocationId == LocationId.LocationId select cat;
setting SettingList = new setting();
foreach (setting setting in objSetting)
{
setting Settinglist = new setting();
Settinglist.SettingId = setting.SettingId;
Settinglist.AccountId = setting.AccountId;
Settinglist.LocationId = setting.LocationId;
Settinglist.SettingName = setting.SettingName;
Settinglist.SettingValue = setting.SettingValue;
Settinglist.FieldType = setting.FieldType;
Result.Add(Settinglist);
}
JavaScriptSerializer js = new JavaScriptSerializer();
strJSON = js.Serialize(Result);
WebOperationContext.Current.OutgoingResponse.ContentType = "application/json; charset=utf-8";
return new MemoryStream(Encoding.UTF8.GetBytes(strJSON));
}
else
{
return null;
}
}
Please help me solve this problem.
I believe return the POCO is enough
the method signature is
public List<setting> GetSetting(string, string)
WCF Web API will serialize the object into json or xml for you as per your request header (accept: application/json, or application/xml)
As was mentioned in misaxi's response, the WebApi WebGet operations generally do not need to concern themselves with how the response is returned. The responsibility of the web operation is to simply return the data. E.g....
[WebGet(UriTemplate = "GetSetting({LocationGuid},{settingName})"]
public List<setting> GetSetting(string LocationGuid, string settingName)
{
List<setting> Result = null;
var Location = from acc in objEntity.locations where acc.LocationGuid == LocationGuid select acc;
if (Location.Count() > 0)
{
Result = new List<setting>();
....
foreach (setting setting in objSetting)
{
....
Result.Add(Settinglist);
}
}
return Result;
}
The fact that the client receives XML, JSON, JSONP, HTML, etc is up to the client (in conjunction with server-side support). The client's request header will include something that looks like Accept: application/json or Accept: application/xml or whatever representation that the client is after. WebApi comes pre-loaded with a few standard formats, XML (the default) and Json. You can introduce more formats as needed to accept a more diverse set of Accept: .... headers, but the conversion from your data to these requested formats are generally out-of-scope for your web operation and rely on the formatters you set up (or were set up by default) when your service is initialized.
Likewise, WebPost operations generally do not care if the body of the request was XML or JSON, by the time the operation is invoked, formatters have already translated that payload into your method's parameters.