Updating (patch?) OData object - odata

I have classes as below;
class EMSSecurityUserOData
{
public string odatacontext { get; set; }
public EMSSecurityUser[] value { get; set; }
}
public class EMSSecurityUser
{
public string Oid { get; set; }
public string UserName { get; set; }
public bool IsActive { get; set; }
public string PushDeviceToken { get; set; }
public DateTime PushDeviceTokenOn { get; set; }
}
I am using this code to get the current user;
void GetUser()
{
HttpClient httpClient = new HttpClient();
var Token = await GetAccessToken(_username, _password);
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Token.Token);
string requestAdress = "http://example.com/api/odata/EMSSecurityUser";
string url = $"{requestAdress}?$filter=UserName eq '{username}'";
var json = await httpClient.GetStringAsync(url);
EMSSecurityUser CurrentEMSSecurityUser = JsonConvert.DeserializeObject<EMSSecurityUserOData>(json).value[0];
}
How can I now change just PushDeviceToken and PushDeviceTokenOn and push these changes back? Basically I am looking for c# equivalent of following curl;
curl -X 'PATCH' \
'http://localhost:65202/api/odata/EMSSecurityUser(562f1bde-4b5f-4d58-bf09-5a84d64c53d7)' \
-H 'accept: */*' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json;odata.metadata=minimal;odata.streaming=true' \
-d '{ "PushDeviceToken": "Token Value", "PushDeviceTokenOn":"2022-04-12T00:00:00Z" }'
Thanks
Regards

Related

Exchange ActiveSync, using OAuth2 to read OPTIONS

For an application created and configured in Azure Active Directory I am able to request and obtain a token. When I am trying to use this token to read OPTIONS from Exchange ActiveSync, the response is 401 unauthorized. The source code is below. Obviously I am doing something wrong. Any help is greatly appreciated!
Thank you!
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace FAC.ActiveSync.ModernAuth
{
internal partial class Program
{
private static readonly AzureApp app = new AzureApp
{
TenantId = "***",
ClientId = "***",
ClientSecretId = "***",
ClientSecretValue = "***"
};
static async Task Main()
{
var response = await GetOptions();
}
private static async Task<AccessTokenModel> GetToken()
{
var data = new Dictionary<string, string>
{
{ "grant_type", "client_credentials"},
{ "scope", "https://outlook.office365.com/.default"},
{ "client_id", app.ClientId},
{ "client_secret", app.ClientSecretValue}
};
using (var client = new HttpClient())
{
HttpResponseMessage response =
await client.PostAsync(app.UrlGetToken,
new FormUrlEncodedContent(data));
return await response.Content.ReadAsAsync<AccessTokenModel>();
}
}
private static async Task<string> GetOptions()
{
var accessToken = await GetToken();
var request = new HttpRequestMessage(
HttpMethod.Options,
"https://outlook.office365.com/Microsoft-Server-ActiveSync");
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer",
accessToken.access_token);
var response = await client.SendAsync(request);
return await response.Content.ReadAsStringAsync();
}
}
}
public class AccessTokenModel
{
public string access_token { get; set; }
public string token_type { get; set; }
public int expires_in { get; set; }
public int ext_expires_in { get; set; }
}
public class AzureApp
{
public string TenantId { get; set; }
public string ClientId { get; set; }
public string ClientSecretValue { get; set; }
public string ClientSecretId { get; set; }
public string UrlGetToken
{
get
{
return $"https://login.microsoftonline.com/{TenantId}/oauth2/v2.0/token";
}
}
public string UrlAuthorize
{
get
{
return $"https://login.microsoftonline.com/{TenantId}/oauth2/v2.0/authorize";
}
}
}
}

How Do I Sign In To Google with CEFSharp Browser in WPF?

I know this is a very basic question, but I'm creating a browser in wpf (I'm almost done with it) using CEFSharp, but I hit a snag with logging into google on some accounts. I get a "This browser or app may not be secure." message. Now, I've researched using OAuth to get a token for accessing and using certain features of Google, but not just how to log in as a whole. I just want the user to be able to log into Google, just like they would on a Chrome browser (without the Sync option, of course).
I registered my application with Google Console, and received a ClientId and ClientSecret, and I created a window to be called when the sign-in button is clicked on the google page that tries to get the token, but when the user types in their e-mail, they get the same message (See Below).
I'm not sure if there's an API that I can use or something that can let my user login to google through my browser without having to call the Google Chrome browser itself, because that defeats the purpose of my browser being self-sufficient. I've been beating my head on this for days. Can anyone help?
Below is the xaml for my Google Login window:
<Window x:Class="MyProject.Windows.GoogleLoginWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wpf="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
xmlns:local="clr-namespace:NP_Browser.Windows"
mc:Ignorable="d"
Title="Google Login Window" Height="450" Width="800" Icon="../Images/NPBrowserLogo.ico">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="btv" />
</Window.Resources>
<Grid>
<DockPanel Visibility="{Binding State.IsSigned, Converter={StaticResource btv}}">
<Label Content="{Binding State.Token.Name}" />
</DockPanel>
<Grid Visibility="{Binding State.IsNotSigned, Converter={StaticResource btv}}">
<wpf:ChromiumWebBrowser x:Name="Wb" FontSize="16"/>
</Grid>
</Grid>
Below is the code-behind for my Google Login window:
namespace MyProject.Windows
{
public partial class GoogleLoginWindow : Window
{
public GoogleLoginWindow()
{
InitializeComponent();
State = new OAuthState();
DataContext = this;
Topmost = true;
var thread = new Thread(HandleRedirect);
thread.Start();
}
public OAuthState State { get; }
private async void HandleRedirect()
{
State.Token = null;
var request = OAuthRequest.BuildLoopbackRequest();
var listener = new HttpListener();
listener.Prefixes.Add(request.RedirectUri);
listener.Start();
// note: add a reference to System.Windows.Presentation and a 'using System.Windows.Threading' for this to compile
await Dispatcher.BeginInvoke(() =>
{
Wb.Address = request.AuthorizationRequestUri;
});
// here, we'll wait for redirection from our hosted webbrowser
var context = await listener.GetContextAsync();
// browser has navigated to our small http server answer anything here
string html = string.Format("<html><body></body></html>");
var buffer = Encoding.UTF8.GetBytes(html);
context.Response.ContentLength64 = buffer.Length;
var stream = context.Response.OutputStream;
var responseTask = stream.WriteAsync(buffer, 0, buffer.Length).ContinueWith((task) =>
{
stream.Close();
listener.Stop();
});
string error = context.Request.QueryString["error"];
if (error != null)
return;
string state = context.Request.QueryString["state"];
if (state != request.State)
return;
string code = context.Request.QueryString["code"];
State.Token = request.ExchangeCodeForAccessToken(code);
}
}
// state model
public class OAuthState : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private OAuthToken _token;
public OAuthToken Token
{
get => _token;
set
{
if (_token == value)
return;
_token = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Token)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsSigned)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsNotSigned)));
}
}
public bool IsSigned => Token != null && Token.ExpirationDate > DateTime.Now;
public bool IsNotSigned => !IsSigned;
}
// This is a sample. Fille information (email, etc.) can depend on scopes
[DataContract]
public class OAuthToken
{
[DataMember(Name = "access_token")]
public string AccessToken { get; set; }
[DataMember(Name = "token_type")]
public string TokenType { get; set; }
[DataMember(Name = "expires_in")]
public int ExpiresIn { get; set; }
[DataMember(Name = "refresh_token")]
public string RefreshToken { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Email { get; set; }
[DataMember]
public string Picture { get; set; }
[DataMember]
public string Locale { get; set; }
[DataMember]
public string FamilyName { get; set; }
[DataMember]
public string GivenName { get; set; }
[DataMember]
public string Id { get; set; }
[DataMember]
public string Profile { get; set; }
[DataMember]
public string[] Scopes { get; set; }
// not from google's response, but we store this
public DateTime ExpirationDate { get; set; }
}
// largely inspired from
// https://github.com/googlesamples/oauth-apps-for-windows
public sealed class OAuthRequest
{
private const string ClientId = "My-Client-Id";
private const string ClientSecret = "My-Client-Secret";
private const string AuthorizationEndpoint = "https://accounts.google.com/o/oauth2/v2/auth";
private const string TokenEndpoint = "https://www.googleapis.com/oauth2/v4/token";
private const string UserInfoEndpoint = "https://www.googleapis.com/oauth2/v3/userinfo";
private OAuthRequest()
{
}
public string AuthorizationRequestUri { get; private set; }
public string State { get; private set; }
public string RedirectUri { get; private set; }
public string CodeVerifier { get; private set; }
public string[] Scopes { get; private set; }
// https://developers.google.com/identity/protocols/OAuth2InstalledApp
public static OAuthRequest BuildLoopbackRequest(params string[] scopes)
{
var request = new OAuthRequest
{
CodeVerifier = RandomDataBase64Url(32),
Scopes = scopes
};
string codeChallenge = Base64UrlEncodeNoPadding(Sha256(request.CodeVerifier));
const string codeChallengeMethod = "S256";
string scope = BuildScopes(scopes);
request.RedirectUri = string.Format("http://{0}:{1}/", IPAddress.Loopback, GetRandomUnusedPort());
request.State = RandomDataBase64Url(32);
request.AuthorizationRequestUri = string.Format("{0}?response_type=code&scope=openid%20profile{6}&redirect_uri={1}&client_id={2}&state={3}&code_challenge={4}&code_challenge_method={5}",
AuthorizationEndpoint,
Uri.EscapeDataString(request.RedirectUri),
ClientId,
request.State,
codeChallenge,
codeChallengeMethod,
scope);
return request;
}
// https://developers.google.com/identity/protocols/OAuth2InstalledApp Step 5: Exchange authorization code for refresh and access tokens
public OAuthToken ExchangeCodeForAccessToken(string code)
{
if (code == null)
throw new ArgumentNullException(nameof(code));
string tokenRequestBody = string.Format("code={0}&redirect_uri={1}&client_id={2}&code_verifier={3}&client_secret={4}&scope=&grant_type=authorization_code",
code,
Uri.EscapeDataString(RedirectUri),
ClientId,
CodeVerifier,
ClientSecret
);
return TokenRequest(tokenRequestBody, Scopes);
}
// this is not used in this sample, but can be used to refresh a token from an old one
// https://developers.google.com/identity/protocols/OAuth2InstalledApp Refreshing an access token
public OAuthToken Refresh(OAuthToken oldToken)
{
if (oldToken == null)
throw new ArgumentNullException(nameof(oldToken));
string tokenRequestBody = string.Format("refresh_token={0}&client_id={1}&client_secret={2}&grant_type=refresh_token",
oldToken.RefreshToken,
ClientId,
ClientSecret
);
return TokenRequest(tokenRequestBody, oldToken.Scopes);
}
private static T Deserialize<T>(string json)
{
if (string.IsNullOrWhiteSpace(json))
return default(T);
return Deserialize<T>(Encoding.UTF8.GetBytes(json));
}
private static T Deserialize<T>(byte[] json)
{
if (json == null || json.Length == 0)
return default(T);
using (var ms = new MemoryStream(json))
{
return Deserialize<T>(ms);
}
}
private static T Deserialize<T>(Stream json)
{
if (json == null)
return default(T);
var ser = CreateSerializer(typeof(T));
return (T)ser.ReadObject(json);
}
private static DataContractJsonSerializer CreateSerializer(Type type)
{
if (type == null)
throw new ArgumentNullException(nameof(type));
var settings = new DataContractJsonSerializerSettings
{
DateTimeFormat = new DateTimeFormat("yyyy-MM-dd'T'HH:mm:ss.fffK")
};
return new DataContractJsonSerializer(type, settings);
}
// https://stackoverflow.com/questions/223063/how-can-i-create-an-httplistener-class-on-a-random-port-in-c/
private static int GetRandomUnusedPort()
{
var listener = new TcpListener(IPAddress.Loopback, 0);
listener.Start();
var port = ((IPEndPoint)listener.LocalEndpoint).Port;
listener.Stop();
return port;
}
private static string RandomDataBase64Url(int length)
{
using (var rng = new RNGCryptoServiceProvider())
{
var bytes = new byte[length];
rng.GetBytes(bytes);
return Base64UrlEncodeNoPadding(bytes);
}
}
private static byte[] Sha256(string text)
{
using (var sha256 = new SHA256Managed())
{
return sha256.ComputeHash(Encoding.ASCII.GetBytes(text));
}
}
private static string Base64UrlEncodeNoPadding(byte[] buffer)
{
string b64 = Convert.ToBase64String(buffer);
// converts base64 to base64url.
b64 = b64.Replace('+', '-');
b64 = b64.Replace('/', '_');
// strips padding.
b64 = b64.Replace("=", "");
return b64;
}
private static OAuthToken TokenRequest(string tokenRequestBody, string[] scopes)
{
var request = (HttpWebRequest)WebRequest.Create(TokenEndpoint);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
byte[] bytes = Encoding.ASCII.GetBytes(tokenRequestBody);
using (var requestStream = request.GetRequestStream())
{
requestStream.Write(bytes, 0, bytes.Length);
}
var response = request.GetResponse();
using (var responseStream = response.GetResponseStream())
{
var token = Deserialize<OAuthToken>(responseStream);
token.ExpirationDate = DateTime.Now + new TimeSpan(0, 0, token.ExpiresIn);
var user = GetUserInfo(token.AccessToken);
token.Name = user.Name;
token.Picture = user.Picture;
token.Email = user.Email;
token.Locale = user.Locale;
token.FamilyName = user.FamilyName;
token.GivenName = user.GivenName;
token.Id = user.Id;
token.Profile = user.Profile;
token.Scopes = scopes;
return token;
}
}
private static UserInfo GetUserInfo(string accessToken)
{
var request = (HttpWebRequest)WebRequest.Create(UserInfoEndpoint);
request.Method = "GET";
request.Headers.Add(string.Format("Authorization: Bearer {0}", accessToken));
var response = request.GetResponse();
using (var stream = response.GetResponseStream())
{
return Deserialize<UserInfo>(stream);
}
}
private static string BuildScopes(string[] scopes)
{
string scope = null;
if (scopes != null)
{
foreach (var sc in scopes)
{
scope += "%20" + Uri.EscapeDataString(sc);
}
}
return scope;
}
// https://developers.google.com/+/web/api/rest/openidconnect/getOpenIdConnect
[DataContract]
private class UserInfo
{
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "kind")]
public string Kind { get; set; }
[DataMember(Name = "email")]
public string Email { get; set; }
[DataMember(Name = "picture")]
public string Picture { get; set; }
[DataMember(Name = "locale")]
public string Locale { get; set; }
[DataMember(Name = "family_name")]
public string FamilyName { get; set; }
[DataMember(Name = "given_name")]
public string GivenName { get; set; }
[DataMember(Name = "sub")]
public string Id { get; set; }
[DataMember(Name = "profile")]
public string Profile { get; set; }
[DataMember(Name = "gender")]
public string Gender { get; set; }
}
}
}
You are trying to login on a web view and Google blocks that.
Unfortunately, OAuth for desktop apps is tricky. I have some visual blog posts and a code sample you can run to understand behaviour:
Login by invoking the system browser
Receive the response by spinning up a loopback web server
Or receive the response via a private URI scheme (my preference)
My samples are coded in Electron / Javascript. However, the below C# code samples accompany the IdentityModel security library, and I would recommend using this library for your app:
Loopback Sample
Private Scheme Sample
You need to add this line :
settings.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 /CefSharp Browser" + Cef.CefSharpVersion;
after CefSettings settings = new CefSettings();
Google Blocked logins to it from embedded browser as an act against Man In The Middle Attacks.

How to send a request from Postman going to a Function in ASP.Net MVC?

I'm having a problem trying to send a request from Postman going to the Class function.
Here is my code:
public ChargeInitResponse Post([FromBody]LocaliseChargeInit value)
{
if (value == null)
{
throw new HttpResponseException(HttpStatusCode.BadRequest);
}
ChargeInitResponse reply = new PaymentIntegrationService
{
ChargeInitRequest = value
}.PushChargeInit();
if (reply == null)
{
throw new HttpResponseException(HttpStatusCode.InternalServerError);
}
return reply;
}
ChargeInitResponse Class
public class ChargeInitResponse
{
public string partnerTxID { get; set; }
public string request { get; set; }
public string ErrorMessage { get; set; }
}
LocaliseChargeInit Class
public class LocaliseChargeInit : ChargeInit
{
public string CodeVerifier { get; set; }
public ServiceRequestHeader Header { get; set; }
}
ServiceRequestHeader Class
public class ServiceRequestHeader
{
public string Authorization { get; set; }
public string Date { get; set; }
}
So now my problem is I don't know how to throw a request to the ChargeInitResponse Post via Postman. Do you have any suggestions?

How to find the creation date of an image in a (private) Docker registry (API v2)?

I would like to find out the latest timestamp for an image in a private Docker registry using the v2 API without first pulling the image to my local host.
So after some hacking around, I got the following to work using the curl and jq tools:
curl -X GET http://registry:5000/v2/<IMAGE>/manifests/<TAG> \
| jq -r '.history[].v1Compatibility' \
| jq '.created' \
| sort \
| tail -n1
This seems to work but I don't really know how the v1 Compatibility representation is to be interpreted so I don't know if I am really getting the correct number out of this.
Comments on this are welcome!
With the V2 image manifest, schema version 2, the response from http://registry:5000/v2/<IMAGE>/manifests/<TAG> does not contain the 'history' field, and I haven't found a way to retrieve the image creation date in one request. However one can use another request to obtain it, based on the image manifest config's digest.
First, get the config's digest (notice the header which specifies the schema version):
digest=$(curl -H 'Accept: application/vnd.docker.distribution.manifest.v2+json' \
http://registry:5000/v2/<IMAGE>/manifests/<TAG> \
| jq -r '.config.digest')
The value of digest will be something similar to
sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736.
Then, get the blob of the object identified by the digest, i.e. the configuration object for a container, and retrieve the creation date from there:
curl -H 'Accept: application/vnd.docker.distribution.manifest.v2+json' \
http://registry:5000/v2/<IMAGE>/blobs/$digest | jq -r '.created'
This should produce:
2021-10-27T12:18:24.105617451Z
Bonus: Getting the creation dates using skopeo
I'm not sure if the above is the only or the best way, but by the way, it is apparently more or less what skopeo does under the hood when one runs:
skopeo inspect docker://registry:5000/<IMAGE>:<TAG>
The above command returns information about the image tag, among them the creation date:
{
"Name": "registry:5000/<IMAGE>",
"Digest": "sha256:655721ff613ee766a4126cb5e0d5ae81598e1b0c3bcf7017c36c4d72cb092fe9",
"RepoTags": [...],
"Created": "2021-10-27T12:18:24.105617451Z",
...
}
A minor improvement to the answer from #snth : print the date more user friendly by using date:
date --date=$(curl -s -X GET http://$REGISTRY:5000/v2/$IMAGE/manifests/$TAG | \
jq -r '.history[].v1Compatibility' | jq -r '.created' | sort | tail -n 1 )
Prints something like:
Fr 12. Okt 15:26:03 CEST 2018
Compiling the comments and answers above here is a complete solution
With Authentication
# Setup variables to make this more usalbe
USERNAME=docker_user
PASSWORD=docker_pass
DOCKER_REGISTRY=http://my-registry.myorg.org:9080
REPO=myrepo
TAG=atag
# Query Registry and pipe results to jq
DOCKER_DATE=$(curl -s -u $USERNAME:$PASSWORD -H 'Accept: application/vnd.docker.distribution.manifest.v1+json' -X GET http://$REGISTRY_URL/v2/circle-lb/manifests/master | jq -r '[.history[]]|map(.v1Compatibility|fromjson|.created)|sort|reverse|.[0]')
echo "Date for $REPO:$TAG is $DOCKER_DATE"
Without Authentication
DOCKER_DATE=$(curl -s -H 'Accept: application/vnd.docker.distribution.manifest.v1+json' -X GET http://$REGISTRY_URL/v2/circle-lb/manifests/master | jq -r '[.history[]]|map(.v1Compatibility|fromjson|.created)|sort|reverse|.[0]')
And lastly if you want to parse with the date command (gnu date)
on linux:
date -d $DOCKER_DATE
on mac:
gdate -d $DOCKER_DATE
Here is dotnet core (C#) implementation in case anyone is interested:
public class DockerHub{
public DockerRegistryToken GetRegistryToken(string image){
Console.WriteLine("authenticateing with dockerhub");
using HttpClient client = new ();
var url = string.Format($"https://auth.docker.io/token?service=registry.docker.io&scope=repository:{image}:pull");
//var response = client.Send(new HttpRequestMessage(HttpMethod.Get, url));
var result = client.GetStringAsync(url);
var drt = JsonSerializer.Deserialize<DockerRegistryToken>(result.Result);
return drt;
}
public DateTime GetRemoteImageDate(string image, string tag, DockerRegistryToken token){
using HttpClient client = new ();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Token);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.docker.distribution.manifest.list.v2+json"));
var manifestResult = client.GetStringAsync(string.Format($"https://registry-1.docker.io/v2/{image}/manifests/{tag}"));
var json = JsonDocument.Parse(manifestResult.Result);
var created = json.RootElement.GetProperty("history").EnumerateArray()
.Select(m => JsonDocument.Parse(m.GetProperty("v1Compatibility").ToString()).RootElement.GetProperty("created"))
.Select(m => DateTime.Parse(m.GetString()))
.OrderByDescending(m => m)
.FirstOrDefault(); // I challange you to improve this
Console.WriteLine("Date recieved: {0}",created);
return created.ToUniversalTime();
}
}
public class DockerRegistryToken{
[JsonPropertyName("token")]
public string Token { get; set; }
/// always null
[JsonPropertyName("access_token")]
public string AccessToken {get; set; }
[JsonPropertyName("expires_in")]
public int ExpiresInSeconds { get; set; }
[JsonPropertyName("issued_at")]
public DateTime IssuedAt { get; set; }
}
To use
var client = new DockerHub();
var tok = client.GetRegistryToken("your/reponame");
var remoteImageDate = client.GetRemoteImageDate("your/reponame","latest",tok);
Some idea for C#:
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
namespace DockerApi;
public class Manifests
{
[JsonPropertyName("schemaVersion")]
public long SchemaVersion { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; }
[JsonPropertyName("tag")]
public string Tag { get; set; }
[JsonPropertyName("architecture")]
public string Architecture { get; set; }
[JsonPropertyName("fsLayers")]
public FsLayer[] FsLayers { get; set; }
[JsonPropertyName("history")]
public History[] History { get; set; }
[JsonPropertyName("signatures")]
public Signature[] Signatures { get; set; }
public V1Compatibility V1Compatibility
{
get
{
var jsonNode = JsonNode.Parse(History.Where(m => m.V1Compatibility.Contains("architecture")).First().V1Compatibility);
return JsonSerializer.Deserialize<V1Compatibility>(jsonNode);
}
}
}
public partial class FsLayer
{
[JsonPropertyName("blobSum")]
public string BlobSum { get; set; }
}
public partial class History
{
[JsonPropertyName("v1Compatibility")]
public string V1Compatibility { get; set; }
}
public partial class Signature
{
[JsonPropertyName("header")]
public Header Header { get; set; }
[JsonPropertyName("signature")]
public string SignatureSignature { get; set; }
[JsonPropertyName("protected")]
public string Protected { get; set; }
}
public partial class Header
{
[JsonPropertyName("jwk")]
public Jwk Jwk { get; set; }
[JsonPropertyName("alg")]
public string Alg { get; set; }
}
public partial class Jwk
{
[JsonPropertyName("crv")]
public string Crv { get; set; }
[JsonPropertyName("kid")]
public string Kid { get; set; }
[JsonPropertyName("kty")]
public string Kty { get; set; }
[JsonPropertyName("x")]
public string X { get; set; }
[JsonPropertyName("y")]
public string Y { get; set; }
}
public partial class V1Compatibility
{
[JsonPropertyName("architecture")]
public string Architecture { get; set; }
[JsonPropertyName("config")]
public Config Config { get; set; }
[JsonPropertyName("created")]
public DateTimeOffset Created { get; set; }
[JsonPropertyName("id")]
public string Id { get; set; }
[JsonPropertyName("os")]
public string Os { get; set; }
[JsonPropertyName("parent")]
public string Parent { get; set; }
[JsonPropertyName("throwaway")]
public bool Throwaway { get; set; }
}
public partial class Config
{
[JsonPropertyName("Env")]
public string[] Env { get; set; }
[JsonPropertyName("Cmd")]
public string[] Cmd { get; set; }
[JsonPropertyName("WorkingDir")]
public string WorkingDir { get; set; }
[JsonPropertyName("ArgsEscaped")]
public bool ArgsEscaped { get; set; }
[JsonPropertyName("OnBuild")]
public object OnBuild { get; set; }
}

How to get Json Data from IPinfodb.com with MVC WebService/Method

I want to get User's Location based on IP. When user enters website
I used to do it with XMLHTTPREquest in classic asp
how to do it with .net MVC.
I am new to .net
A combination of WebClient and JavaScriptSerializer classes could help you. As always start by defining a class that will represent your model:
public class LocationResult
{
public string Ip { get; set; }
public string Status { get; set; }
public string CountryCode { get; set; }
public string CountryName { get; set; }
public string RegionCode { get; set; }
public string RegionName { get; set; }
public string City { get; set; }
public string ZipPostalCode { get; set; }
public float Latitude { get; set; }
public float Longitude { get; set; }
}
and then call the service and deserialize the JSON result back to your model:
public LocationResult GetLocationInfo(string ip)
{
using (var client = new WebClient())
{
// query the online service provider and fetch the JSON
var json = client.DownloadString(
"http://ipinfodb.com/ip_query.php?ip=" + ip +
"&output=json&timezone=false"
);
// use the JavaScriptSerializer to deserialize the JSON
// result back to a LocationResult
var serializer = new JavaScriptSerializer();
return serializer.Deserialize<LocationResult>(json);
}
}

Resources