Error when calling WCF function with two arguments - c#

My WCF service have method that accepts two parameters. In object browers this method looks like
public wcfelmaservice.racun SendOrder(wcfelmaservice.order Order_Header, System.Collections.Generic.List<order_items> Order_Items)
Order_Header have two members:
public string Number { set; get; }
public string Name { set; get; }
Order_Items have these members:
public decimal Price { set; get; }
public decimal Qty { set; get; }
public string ItemName { set; get; }
Now I have to pass values from PHP to WCF service. I'm doing it on this way:
<?php
$wcfClient = new SoapClient('http://localhost:28309/Service1.svc?wsdl');
ini_set("soap.wsdl_cache_enabled", "0");
//var_dump($wcfClient->__getFunctions());
$header = new StdClass;
$header->Number="1";
$header->Name="Test d.o.o";
$item = new StdClass;
$item->Price = "10.00";
$item->Qty="5";
$item->ItemName="SomeItemName";
$paramHeader = array ('Order_Header' => $header);
$paramItems = array ('Order_Items' => $item);
$response = $wcfClient->SendOrder($paramHeader, $paramsItems);
?>
When I run this script i get error:
Fatal error: Uncaught SoapFault exception: [a:DeserializationFailed]
The formatter threw an exception while trying to deserialize the
message: Error in deserializing body of request message for operation
'SendOrder'. End element 'Body' from namespace
'http://schemas.xmlsoap.org/soap/envelope/' expected.
I have no idea what I'm doing wrong?

PHP is not my forte, but a quick search on SO and I found this: How to serialize an "Object" type in PHP to be sent to a WCF Service?. Hope that helps.

Related

System.NotSupportedException: ... API HTTPPost with .net and c#

I am an engineering student, doing my final degree project based on xamarin apps, including a connection between the client (xamarin) and API (.net). I am trying to send some encrypted data (in base64 encoding) included on a json object as the Request. On the side of the API, it takes the json request, does some fully homomorphic encryption functions and returns the response within new encrypted information.
The problem is when I am trying to receive the response in API as a self-created class named "Post.cs" which includes the next properties;
public class Post
{
public ulong ? userId { get; set; }
public int ? id { get; set; }
public string? title { get; set; }
public string? body { get; set; }
public string? userIdEncrypted { get; set; }
public string? userIdEncryptedReturned { get; set; }
public string? parmsStr { get; set; }
public Post(ulong? userId, int? id, string? title, string? body, string? userIdEncrypted, string? userIdEncryptedReturned, string? parmsStr)
{
this.userId = userId;
this.id = id;
this.title = title;
this.body = body;
this.userIdEncrypted = userIdEncrypted;
this.userIdEncryptedReturned = userIdEncryptedReturned;
this.parmsStr = parmsStr;
}
So, my API takes the request and deserialize it in order to create a "Post" and do some stuff with it.
I am trying to reproduce HttpPost as follows:
[Route("api/[controller]")]
[ApiController]
public class PostController
{
#region CONSTRUCTOR
public PostController()
{
}
#endregion
//POST ://api/Post
[Route("api/[controller]")]
[HttpPost]
public Post ReceivePost([FromBody] Post post)
{
...
var _post = new Post(post.userId, post.id, post.title, post.body, post.userIdEncrypted
post.userIdEncryptedReturned, post.parmsStr);
... FHE functions...
return _post;
}
}
So, at the time I post the "Post" from the client on xamarin, I am sending a Post as the already mentioned structure, where userIdEncrypted and parmsStr contains a base64 encoded string. When it arrives to the API server, the following issue appears:
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.NotSupportedException: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'System.IO.Stream'. Path: $ | LineNumber: 0 | BytePositionInLine: 1.
---> System.NotSupportedException: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'System.IO.Stream'.
--- End of inner exception stack trace ---
CLIENT ON XAMARIN APP
This is the json string that I post from the client:
PostModel postAux = new PostModel()
{
userId = 2,
id = 1,
title = "Title for post 1",
body = "Body for post 1",
};
/******************************************************
* Encrypt data of the post (userId)
******************************************************/
PostModel newPost = initializeFHE(postAux);
//Here is where I fill the encrypted data (base64 string) included in the Post object
/******************************************************
* POST encrypted data to the server in csharp
******************************************************/
Uri requestUri = new Uri("http://myHost:3000/api/Post");
var client = new HttpClient();
client.DefaultRequestHeaders
.Accept
.Add(new MediaTypeWithQualityHeaderValue("application/json")); // ACCEPT header
var json = JsonConvert.SerializeObject(newPost);
var contentJson = new StringContent(json.ToString(), Encoding.UTF8, "application/json");
//Console.WriteLine(contentJson);
var response = await client.PostAsync(requestUri, contentJson);
...
In which PostModel refers to this self-created Model:
public class PostModel : BaseViewModel
{
public ulong userId { get; set; }
public int id { get; set; }
public string title { get; set; }
public string body { get; set; }
public string userIdEncrypted { get; set; }
public string userIdEncryptedReturned { get; set; }
public string parmsStr { get; set; }
}
I am aware of my inexperience programming on .Net and c#, so any help and explanations are welcome.
Regards,
Raul.
this is one of those rare error messages that tells you exactly what the problem is
Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported.
you need to add a default constructor to Post
public Post() {}

How to serialize this C# return value into a JSON object?

I have this object value that is being returned and I would like to convert it into a useful JSON object that I can inspect and manipulate. Ultimately, my goal is to validate the values of username and accessKey. But 2 things are throwing this off. Double {{ makes it invalid JSON and sauce:options can't be converted into a property in a class.
{{
"browserName": "MicrosoftEdge",
"browserVersion": "latest",
"platformName": "Windows 10",
"sauce:options": {
"username": "test",
"accessKey": "123"
}
}}
Here is what I tried:
string output = JsonConvert.SerializeObject(SauceSession.Options.ConfiguredEdgeOptions);
This SauceSession.Options.ConfiguredEdgeOptions returns that object I mentioned above.
Got this back:
Newtonsoft.Json.JsonSerializationException: 'Error getting value from 'BinaryLocation' on 'OpenQA.Selenium.Edge.EdgeOptions'.'
I also tried this as per suggestions:
var serialized = JsonConvert.SerializeObject(SauceSession.Options.ConfiguredEdgeOptions);
And got back this Newtonsoft.Json.JsonSerializationException: 'Error getting value from 'BinaryLocation' on 'OpenQA.Selenium.Edge.EdgeOptions'.'
Since you cannot fix the source, you're going to have to apply a bodge to fix the JSON, for example this will work:
var fixedJson = sourceJson.Substring(1, Json.Length - 2);
Now you should have a couple of classes to hold your data, this way you can also cope with the unusual names:
public class Root
{
public string BrowserName { get; set; }
public string BrowserVersion { get; set; }
public string PlatformName { get; set; }
[JsonProperty("sauce:options")]
public Options SauceOptions { get; set; }
}
public class Options
{
public string Username { get; set; }
public string AccessKey { get; set; }
}
And now you should be able to deserialise like this:
var root = JsonConvert.DeserializeObject<Root>(fixedJson);

Rest exception: Unable to find a constructor to use for type "myclass". A class should either have a default constructor

I know this question has been asked before, but I can't find an answer to solve this problem.
I'm making a request to a web service which returns a json, and then I save that json as an object in a list using json.net.
List<myclass> result;
var request = new RestRequest(url, Method.POST);
//Set the parameters of the request
//[...]
IRestResponse response = client.Execute(request)
Console.WriteLine(response.Content);
//response.Content = [{"nomPrecio":"string","nomPrecioEN":"string","IDrangoPrecio":0,"IDPoblacionMv":0,"NumOfertas":0,"NumOVotaciones":0,"Imagen":"anUrl"}]
//Everything works fine until here, and I can see the json is being received OK, but then...
result = JsonConvert.DeserializeObject<List<myclass>>(response.Content);
Then the console shows this message:
Rest Exception: Unable to find a constructor to use for type mynamespace.myclass. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path '[0].nomPrecio', line 1, position 14.
namespace mynamespace
{
public class myclass
{
public myclass()
{
}
public myclass(string nomPrecio, string nomPrecioEN, int IDrangoPrecio, int IDPoblacionMv, int NumOfertas, int NumOVotaciones, string Imagen)
{
this.nomPrecio = nomPrecio;
this.nomPrecioEN = nomPrecioEN;
this.IDrangoPrecio = IDrangoPrecio;
this.IDPoblacionMv = IDPoblacionMv;
this.NumOfertas = NumOfertas;
this.NumOVotaciones = NumOVotaciones;
this.Imagen = Imagen;
}
public string nomPrecio { get; set; }
public string nomPrecioEN { get; set; }
public int IDrangoPrecio { get; set; }
public int IDPoblacionMv { get; set; }
public int NumOfertas { get; set; }
public int NumOVotaciones { get; set; }
public string Imagen { get; set; }
}
}
What's more weird is that I make the same for other classes in the app and no one returns this error, all of them works.
I tried a lot of things like "json2csharp" but nothing works.
Any tip about what could I be doing wrong? Thanks
Some linker problem mb? Try to add for your class
[Preserve(AllMembers = true)]
That can happen when linker is set to "Sdk and user assemblies"

Deserializing OData.Error messages

I have an ASP.NET application that uses the Azure AD Graph API. Often, when an invalid operation is performed against the Graph API, an exception is thrown.
The following code shows an invalid Graph API call that would trigger an exception:
// Query the Azure AD User
var userToUpdate = await activeDirectoryClient.Users.GetByObjectId("user#domain.net").ExecuteAsync();
// Set given name to an empty string (not allowed)
userToUpdate.GivenName = "";
try
{
// Update the user in Azure AD
await userToUpdate.UpdateAsync();
}
catch (Exception e)
{
// Return exception message
}
The message of the inner exception is a JSON string with forward slashes before each quotation mark. It looks something like this:
"{\"odata.error\":{\"code\":\"Request_BadRequest\",\"message\":{\"lang\":\"en\",\"value\":\"Invalid value specified for property 'givenName' of resource 'User'.\"},\"values\":[{\"item\":\"PropertyName\",\"value\":\"givenName\"},{\"item\":\"PropertyErrorCode\",\"value\":\"InvalidValue\"}]}}"
Attaching a screenshot of the Locals window where the exception message is found:
I would like to convert this JSON to a .NET object to return informative error details. I am using the JSON.NET library for this, and I am assuming that the JSON will deserialize to an ODataError object:
var error = Newtonsoft.Json.JsonConvert.DeserializeObject<ODataError>(e.InnerException.Message);
However, the deserialized object always has a value of null, which means that the conversion is not working as expected.
That being said, what class should the above JSON string map to? Also, should I be removing the forward slashes from the string for proper deserialization?
The reason you've got null after deserialization is your JSON object properties names differs from Microsoft.Azure.ActiveDirectory.GraphClient.ODataError class properties names - "odata.error" property can not be deserialized to Error property of Microsoft.Azure.ActiveDirectory.GraphClient.ODataError
As workaround I've added my own types for correct deserialization:
internal class ODataError
{
[JsonProperty("odata.error")]
public ODataErrorCodeMessage Error { get; set; }
}
internal class ODataErrorCodeMessage
{
public string Code { get; set; }
public ODataErrorMessage Message { get; set; }
public List<ExtendedErrorValue> Values { get; set; }
}
internal class ExtendedErrorValue
{
public string Item { get; set; }
public string Value { get; set; }
}
internal class ODataErrorMessage
{
public string Lang { get; set; }
public string Value { get; set; }
}
After that JSON message was properly deserialized:
...
try
{
await ADClient.Users.AddUserAsync(newUser);
return Result.Ok();
}
catch (DataServiceRequestException ex)
{
var innerException = ex.InnerException;
var error = JsonConvert.DeserializeObject<ODataError>(innerException.Message);
return Result.Fail(new Error(error.Error.Message.Value, error.Error.Code, ex));
}

converting mashape api response to c# class

I am using mashape api for getting the speed post tracking information:-
https://www.mashape.com/blaazetech/indian-post
As this is in .NET c# following code is not getting complied:-
Task<HttpResponse<MyClass>> response = Unirest.get("https://indianpost.p.mashape.com/index.php?itemno=EF990403084IN")
.header("X-Mashape-Key", mykey)
.header("Accept", "application/json")
.asJson();
the complie error is "The type arguments for method 'unirest_net.request.HttpRequest.asJson()' cannot be inferred from the usage. Try specifying the type arguments explicitly."
I am not sure how this api can be consumed. Is it problem with "MyClass" and what?
RSDC - Ok, turns out that your API endpoints for Indian-Post don't work anyways. Tested them on Mashape and it returns error.
>>> I got it working for the metaCritic GET API <<<
https://www.mashape.com/byroredux/metacritic (Game List API, 2nd one down)
re: MyClass
1) On the mashape.com site in the API documentation page, find the 200/JSON response on the right side.
2) Copy the json data
3) go to http://json2csharp.com/ and paste the code
4) click Generate button to get c# class code. Copy the class code.
5) back in VS, go to Models folder and create class called MyClass.cs.
6) paste your code in as such:
public class MyClass
{
public class Result
{
public string name { get; set; }
public string score { get; set; }
public string url { get; set; }
public string rlsdate { get; set; }
public string rating { get; set; }
public string summary { get; set; }
public string platform { get; set; }
}
public class RootObject
{
public List<Result> results { get; set; }
}
}
7) Try this:
HttpResponse<MyClass.RootObject> response = Unirest.get("https://byroredux-metacritic.p.mashape.com/game-list/ps4/coming-soon")
.header("X-Mashape-Key", "KxdVFN6Vlymshd5ezOQwBvS2Svjtp1bq5YOjsnFOkgTOwqwM6y")
.header("Accept", "application/json")
.asJson<MyClass.RootObject>();
If you run the debugger, you can see that response > Body > results now holds 25 items of data.

Categories