Archive

Author Archive

Creating an #API from an #XML file in C#

661763-636519532411453000-16x9

Let’s say you’ve been given a large XML file – Let’s say, it’s too large to be stored in memory, and it contains data that you want to show wihin an App. Perhaps you don’t want to package the XML file with your app, because perhaps it’s big, or perhaps you don’t want someone extracting all your data wholesale, if they decompile your app.

You don’t want to have the app download the XML file, since it’s huge, and is going to be slow to download, and once again, could allow someone who decompiles your app, the ability to copy all your data,  Instead, you want to have your app send search queries to your server, and have your server read the XML file in an efficient way, and return snippets in JSON back to the App.

So, lets create an API in C# to do that, using ASP.NET

First off, you need a way to read an XML file node by node in C#, without reading the entire document into memory, as I said, in this example, imagine the XML file is too big to load into memory at once – or you don’t want to unduly use too much memory on your server.

Here’s a code snippet to do that;

private static IEnumerable<XElement> SimpleStreamAxis(string inputUrl,
string elementName)
{
using (var reader = XmlReader.Create(inputUrl))
{
reader.MoveToContent();
while (reader.Read())
{
if (reader.NodeType != XmlNodeType.Element) continue;
if (reader.Name != elementName) continue;
var el = XNode.ReadFrom(reader) as XElement;
if (el != null)
{
yield return el;
}
}
}
}

Now, assuming I have my XML file in a folder called /Data and it’s called clubs.xml. The Node I want to iterate is called GolfClubDTO and the element I want to search on is called ClubCity – so here’s my code

var strSearch = Request.QueryString[“Search”];
if (string.IsNullOrEmpty(strSearch))
{
Response.Write(“Pass a Search Param!”);
Response.End();
}
var strXmlPath = Server.MapPath(“~/data/Clubs.xml”);
var xeClubs = SimpleStreamAxis(strXmlPath, “GolfClubDTO”);
var lClubs = new List<XElement>();
foreach (var xeClub in xeClubs)
{
// ClubCity
var xClubCity = xeClub.Elements().FirstOrDefault(c => c.Name.LocalName == “ClubCity”);
if (xClubCity != null)
{
var strClubCity = xClubCity.Value;
if (strClubCity.ToLower() == strSearch.ToLower())
{
lClubs.Add(xeClub);
}
}
}
var strJson = JsonConvert.SerializeObject(lClubs, Newtonsoft.Json.Formatting.Indented);
Response.ContentType = “application/json”;
Response.AddHeader(“Access-Control-Allow-Origin”, “*”);
Response.Write(strJson);

Here I am also writing out the data with the mime type application/json and allowing CORS, to make life easier for my clients.

 

 

 

Categories: Uncategorized

New tech to cut 50% off IOT bandwidth usage. UDPAPI.com

udpapi

IOT devices are often connected to the cloud via costly mobile data network connections, where every MB of data transmitted can quickly add up. Quite often an IOT device calls a HTTP endpoint in the cloud, and there is quite alot of needless overhead in the transmission of HTTP headers, and TCP/IP handshakes.

UDP/IP is a protocol designed for transmitting data that can forgive a certain level of dropped packets and out-of-order transmissions, but it has half the overhead of TCP/IP. However, you can’t just send a UDP packet to an HTTP server, and expect it to respond.

This is where UDPAPI.com comes in, you can define a UDP Port, and a HTTP endpoint, and this gateway will forward data received via the UDP protocol on that port to your defined HTTP endpoint, thus saving you up to 50% on your bandwidth costs.

UDP can half the bandwidth useage of your IOT device with respect to the more normal TCP/IP. If your IOT device is communicating over expensive cellular data networks, and is particularly ‘chatty’ then this can save you significantly on your costs. All this without having to re-write your back-end code, or alter firewall rules.

With UdpAPI.com, you modify the code in your IOT device to send a UDP packet to our server at a port that we provide you with, and we will forward the data via HTTP-POST to a URL endpoint of your choosing. We monitor for errors, and keep track of your bandwidth usage, so that you can keep an eye on problems in real-time.

UDPAPI.com is free for early adopters, and will remain free for ever for those first registered users. – Give it a go, and send us feedback!

Categories: Uncategorized

Synchronizing #Resx files within a .NET project

resx

If you are developing a multi-lingual website or application in .NET, then you undoubtedly use resx files. Over time, it’s likely that these files go out of sync, when you add text to the english version, and forget to send the french version for translation.

Here’s some code in C# that can compare a master resx file (english) with a candidate file (french), and determine what keys are missing, and what keys are present, but not translated.

To start off with, lets create an XSD model for the resx xml;

<?xml version=”1.0″ encoding=”UTF-8″?>
<xs:schema xmlns:xs=”http://www.w3.org/2001/XMLSchema&#8221; elementFormDefault=”qualified”>
<xs:import namespace=”http://www.w3.org/XML/1998/namespace&#8221; schemaLocation=”xml.xsd”/>
<xs:element name=”root”>
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs=”unbounded” ref=”resheader”/>
<xs:element maxOccurs=”unbounded” ref=”data”/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name=”resheader”>
<xs:complexType>
<xs:complexContent>
<xs:extension base=”value”>
<xs:attribute name=”name” use=”required” type=”xs:NCName”/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name=”data”>
<xs:complexType>
<xs:complexContent>
<xs:extension base=”value”>
<xs:sequence>
<xs:element minOccurs=”0″ ref=”comment”/>
</xs:sequence>
<xs:attribute name=”name” use=”required”/>
<xs:attribute ref=”xml:space”/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name=”comment” type=”xs:string”/>
<xs:complexType name=”value”>
<xs:sequence>
<xs:element ref=”value”/>
</xs:sequence>
</xs:complexType>
<xs:element name=”value” type=”xs:string”/>
</xs:schema>

From this, I create resx.cs by running xsd.exe, and include it in my project

Two helper functions I’m going to need is some code to serialise and deserialise the XML into objects as follows;

public static T ParseXmlData<T>(string xml)
{
var xsT = new XmlSerializer(typeof(T));
var srT = new StringReader(xml);
return (T)xsT.Deserialize(srT);
}
public static string Serialize<T>(T o)
{
var swOutput = new StringWriter();
var xs = new XmlSerializer(typeof(T));
xs.Serialize(swOutput, o);
return swOutput.ToString();
}

Now, lets create the main function

private static void CompareResx(string masterFile, string testFile, string outputFile)
{
var strMasterXml = File.ReadAllText(masterFile);
var strTestXml = File.ReadAllText(testFile);
var rootMaster = ParseXmlData<root>(strMasterXml);
var rootTest = ParseXmlData<root>(strTestXml);
if (rootTest.data == null) return;
var lMissingNodes = new List<data>();
foreach (var entry in rootMaster.data)
{
var testEntry = rootTest.data.FirstOrDefault(e => e.name == entry.name);
if (testEntry != null)
{
if (testEntry.value1 == entry.value1)
{
Console.WriteLine(“English?” + entry.name);
lMissingNodes.Add(entry);
}
else if (string.IsNullOrEmpty(testEntry.value1))
{
Console.WriteLine(“Blank entry:” + entry.name);
lMissingNodes.Add(entry);
}
}
else
{
Console.WriteLine(“Missing entry:” + entry.name);
lMissingNodes.Add(entry);
}
}
var output = new root();
output.data = lMissingNodes.ToArray();
var strOutputXml = Serialize(output);
File.WriteAllText(outputFile, strOutputXml);
}

Pass in the location of the master resx, the candidate resx, and an output file, and then run this code.

Categories: Uncategorized

Image recognition using #Azure Computer Vision with C#

car1

Assuming you have an Azure account, if you open up a Computer vision service under Cognitive Services, and grab an API key, you can use Azure to recognise the content of images. – Great for tagging images in blogs, or making sure nobody uploads a nude pic as their profile image on your website – For which you should check out AvatarApi.com for this!

So, lets see some code – I’m using C#, and Newtonsoft to parse the Json;

const string strUrl = “https://westeurope.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Tags&#8221;;
var wc = new WebClient();
wc.Headers[“Ocp-Apim-Subscription-Key”] = “xxxxxxx”;
var jPost = new { url = Url };
var strPost = JsonConvert.SerializeObject(jPost, Formatting.Indented);
var strJson = wc.UploadString(strUrl, “POST”, strPost);
var jResult = JObject.Parse(strJson);

Depending on your image of course, this will return JSON similar to the following;

{
  "tags": [
    {
      "name": "car",
      "confidence": 0.99999725818634
    },
    {
      "name": "outdoor",
      "confidence": 0.99585741758347
    },
    {
      "name": "transport",
      "confidence": 0.82641708850861
    },
    {
      "name": "blue",
      "confidence": 0.51219713687897
    },
    {
      "name": "roof",
      "confidence": 0.091790720820427
    },
    {
      "name": "automotive",
      "confidence": 0.01434036432286
    },
    {
      "name": "summer",
      "confidence": 0.0078773201327271
    }
  ],
  "requestId": "e0010f8b-189f-4481-ad02-5b71b3ac2b2b",
  "metadata": {
    "width": 1600,
    "height": 1200,
    "format": "Jpeg"
  }
}

 

Categories: Uncategorized

Simple #UDP/IP client/server in C#

udp

TL;DR;

You can grab the code for this demo here https://github.com/infiniteloopltd/udp

Internet traffic can be thought of as layers, normally the stack for viewing a website is IP at the bottom, TCP/IP in the middle, and HTTP at the top.

IP just gets data from A to B , TCP/IP makes sure that data doesn’t get jumbled or dropped in between, and HTTP does things specific to serving websites, like HTTP redirects, HTTP error messages etc.

But, instead of TCP/IP you can also use UDP/IP or simply “UDP”, which is TCP’s messy little brother. It still has the concept of ports like TCP has, but offers no guarantee of jumbled or dropped data.

For this reason, UDP is only used in situations where low latency is much more important than data integrity, like audio / video streaming or gaming. It’s terrible for file transfer.

One other key use of UDP is it’s lower bandwidth usage, which makes it useful for IOT applications over expensive mobile data networks.

If you want to read more about Network programming, check out my book- which you can Buy at Amazon US or Buy at Amazon UK

 

Categories: Uncategorized

‘Promise’ is undefined #IE11

1_Bf17KrH3fJo09LTKHRYJcw

Javascript promises are a key feature of modern asyncronous javascript, but, if you’re developing a mass-market website, cross-browser support may trump the syntactical sugar, especially if you’re facing down business-types, rather than other developers.

Specifically, IE11 does not support Javascript promises, and if you are looking to support a wide range of browsers, then there is a polyfill available from Taylor Hakes, that can get round that error message, that simply says “‘Promise’ is undefined” in IE11

So, working with an example from SMTPJS v3 – which now uses promises, and arrow functions, you need include the following script tags;

https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.min.js
https://smtpjs.com/v3/smtp.js

Then adjust the code to use an inline function instead of an arrow function:

Email.send({
Host : “email-smtp.eu-west-1.amazonaws.com”,
Username : “******”,
Password : “*****”,
To : ‘them@gmail.com’,
From : “you@website.com”,
Subject : “This is the subject”,
Body : “My useragent is ” + navigator.userAgent
}).then(
function(message) { alert(message) } // FOR IE
);

Categories: Uncategorized

#SMTPJS now supports multiple attachments, ReplyTo and sender name

smtpjs

In case you’ve missed it, SMTPJS.com has just released the V3 Library, this offers a cleaner object model, promises, and new features, such as multiple attachments, Reply-to, and sender name

Here’s an example on how to send multiple attachments:

Email.send({
SecureToken : “XXXXX-XXXX-XXXX-XXXX-XXXXXXX”,
To : “recipient@website.com”,
From : “sender@website.com”,
FromName: “Joe Sender”,
ReplyAddress: “noreply@website.com”,
Subject : “This is the subject”,
Body : “This is the body”,
Attachments : [
{
name : “padlock.png”,
path : “https://www.smtpjs.com/img/ipad.png&#8221;
},
{
name : “spam.png”,
path : “https://www.smtpjs.com/img/iphone.png&#8221;
}
]
}).then(
message => alert(message)
);

Obviously, you need to change the secureToken property above, or pass in naked SMTP credentials.

Here’s another example, imagine you want to offer an upload form, so people can upload a file to be sent to you – without putting the file on your server.

First, here’s the required line of HTML:

<input type=”fileid=”fileuploadonchange=”uploadFileToServer()” />

Then here’s the uploadFileToServer() method;

function uploadFileToServer() {
var file = event.srcElement.files[0];
var reader = new FileReader();
reader.readAsBinaryString(file);
reader.onload = function () {
var datauri = “data:” + file.type + “;base64,” + btoa(reader.result);
Email.send({
SecureToken : “XXXX-XXXX-XXXX-XXXX-XXXX”,
To : “recipient@website.com”,
From : “sender@isp.com”,
Subject : “The subject”,
Body : “See file attached”,
Attachments : [
{
name : file.name,
data : datauri
}
]
}).then(
message => alert(message)
);
};
reader.onerror = function() {
console.log(‘there are some problems’);
};
}

Categories: Uncategorized

Support for #Motorcycle registration lookups in #Spain via #API

1501179276-bosch-2wp-motorcycle-stabiliy-control-008

Need to find vehicle details of a motorcycle registered in Spain via an API?, this new addition to our suite lets you do this; you should use an alternative API endpoint, as follows;

http://www.matriculaapi.com/api/bespokeapi.asmx?op=CheckMotorBikeSpain

Which returns data in the following format:

{

 “Description”: “SUZUKI DL 650 V-STROM”,

 “CarMake”: {

   “CurrentTextValue”: “SUZUKI”

 },

 “CarModel”: {

   “CurrentTextValue”: “DL 650”

 },

 “MakeDescription”: {

   “CurrentTextValue”: “SUZUKI”

 },

 “ModelDescription”: {

   “CurrentTextValue”: “DL 650”

 },

 “EngineSize”: “645”,

 “VehicleIdentificationNumber”: “”,

 “RegistrationYear”: “2003”,

 “RegistrationDate”: “01/11/2003”,

 “Variation”: “V-STROM”,

 “Seats”: 1,

 “VariantType”: “”,

 “VehicleType”: “MOTOCICLETA”,

 “Fuel”: “GASOLINA”,

 “IndicativePrice”: “7909.79”,

 “Doors”: 0,

 “AllTerain”: 0,

 “KType”: 0,

 “ImageUrl”: “http://matriculaapi.com/image.aspx/@U1VaVUtJIERMIDY1MHxtb3RvcmN5Y2xl&#8221;,

 “Transmission”: “MANUAL”,

 “DynamicPower”: “68”,

 “Stolen”: null

}

Categories: Uncategorized

A simple change to make your website #IPv6 ready.

download

Making your website accessible by both IPv4 (What everyone is familiar with) and IPv6, those wierd long IP addresses with hex numbers in them, is as simple as

(1) finding your IPv6 address, which you can do by doing a IPConfig /all on your desktop

And getting the IPv6 address from the “6TO4 adapter”

Tunnel adapter 6TO4 Adapter:

Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : Microsoft 6to4 Adapter
Physical Address. . . . . . . . . : 00-00-00-00-00-00-00-E0
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes
IPv6 Address. . . . . . . . . . . : 2002:5f9a:f46a::5f9a:f46a(Preferred)
Default Gateway . . . . . . . . . : 2002:c058:6301::1
DHCPv6 IAID . . . . . . . . . . . : 469762048
DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-21-42-14-1B-00-25-90-1E-04-94

(2) Then adding a DNS entry for an AAAA record pointing to the IPv6 address that you found above.

I doubt it will make much difference today or tomorrow, since IPv4 will take a long long time to die out completely, but slowly, IPv6 will become the norm, and it’s best to be ahead of the curve, rather than being behind it.

 

 

Categories: Uncategorized

Run #ASP.NET on #Ubuntu using .NET Core

Screenshot 2018-11-27 at 10.54.01

Yes, it’s possible to host ASP.NET on linux, and there are plenty of great tutorials out there, and this is just a quick post with a few of my tips thrown in…

I followed the tutorial at https://www.microsoft.com/net/learn/web/aspnet-hello-world-tutorial, using a EC2 instance from Amazon.

However, at the point where it says, “point a browser at https://localhost:5001&#8221; I had to get a bit inventive,

So, I opened up port 5001 in security settings, and I created a release build

dotnet build –configuration Release

Navigated to the “publish” folder and ran this command to have the app listen on all hosts, not just localhost.

dotnet myWebAppp.dll –urls https://0.0.0.0:5001

Then from my mac, I could navigate to https://%5BIP%5D:5001, and dismissed the bad cert warning.

Categories: Uncategorized