Custom Object as parameter to a soap service always null - c#

I have a .NET Core Web Api which i need to develop to handle a request arriving from another system. The XML i receive has this tag inside:
<root>
<child1>
<child1.1>192.168.1.1</child1.1>
</child1>
<child2>true</child2>
</root>
My Web Api create an endpoint in the Configure Method
app.UseSoapEndpoint<ISampleService>("/Service.svc", new BasicHttpBinding(), SoapSerializer.XmlSerializer);
Finally i have a .NET Core Library where i handle the requests:
public Response Root(Request r)
{
//code
}
Using postman i noticed that my method is called but the Request object is always null.
This is my Request Object
[DataContract]
public class Child1
{
[DataMember]
public string child1.1 { get; set; }
}
public class Request
{
[DataMember]
public Child1 child1 { get; set; }
[DataMember(Name = "child2")]
public string child2 { get; set; }
}
Any ideas?

Related

Deserializing XML from API in ASP.NET MVC

I'm building a asp.net MVC program that will consume a xml-based API using httpclient and deserializing it into object using XmlSerializer.
But got an error : There is an error in XML document (1, 2).
Inner exception: {"http://schemas.datacontract.org/2004/07/Service.Models'> was not expected."}
My suspicion is somehow I messed up the model class, but I'm not sure.
Thanks!
XML from API:
<ArrayDTO xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/RestService.Models">
<LaborDTO>
<CreateDate>2014-04-09T09:20:15.57</CreateDate>
<CreateUser>test</CreateUser>
</LaborDTO>
<LaborDTO>
<CreateDate>2014-04-09T09:20:15.57</CreateDate>
<CreateUser>test</CreateUser>
</LaborDTO>
</ArrayDTO>
Below is my C# code:
HttpClient client = new HttpClient();
....
HttpResponseMessage response = client.GetAsync(serviceString).Result;
....
XmlSerializer ds = new XmlSerializer(typeof(ArrayDTO));
var obj = ds.Deserialize(response.Content.ReadAsStreamAsync().Result);
ArrayDTO data = (ArrayDTO) obj;
foreach (var item in ArrayDTO.collection) {
....
}
this my model class:
public class LaborDTO
{
public Nullable<System.DateTime> CreateDate { get; set; }
public string CreateUser { get; set; }
}
public class ArrayDTO
{
[XmlAttribute("xmlns")]
public string schema { get; set; }
[XmlElement("LaborDTO")]
public LaborDTO[] collection { get; set; }
}
All you need is using the Xml namespace
[XmlRoot(Namespace = "http://schemas.datacontract.org/2004/07/RestService.Models")]
public class ArrayDTO
{
[XmlElement("LaborDTO")]
public LaborDTO[] collection { get; set; }
}

Using 'Paste XML as Classes' to deserialize a Web API rest response

I am having trouble using the 'Paste XML as Classes' feature in VS2012 to properly deserialize XML results from a Rest call using Web API.
The XML response from the call looks like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<SCResponse>
<AccountId>86</AccountId>
<Administrator>false</Administrator>
<Email>6z#z.com</Email>
<FirstName>6z#z.com</FirstName>
<Label>false</Label>
<LastName>6z#z.com</LastName>
<link href="https://cnn.com" rel="news" title="News"/>
</SCResponse>
I copied this XML and used the handy new feature to paste this XML as classes:
namespace Models.account.response
{
[XmlRoot(ElementName = "SCResponse")] // I added this so I could name the object Account
[DataContract(Name = "SCResponse", Namespace = "")] // I added this as the namespace was causing me problems
public partial class Account
{
public byte AccountId { get; set; }
public bool Administrator { get; set; }
public string Email { get; set; }
public string FirstName { get; set; }
public bool Label { get; set; }
public string LastName { get; set; }
[XmlElement("link")]
public SCResponseLink[] Link { get; set; }
}
[XmlType(AnonymousType = true)]
public partial class SCResponseLink
{
private string hrefField;
private string relField;
private string titleField;
[XmlAttribute)]
public string href { get; set; }
XmlAttribute]
public string rel { get; set; }
[XmlAttribute]
public string title { get; set; }
}
}
}
I call the REST endpoint like so:
string path = String.Format("account/{0}", id);
HttpResponseMessage response = client.GetAsync(path).Result; // Blocking call!
if (response.IsSuccessStatusCode)
{
// Parse the response body. Blocking!
account = response.Content.ReadAsAsync<Models.account.response.Account>().Result;
}
and examine the fields of the Account object -- all are null or defaulting to initialized values.
In my Global.asax.cs Application_Start method, I am registering the XML Serializer:
GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;
A simpler way to handle this might be to use the RestSharp library, which will do all of the deserialization for you. This will simplify your calls, and you won't need the XML attributes on your model.
Take a look here for a good example of doing aync calls with RestSharp:
How should I implement ExecuteAsync with RestSharp on Windows Phone 7?
Hopefully this helps.

ASMX JSON WebService, changing property types and having old __type - error

I have a .NET JSON web service
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
[ScriptService]
[GenerateScriptType(typeof(Item))]
[GenerateScriptType(typeof(Info))]
[GenerateScriptType(typeof(Details))]
public class API : System.Web.Services.WebService
{
[WebMethod]
public Item[] GetItems()
{
...
}
[WebMethod]
public bool SaveItem(Item item)
{
...
}
}
Definition of classes is at the bottom of the message.
There is a property More of type Info in Item class.
On the client side (HTML5) i'm calling GetItems(), and storing it in local storage, and periodically call SaveItem.
JSON data that i get on the client is something like:
[{"__type":"MyApp.API.Item","More":{"__type":"MyApp.API.Info","ID":1}}]
All fine so far.
The problem occurs when i change property More from type Info to type Details in Item class, i.e:
[Serializable]
public class Item
{
public Details More { get; set; } // <----- type changed from Info to Details
}
Since my client has the data cached, when i try to call SaveItem ASP.NET is throwing error:
Cannot convert object of type 'MyApp.API.Info' to 'MyApp.API.Details'
Question: If there a solution to this (ideally keeping the ASMX web service, and not changing JSON data on the client)?
Here's what the classes are:
[Serializable]
public class Item
{
public Info More { get; set; }
}
[Serializable]
public class Details: Info, IDetails
{
public string Notes { get; set; }
}
[Serializable]
public class Info: IInfo
{
public int ID { get; set; }
}
public interface IDetails: IInfo
{
string Notes { get; }
}
public interface IInfo
{
int ID { get; }
}
If you don't want to see the "_type":"object" you can have your method as object type.
all this text would dissapear.

How to use custom type with WCF data service and EF

I've created a WCF Data Service with a base class of my EF model.
I wanted to return a custom type (one that isn't in my EF model), but I get the error:
The server encountered an error processing the request. Please see the service help
page for constructing valid requests to the service.
My custom class looks like:
public class MyCustomClass
{
public string CustomProp { get; set; }
public List<int> Ids { get; set; }
}
How can I make this work?
You need to set up your return object as a data contract:
[DataContract]
public class MyCustomClass
{
[DataMember]
public string CustomProp { get; set; }
[DataMember]
public List<int> Ids { get; set; }
}
See also: How to accept JSON in a WCF DataService?
Linked is how to set up a receiving service, returning the values you just change the return types on your methods.
The only way I have found to do this with WCF Data Services is to pass a json string as a parameter and then deserialize it into the custom class.
Like so:
[WebGet(ResponseFormat = WebMessageFormat.Json)]
public bool ConfigurationChanged(string jsonStr)
{
try
{
MyObject obj = new JavaScriptSerializer().Deserialize<MyObject>(jsonStr);
// ... do something with MyObject
}
catch (Exception)
{
throw;
}
}

How can I generate a custom SOAP message

I have a site that give me this xml response on my GET request:
<ServerUnits>
<State Name="ServerName" Date="2008-04-01" >
<Users>
<User login="someUser1" Password="123456">
<User login="someUser2" Password="qwerty">
</Users>
</ServerUnits>
I want use WCF Client for work with this service.
How to discraibe Message Contract of this response for WCF Clien
It is best to create client proxies for the WCF service. It will create the data contracts for you (as mentioned by #Aliostad) so you don't have to create them manually. To do this right click on your solution and select "Add Service Reference..." from the context-menu and enter the address to your WCF service.
I think that WCF is not useful is your case.
A more simple way would be to write objects that match this xml response and just deserialize xml stream onto objects instances.
What you have posted is not a SOAP message so MessageContract is not appropriate.
I imagine what you posted is the SOAP body content so you need to do something along the line of this:
[DataContract]
public class ServerUnits
{
[DataMember]
public ServerState State { get; set; }
[DataMember]
public List<User> Users { get; set; }
}
[DataContract]
public class ServerState
{
[DataMember]
public string Name { get; set; }
[DataMember]
public DateTime Date { get; set; }
}
[DataContract]
public class User
{
[DataMember]
public string login { get; set; }
[DataMember]
public string password { get; set; }
}
UPDATE
Your message is not SOAP. But you can still use the code above if you use webHttpBinding which sends and receives POX.

Categories

Resources