Consume Web Service, Serialize XML response, save xml to database - asp.net

I have this situation, I am creating a Web Service in C# where I need to consume a SOAP Web Service, which gives me an XML response back, I need to serialize this XML response and save it to a table in the database.
I have tried the to call the XML in Postman and it worked fine with a
200 OK status
, but I need how to serialize this reponse and save it to the database.
And then I have tried to write this:
public void CreateFilter(Student student)
{
var XML = XmlSerialization <Student> (student);
ConnectDataBase db = new ConnectDataBase();
SqlCommand cmd = new SqlCommand("sp_Student");
cmd.Parameters.Add("#name", SqlDbType.VarChar).Value = student.name;
cmd.Parameters.Add("#surname", SqlDbType.VarChar).Value = student.surname;
cmd.Parameters.Add("#subject", SqlDbType.VarChar).Value = student.subject;
cmd.Parameters.Add("#student", SqlDbType.Xml).Value = XML;
}
Any thoughts on how to get a response from the Web Service I have to consume, and then serialize the response I'm getting back and then save the serialization on the database?
Thank you in advance

Well, you have a couple of options really. Essentially, if you aren't leveraging an ORM (like Hibernate or some such), you want to:
Grab the XML payload
Get that deserialized into an object instance so you can work with it
Pick out the data you are interested in and persist it
Step 2 is essentially writing a class (or tree of classes) that mimmicks the field structure of the XML, then asking a library nicely to parse the XML state into an instance of that class. This then makes it easy to work with for you.
You can either leverage the the native deserialization as per:
https://learn.microsoft.com/en-us/dotnet/api/system.xml.serialization.xmlserializer.deserialize?view=net-6.0
Or, just for arguments sake alternatively you could use a modern serialization library. There isn't much of a good choice when it comes to XML and C#, so the main one I can think of that will get you from point a to point b is Json.NET:
https://www.newtonsoft.com/json
This library, though predomenantly pushed as an all-in-one object mapper for JSON is also able to translate between XML and Json:
https://www.newtonsoft.com/json/help/html/ConvertingJSONandXML.htm
Depending on how much of a fight the native deserializer puts up (defining the schema can be a bit of a pain, bloody SOAP am I right), it might be easier to use Json.NET to hoover up the XML, convert it to JSON, then deserialize that json as an object.
This gives you a 2-step deserialization process which isn't ideal, but it's not such a bad thing either as you get to work with the "nice" library and not have to fight the old baked in xml serialization stuff.
The choice is yours really. I'd give the first option a good go first then if that puts up too much of a fight you have Json.NET to fall back on :)

Related

Can I configure asp.net so some responses are serialized as camelCase and some as PascalCase?

I have an API with two clients: OldClient and newClient. I currently have this in Startup.cs so my json responses are serialized as PascalCase, i.e. as per all my .net objects which have first letter capitalized.
services.AddControllers().AddJsonOptions(jsonOptions =>
{
// So json output is like 'SomeId' instead of 'someId':
jsonOptions.JsonSerializerOptions.PropertyNamingPolicy = null;
...
}
OldClient loves this format. However, newClient would really prefer camelCase.
Is there a way I can configure my app to respond with camelCase for newClient requests and PascalCase for OldClient requests? newClient can send a header to indicate that it wants camelCase.
You can check out this issue on aspnetcore's github page
The possibility of using specific JSON Serializer Options on a per-controller basis hasn't been implemented yet. It has been moved to ".NET 8 planning", which means it's still a ways-away.
Meanwhile, you could work around this issue by:
For data reception and model-binding, you could create a Custom ModelBinder by implementing IModelBinder interface in a ModelBinderAttribute in order to utilize your specific JSON Serialization options. Then, you could simply add the attribute to the endpoints where you need it.
For data responses, you could simply use:
return new JsonResult([object], [CustomJSONSerializationSettings]);
It's quite annoying to have to modify these per-endpoint, but it seems like it's the only way until the feature is added in .net 8 (if we're lucky).

Get the results of a CosmosDb query as a Raw string (payload of the http response)

I'm using the .NET API of CosmosDB and I'm getting a hard time trying to figure out how to get the raw result of a CosmosDB query prior to it getting deserialized into a class. Browsing the documentation, all examples I find cast the results to an specific class or to a dynamic. That is:
//This returns a Document, wich actually is a dynamic...
client.ReadDocumentAsync(...)
//This returns an object of type MyClass, wich I supose is casted internally by the API
client.ReadDocumentAsync<MyClass>(...)
What I want to do is to get the original raw JSON payload of the result to inspect it without the overhead of deserializing it to anything else.
Does anybody know if it's possible to get the raw result with the .NET api? If so, how?
In other cases, I need to use the result as an ExpandoObject to treat it dynamically, but I find that the "dynamic" results given by the api are not "expandables" so I'm forced to serialize them and then deserialize again in a recursive form into an ExpandoObject. Furthermore, the result is polluted with _rid, Etag, etc. properties that I don't need on my object. It's quite anoying.
I think it's an unnecesary overhead to serialize and then deserialize again, so maybe the optimus way would be to get the raw JSON result and write a method to deserialize directly to Expando.
Or maybe I'm loosing any point and there's an API to get the results as Expandos. Does anybody know it?
Check out this question that I had earlier:
Converting arbitrary json response to list of "things"
Altough I didn't named it, the API in question was actually DocumentDb, so I think you'll be able to use that code.
Seen some bad advice here, but it is built into the SDK natively.
Document doc = cosmosClient.ReadDocumentAsync(yourDocLink);
string json = doc.ToString();

JSON + SOAP - Is DataContract necessary?

Here's my problem.
I'm using SOAP to retrieve information from a third-party web service.
Response time is too high, so I was planning on using JSON instead, at least in a couple of methods.
For this I'm using DataContractJsonSerializer, but I seem to be having some trouble.
For example, in SOAP there's a method called getAvailablePublic with returns an object of type getAvailablePublicResponse.
There's an equivalent for this method in JSON, which also returns a an object of type getAvailablePublicResponse.
In order to deserialize the information I needed to create a couple of data contracts, and here are my concerns:
Do I really need to create a DataContract? Why can't I use getAvailablePublicResponse object from asmx?
The problem is that if I create a DataContract, I need to use a different name other than getAvailablePublicResponse, as I would have two objects with the same name (the one created by me, and the one from SOAP), and this would require making several changes in my solution.
Hope this makes sense.
Thanks.
Can you post your client code that is making the call to the web service? I don't know what you are using now, but I'm a fan of RestSharp for making remote calls and serializing JSON to C# classes. Something like this:
RestClient client = new RestClient("http://some.domain.com/someservice?someparam=yes");
var results = client.Execute<MyGreatDTOClass>(new RestRequest(Method.GET));

How to get all SolrNet query result info in JSON format?

I am not sure if this is a JSON.Net issue or a SolrNet issue, which is why I am tagging it with both.
I am using SolrNet and currently handling all page interactivity with JavaScript from an MVC call, by returning a JsonNetResult encoding of the object returned by solr.Query(). I am now experimenting with Faceting, but am not seeing the Facet info in my results.
I've got an MVC Controller method like the one below. (JsonNetResult is similar to the stock JsonResult, but encodes JSON using JSON.Net, described here.)
public JsonNetResult Index(string keywords)
{
JsonNetResult jsonNetResult = new JsonNetResult();
var documents = solr.Query(new SolrQuery(keywords), new QueryOptions
{
Rows = 10,
Facet = new FacetParameters
{
Queries = new[] {new SolrFacetFieldQuery("system")}
}
});
jsonNetResult.Formatting = Formatting.Indented;
jsonNetResult.Data = documents;
return jsonNetResult;
}
I was expecting to see the faceting information encoded into JSON in the JsonNetResult, but all it contains is the array of hashes of the documents matching my query. Am I missing something in how SolrNet response objects work, or do I really need to parse through the object myself, and create something that JSON.Net can use to encode all of the information related to my query?
FYI, I have tried using a standard JsonResult in MVC, and the results are the same. Also, the reason I am using SolrNet and not just calling Solr directly and asking for JSON is because we do not want to expose the Solr search engine web interface directly to the user.
Since Solr can respond with JSON, if you want to return JSON directly to the view you'd be incurring some unnecessary overhead by having SolrNet deserialize a XML response, then serialize it to JSON. Instead, use SolrNet's components to skip the response parser. A couple of pointers to do this:
SolrQueryExecuter.GetAllParameters()
Low-level SolrNet
I am not sure if this is the best answer, but I have since been experimenting and found that if I change my original line from:
jsonNetResult.Data = documents;
to:
jsonNetResult.Data = new { Documents = documents, FacetFields = documents.FacetFields };
The data is at least serialized by JSON.Net. I guess I still don't understand the format of the object being returned by SolrNet's Query() method, since it seems like those properties (like FacetFields) should be serialized without me having to explicitly name them like I'm now doing above?

NHibernate.IFutureValue<> when serialized includes .Value

I'm building an ASP.NET (2.0, no, I can't change it) site with NHibernate, and have a custom JSON converter so I can not-serialize properties I want hidden from the client. This lets me just return the objects, and never have to worry about their serialized values - they're always secure.
Unfortunately, it appears that if I use query.FutureValue<class>(), the object that gets serialized is first the NHibernate.Impl.FutureValue<class> and not my entity, which means I get JSON that looks like this if I throw it in a dictionary and return it to the client:
{key: { Value: { /* my serialized object properties */ } }
Previously I discovered that I can't get any interfaces to work in ASP's JavaScriptConverter implementations... only regular or abstract classes. So returning typeof(IFutureValue<MyBaseClass>) as a supported type means my converter is completely ignored. I can catch MyBaseClass, because I refactored things earlier to use an abstract base instead of an interface, but not the interface.
And then I discover that the FutureValue implementation in .Impl is internal to the assembly, or some other such nonsense that only serves to make my .NET experience even more painful. So I can't use typeof(FutureValue<MyBaseClass>) to handle it all, because FutureValue exists only in my debugging sessions.
Is there a way to get the class type out of the assembly? Or a way to convince ASP that interfaces do in fact have uses? Or might there be some superclass I can access that would let me get around the whole issue?
Help! I like my Futures, it lets me batch a whole heck-ton of calls at once!
(if something isn't clear, or you want more code, by all means, ask! I can post quite a bit.)
If I'm understanding you correctly, it seems you are mixing things a together a little bit.
It sounds like you're trying to serialize an instance of query.FutureValue<class>(), which unsurprisingly gives you just that: a JSON object where the Value fields has JSON representing your entity.
To me it sounds like you really want to just serialize query.FutureValue<class>().Value.
Using NHibernate futures like this gives you little benefit though, so you're probably after something like:
var future1 = query1.FutureValue<SomeEntity>();
var future2 = query2.FutureValue<AnotherEntity>();
var json1 = serializer.Serialize(future1.Value); //<BAM! Multi-query gets fired!
var json2 = serializer.Serialize(future2.Value);
Does that make sense?

Resources