I have added a WebAuthenticator.AuthenticateAsync method in my xamarin forms app with start up Url as "https://accounts.google.com/o/oauth2/auth"
and call back url as "myapp://"
I have also tried with call back url as "com.googleusercontent.apps.{clientId}:/oauth2redirect"
I am doing this to add google login in my xamarin forms app.
On this browser with available google accounts are been showing up and after successful completion of email authentication it returns to app but result is not returned from WebAuthenticator.AuthenticateAsync method.
On second time invocation of this method returns the first invocation result as cancelled by user and the browser opens again for second time email authentication.
But it works in ios.
I have added 3 classes
public class Auth0Client
{
private readonly OidcClient oidcClient;
public Auth0Client(Auth0ClientOptions options)
{
var discovery = new DiscoveryPolicy
{
ValidateEndpoints = false,
Authority = "https://accounts.google.com"
};
oidcClient = new OidcClient(new OidcClientOptions
{
Authority = $"https://accounts.google.com/o/oauth2/auth",
ClientId = options.ClientId,
Scope = options.Scope,
RedirectUri = options.RedirectUri,
Browser = options.Browser,
ProviderInformation = options.ProviderInformation,
Policy = new Policy
{
Discovery = discovery,
RequireAccessTokenHash = false
},
});
}
public IdentityModel.OidcClient.Browser.IBrowser Browser
{
get
{
return oidcClient.Options.Browser;
}
set
{
oidcClient.Options.Browser = value;
}
}
public async Task<LoginResult> LoginAsync()
{
return await oidcClient.LoginAsync();
}
}
public class Auth0ClientOptions
{
public Auth0ClientOptions()
{
}
public string Domain { get; set; }
public string ClientId { get; set; }
public string RedirectUri { get; set; }
public string Scope { get; set; }
public IBrowser Browser { get; set; }
public ProviderInformation ProviderInformation { get; set; }
}
public class WebBrowserAuthenticator : IBrowser
{
public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = default)
{
try
{
WebAuthenticatorResult result = await WebAuthenticator.AuthenticateAsync(
new Uri(options.StartUrl),new Uri(options.EndUrl));
var url = new RequestUrl(options.EndUrl)
.Create(new Parameters(result.Properties));
return new BrowserResult
{
Response = url,
ResultType = BrowserResultType.Success
};
}
catch (Exception ex)
{
return new BrowserResult
{
ResultType = BrowserResultType.UserCancel,
ErrorDescription = "Login canceled by the user."
};
}
}
}
In view model we are creating authoclient
private async void NavigateToGoogleLogin(object obj)
{
string clientId = null;
string redirectUri = null;
switch (Device.RuntimePlatform)
{
case Device.iOS:
clientId = AppConstants.GoogleiOSClientId;
redirectUri = AppConstants.GoogleiOSRedirectUrl;
break;
case Device.Android:
clientId = AppConstants.GoogleAndroidClientId;
redirectUri = AppConstants.GoogleAndroidRedirectUrl;
break;
}
var auth0client = new Auth0Client(new Auth0ClientOptions()
{
Domain = "accounts.google.com/o/oauth2/auth",
ClientId = clientId,
RedirectUri = redirectUri,
Scope = AppConstants.GoogleScope,
Browser = new WebBrowserAuthenticator(),
ProviderInformation = new ProviderInformation
{
IssuerName = "accounts.google.com",
AuthorizeEndpoint = AppConstants.GoogleAuthorizeUrl,
TokenEndpoint = AppConstants.GoogleAccessTokenUrl,
UserInfoEndpoint = AppConstants.GoogleUserInfoUrl,
KeySet = new JsonWebKeySet(),
},
});
var loginResult = await auth0client.LoginAsync();
}
We are using below constants in authoclient object creation
internal static string GoogleScope = "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile";
internal static string GoogleAuthorizeUrl = "https://accounts.google.com/o/oauth2/auth";
internal static string GoogleAccessTokenUrl = "https://www.googleapis.com/oauth2/v4/token";
internal static string GoogleUserInfoUrl = "https://www.googleapis.com/oauth2/v3/userinfo";
Xamarin forms version:5.0.0.2012
Xamarin essentials: 1.7.3
Thanks in advance
I am trying to consume an endpoint with RestSharp with Basic authentication.
I followed the instructions on the documentation https://restsharp.dev/getting-started/getting-started.html
The request was successful but I think the request body was malformed.
How can I get this to work
internal BalanceInquiryResponse BalanceInquiryRest(BalanceInquiryRequest BalanceInquiryRequest, Settings Settings)
{
// BalanceInquiryResponse BalanceInquiryResponse = new BalanceInquiryResponse();
var client = new RestClient(Settings.BaseUrl + "All/Inquiry");
client.Authenticator = new HttpBasicAuthenticator(Settings.Username, Settings.Password);
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddJsonBody(new
{
Acc = BalanceInquiryRequest.Acc
});
IRestResponse response = client.Execute(request);
IRestResponse<BalanceInquiryResponse> res = client.Execute<BalanceInquiryResponse>(request);
if (response.IsSuccessful)
{
BalanceInquiryResponse = new BalanceInquiryResponse
{
responseInquiry = res.Data.responseInquiry,
ResponseDescription = res.Data.ResponseDescription,
ResponseMessage = res.Data.ResponseMessage
};
return BalanceInquiryResponse;
}
else
{
BalanceInquiryResponse = new BalanceInquiryResponse
{
ResponseDescription = responseses.ErrorMessage,
};
return BalanceInquiryResponse;
}
}
This is my response body
{
"responseMessage": "Successful",
"responseDescription": "Request Successful",
"responseInquiry": null
}
When I tried with postman I got
{
"ResponseMessage": "Successful",
"ResponseDescription": "Request Successful",
"response": {
"AvalBal": 586324.42,
"ReverAmt": 0,
"AccCurrency": "US "
}
}
IRestResponse<BalanceInquiryResponse> res = client.Execute<BalanceInquiryResponse>(request);
So there is a specific reason...you are putting BalanceInquiryResponse in the generic IRestResponse above.
With the above call, this should automatically hydrate the BalanceInquiryResponse object, and you shouldn't need to hand map.
Aka, you should ~not~ need this below code:
BalanceInquiryResponse = new BalanceInquiryResponse
{
responseInquiry = res.Data.responseInquiry,
ResponseDescription = res.Data.ResponseDescription,
ResponseMessage = res.Data.ResponseMessage
};
I think your issue is that your POCO object (BalanceInquiryResponse) should perfectly match the "structure" of the JSON.
Change your BalanceInquiryResponse to PERFECTLY match the json "properties".
and recognize you have a nested object.
I think it it would be:
public class ResponsePoco {
public double AvalBal { get; set; }
public int ReverAmt { get; set; }
public string AccCurrency { get; set; }
}
public class BalanceInquiryResponse{
public string ResponseMessage { get; set; }
public string ResponseDescription { get; set; }
public ResponsePoco response { get; set; }
}
Pay attention the to "ResponsePoco response"..note the variable name is LOWERCASE .. because...the json has a lowercase "response" in it.
I have called the (child) object "ResponsePoco" to highlight the difference between the object name and the variable name.
If you cannot "perfectly" match the Poco properties. you can use attributes to "massage" the discrepencies. As seen here:
https://www.newtonsoft.com/json/help/html/JsonPropertyName.htm
public class Videogame
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("release_date")]
public DateTime ReleaseDate { get; set; }
}
I am using .NET Core with Boilerplate. I'm trying to unit test some new forms that require that I have nested objects with properties. The Integration Tests use AbpAspNetCoreIntegratedTestBase<Startup> which uses an instance of both HttpClient and TestServer. The client has various types of methods at its disposal. There are GetAsync, PostAsync, SendSync and PutAsync methods just to name a few.
I thought I had gotten comfortable with some of the methods and helper methods in this frame work and have been successful thus far. However, I have a form with an Model called Vendor, the Vendor has an Address Model as part of the view model. This is so I can reuse the Address View Model with other items in the application that also require Address(es).
One of the helpers that is used with BoilerPlate is GetUrl<TController>(string actionName, object queryStringParamsAsAnonymousObject) Since this is a Post from a form I'm attempting to use public Task<HttpResponseMessage> PostAsync(string requestUri, HttpContent content) No matter what I'm attempting to do, I'm getting a 400 Bad Request response and my test fails before it even gets inside the controller method. I'm at a loss of how to handle this.
Here are my Models:
VendorViewModel:
[AutoMap(typeof(Domains.Vendor))]
public class VendorViewModel : BaseViewModelEntity
{
[Required]
public string Name { get; set; }
[Required]
public string PointOfContact { get; set; }
[Required]
public string Email { get; set; }
[Required]
public int AddressId { get; set; }
//[Required]
//public string Address1 { get; set; }
//public string Address2 { get; set; }
//public string Address3 { get; set; }
//[Required]
//public string City { get; set; }
//[Required]
//public int State { get; set; }
//[Required]
//public string Zip { get; set; }
//[Required]
//public string Phone { get; set; }
//public string Fax { get; set; }
public AddressViewModel VendorAddress { get; set; }
public VendorViewModel()
{
VendorAddress = new AddressViewModel();
}
public VendorViewModel(VendorDto vendor)
{
Id = vendor.Id;
Name = vendor.Name;
IsActive = vendor.IsActive;
PointOfContact = vendor.PointOfContact;
Email = vendor.Email;
AddressId = vendor.AddressId;
CreatorUserId = vendor.CreatorUserId;
CreationTime = vendor.CreationTime;
DeleterUserId = vendor.DeleterUserId;
DeletionTime = vendor.DeletionTime;
LastModificationTime = vendor.LastModificationTime;
LastModifierUserId = vendor.LastModifierUserId;
//Address1 = vendor.Address.Address1;
//Address2 = vendor.Address.Address2;
//Address3 = vendor.Address.Address3;
//City = vendor.Address.City;
//State = vendor.Address.State;
//Zip = vendor.Address.Zip;
//Phone = vendor.Address.Phone;
//Fax = municipalities.Address.Fax;
VendorAddress = new AddressViewModel()
{
Id = vendor.Address.Id,
Address1 = vendor.Address.Address1,
Address2 = vendor.Address.Address2,
Address3 = vendor.Address.Address3,
City = vendor.Address.City,
State = vendor.Address.State,
Zip = vendor.Address.Zip,
Phone = vendor.Address.Phone,
Fax = vendor.Address.Fax,
CreationTime = vendor.Address.CreationTime,
};
}
}
Address View Model:
public class AddressViewModel : BaseViewModelEntity
{
[Required]
public string Address1 { get; set; }
public string Address2 { get; set; }
public string Address3 { get; set; }
[Required]
public string City { get; set; }
[Required]
public int State { get; set; }
[Required]
public string Zip { get; set; }
[Required]
public string Phone { get; set; }
public string Fax { get; set; }
public AddressViewModel()
{
}
public AddressViewModel(AddressDto address)
{
Id = address.Id;
Address1 = address.Address1;
Address2 = address.Address2;
Address3 = address.Address3;
City = address.City;
State = address.State;
Zip = address.Zip;
Phone = address.Phone;
Fax = address.Phone;
CreatorUserId = address.CreatorUserId;
CreationTime = address.CreationTime;
DeleterUserId = address.DeleterUserId;
DeletionTime = address.DeletionTime;
LastModificationTime = address.LastModificationTime;
LastModifierUserId = address.LastModifierUserId;
}
}
I have my Test set up with xUnit
//Arrange
//Add Client Headers so User Auth and Permission Checkers work correctly
Client.DefaultRequestHeaders.Add("my-name", "admin");
Client.DefaultRequestHeaders.Add("my-id", "2");
//set up test data
var addressViewModel = new AddressViewModel()
{
Address1 = "123 This Way", City = "Arlington", State = 44, Zip = "76001", Phone = "8175555555",
CreationTime = DateTime.Now
};
var viewModelSave = new VenderViewModel()
{
Name = "Controller Test Name",
PointOfContact = "Tom Jerry",
Email = "Tom.Jerry#yolo.com",
CreationTime = DateTime.Now,
LastModificationTime = null,
IsActive = true,
AddressId = 0,
VendorAddress = addressViewModel
//Address1 = "123 This Way",
//City = "Arlington",
//State = 44,
//Zip = "76001",
//Phone = "8175555555"
};
/* This is an attempt to use string interpolation to create querystring parameters */
//var rawData =
// $"?Name={viewModelSave.Name}&Id={viewModelSave.Id}&PointOfContat=${viewModelSave.PointOfContact}&Email={viewModelSave.Email}&CreationTime={DateTime.Now}" +
// $"&LastModificationTime=&IsActive={viewModelSave.IsActive}&AddressId={viewModelSave.AddressId}&VendorAddress.Id={viewModelSave.VendorAddress.Id}&VendorAddress.Address1={viewModelSave.VendorAddress.Address1}" +
// $"&VendorAddress.City={viewModelSave.VendorAddress.City}&VendorAddress.State={viewModelSave.VendorAddress.State}&VendorAddress.Zip={viewModelSave.VendorAddress.Zip}&VendorAddress.Phone={viewModelSave.VendorAddress.Phone}" +
// $"&VendorAddress.CreationTime={DateTime.Now}&VendorAddress.IsActive={viewModelSave.VendorAddress.IsActive}";
/*This is an attempt to create a json object that could be serialize into an object as the "queryStringParamsAsAnonymousObject" that can be used in the GetUrl Helper method below */
var rawData = $"{{'Name':'Controller Test Name','PointOfContact':'Tom Jerry', 'Email': 'Tom.Jerry#yolo.com',"
+ "'CreationTime':'" + DateTime.Now + "','LastModificationTime':'','IsActive' : 'true','AddressId':'0','Address.Address1':'123 This Way',"
+ "'Address.City':'Arlington','Address.State':'44','Address.Zip':'76001','Address.Phone':'8175555556','Address.IsActive':'true'}";
var jsonData = JsonConvert.DeserializeObject(rawData);
//Serialize ViewModel to send with Post as part of the HttpContent object
var data = JsonConvert.SerializeObject(viewModelSave);
var vendorAddress = new
{
viewModelSave.vendorAddress.Id,
viewModelSave.vendorAddress.Address1,
viewModelSave.vendorAddress.City,
viewModelSave.vendorAddress.State,
viewModelSave.vendorAddress.Zip,
viewModelSave.vendorAddress.Phone,
viewModelSave.vendorAddress.IsActive,
viewModelSave.vendorAddress.CreationTime
};
//actually get the url from helper method (with various attempts at creating an anonymousObject directly
var url = GetUrl<VendorController>(nameof(VendorController.SaveVendor),
new
{
viewModelSave.Id,
viewModelSave.Name,
viewModelSave.PointOfContact,
viewModelSave.Email,
viewModelSave.CreationTime,
viewModelSave.LastModificationTime,
viewModelSave.IsActive,
viewModelSave.AddressId,
vendorAddress
//VendorAddress_Address1 = vendorAddress.Address1,
//VendorAddress_Id = vendorAddress.Id,
//VendorAddress_City = vendorAddress.City,
//VendorAddress_State = vendorAddress.State,
//VendorAddress_Zip = vendorAddress.Zip,
//VendorAddress_Phone = vendorAddress.Phone,
//VendorAddress_IsActive = vendorAddress.IsActive,
//VendorAddress = new
//{
// viewModelSave.VendorAddress.Id,
// viewModelSave.VendorAddress.Address1,
// viewModelSave.VendorAddress.City,
// viewModelSave.VendorAddress.State,
// viewModelSave.VendorAddress.Zip,
// viewModelSave.VendorAddress.Phone,
// viewModelSave.VendorAddress.IsActive,
// viewModelSave.VendorAddress.CreationTime
//},
//viewModelSave.Address1,
//viewModelSave.City,
//viewModelSave.State,
//viewModelSave.Zip,
//viewModelSave.Phone
}
);
var content = new StringContent(data, Encoding.UTF8, "application/x-www-form-urlencoded");
var message = new HttpRequestMessage {
Content = content,
Method = HttpMethod.Post,
RequestUri = new Uri("http://localHost" + url)
};
//Act
var response = await PostResponseAsObjectAsync<AjaxResponse>(url, content);
//Assert
var count = UsingDbContext(context => { return context.Municipalities.Count(x => x.IsActive); });
response.ShouldBeOfType<AjaxResponse>();
response.Result.ShouldNotBeNull();
count.ShouldBe(3);
}
As I attempt to debug what is happening. I've noticed that the VendorAddress properties that are sent via the test request do not match what the actual form post looks like when parsed in Chrome developer tools. In Chrome I see (example:
PointOfContact:"Tom Jerry"
IsActive:True
VendorAddress.Address1:"123 This Way"
VendorAddress.City: "Arlington")
I cannot get my test data into that same format, therefore its not binding correctly to my view models on post, and thus returns a 400 response and fails the test.
I have gotten it to work if I remove the Address View Model all together and put those properties as properties of the VendorViewModel. However, I would run into the same if not similar issue if I'm attempting to save a collection of objects along with the main view model.
I feel like there has to be a way to submit test form data via integration tests with boilerplate. I just need some missing piece to this puzzle.
The Solution that is working for both Post and Send Requests:
.NET Core has a QueryHelper class that will take a dictionary and a uri string and convert it into a url with querystring parameters. QueryHelpers.AddQueryString(string uri, IDictionary queryString) This is part of Microsoft.AspNetCore.WebUtilities.
Using this method I was able to properly prepare my formData. For a Post Request the Test would look like this
//Arrange
//Add Client Headers so User Auth and Permission Checkers work correctly
Client.DefaultRequestHeaders.Add("my-name", "admin");
Client.DefaultRequestHeaders.Add("my-id", "2");
//set up test data
var rawData = new Dictionary<string, string>(){{ "Id", "0"}, {"Name", "Controller Test Name"}, {"PointOfContact", "Tom Jerry"}
, {"Email", "Tom.Jerry#yolo.comy"}, {"CreationTime", $"{DateTime.Now}"}, {"LastModificationTime", ""}, {"IsActive", "true"}, {"AddressId", "0"}
, {"VendorAddress.Id", "0"}, {"VendorAddress.Address1", "123 This Way"}, {"VendorAddress.City", "Arlington"}, {"VendorAddress.State", "44"}, {"VendorAddress.Zip", "76001"}
, {"VendorAddress.Phone", "8175555555"}, {"VendorAddress.Fax", ""}, {"VendorAddress.IsActive", "true"}, {"VendorAddress.CreationTime", $"{DateTime.Now}"}, {"VendorAddress.LastModificationTime", ""}
};
var jsonData = JsonConvert.DeserializeObject(rawData);
//Serialize ViewModel to send with Post as part of the HttpContent object
var data = JsonConvert.SerializeObject(viewModelSave);
//actually get the url from helper method
var url = GetUrl<VendorController>(nameof(VendorController.SaveVendor));
var content = new StringContent(data, Encoding.UTF8, "application/x-www-form-urlencoded");
//Act
var response = await PostResponseAsObjectAsync<AjaxResponse>(url, content);
//Assert
var count = UsingDbContext(context => { return context.Municipalities.Count(x => x.IsActive); });
response.ShouldBeOfType<AjaxResponse>();
response.Result.ShouldNotBeNull();
count.ShouldBe(3);
Send Request Test would look like this
//Arrange
//Add Client Headers so User Auth and Permission Checkers work correctly
Client.DefaultRequestHeaders.Add("my-name", "admin");
Client.DefaultRequestHeaders.Add("my-id", "2");
//set up test data
var rawData = new Dictionary<string, string>(){{ "Id", "0"}, {"Name", "Controller Test Name"}, {"PointOfContact", "Tom Jerry"}
, {"Email", "Tom.Jerry#yolo.comy"}, {"CreationTime", $"{DateTime.Now}"}, {"LastModificationTime", ""}, {"IsActive", "true"}, {"AddressId", "0"}
, {"VendorAddress.Id", "0"}, {"VendorAddress.Address1", "123 This Way"}, {"VendorAddress.City", "Arlington"}, {"VendorAddress.State", "44"}, {"VendorAddress.Zip", "76001"}
, {"VendorAddress.Phone", "8175555555"}, {"VendorAddress.Fax", ""}, {"VendorAddress.IsActive", "true"}, {"VendorAddress.CreationTime", $"{DateTime.Now}"}, {"VendorAddress.LastModificationTime", ""}
};
var jsonData = JsonConvert.DeserializeObject(rawData);
//Serialize ViewModel to send with Post as part of the HttpContent object
var data = JsonConvert.SerializeObject(viewModelSave);
//actually get the url from helper method
var url = GetUrl<VendorController>(nameof(VendorController.SaveVendor));
var content = new StringContent(data, Encoding.UTF8, "application/x-www-form-urlencoded");
var message = new HttpRequestMessage {
Content = content,
Method = HttpMethod.Post,
RequestUri = new Uri("http://localHost" + url)
};
//Act
var response = await SendResponseAsObjectAsync<AjaxResponse>(message);
//Assert
var count = UsingDbContext(context => { return context.Municipalities.Count(x => x.IsActive); });
response.ShouldBeOfType<AjaxResponse>();
response.Result.ShouldNotBeNull();
count.ShouldBe(3);
I am trying to implement a payment gateway(INTUIT payment gateway). I would like to serialize an xml to an model class and save into my database. I am using Desktop Model for intuit payment gateway, as the hosted model is a pain to get working with especially ssl certificates, so i dont want to try that.
I must mention i am able to get the response using the below mentioned code, where i am stuck at the moment is serialize the xml and save the response into the database. This xml is pulled from a folder in my xmlfiles folder located in my project.
For sample xml format, check out this one. https://ipp.developer.intuit.com/0085_QuickBooks_Windows_SDK/qbms/0060_Documentation/Sending_Requests
this is an xml file i am trying to post to url (https://merchantaccount.ptc.quickbooks.com/j/AppGateway)
<?xml version="1.0"?>
<?qbmsxml version="4.5"?>
<QBMSXML>
<SignonMsgsRq>
<SignonDesktopRq>
<ClientDateTime>2012-07-25T17:13:45</ClientDateTime>
<ApplicationLogin>abc.abc.us</ApplicationLogin>
<ConnectionTicket>TGT-1-g42FGaMfOTQ82GcWFBpsuQ</ConnectionTicket>
</SignonDesktopRq>
</SignonMsgsRq>
<QBMSXMLMsgsRq>
<CustomerCreditCardChargeRq>
<TransRequestID>4540453787200</TransRequestID>
<CreditCardNumber>4111111111111111</CreditCardNumber>
<ExpirationMonth>12</ExpirationMonth>
<ExpirationYear>2016</ExpirationYear>
<IsCardPresent>false</IsCardPresent>
<Amount>10.00</Amount>
</CustomerCreditCardChargeRq>
</QBMSXMLMsgsRq>
</QBMSXML>
The Controller i use to make a post to the url
public ActionResult Index()
{
WebRequest req = null;
WebResponse rsp = null;
string fileName = Server.MapPath("~/XMLData/XMLFile1.xml");
string uri = "https://merchantaccount.ptc.quickbooks.com/j/AppGateway";
req = WebRequest.Create(uri);
//req.Proxy = WebProxy.GetDefaultProxy(); // Enable if using proxy
req.Method = "POST"; // Post method
req.ContentType = "application/x-qbmsxml"; // content type
// Wrap the request stream with a text-based writer
StreamWriter writer = new StreamWriter(req.GetRequestStream());
// Write the XML text into the stream
writer.WriteLine(this.GetTextFromXMLFile(fileName));
writer.Close();
// Send the data to the webserver
rsp = req.GetResponse();
// var resp = (Object)rsp.GetResponseStream();
if (rsp != null)
{
StreamReader inStream = new StreamReader(rsp.GetResponseStream());
var data = inStream.ReadToEnd();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(data);
string path = Server.MapPath("~/XMLData/SampleXmlE2E.xml");
xmlDoc.Save(path);//regenerates the xml file in different system.
}
return View();
//XElement root = new XElement("root");
//root.Add(new XElement("element1"));
//root.Add(new XElement("element2"));
//root.Add(new XAttribute("attribute1", "a value"));
//return new XmlResult(root);
}
private string GetTextFromXMLFile(string file)
{
StreamReader reader = new StreamReader(file);
string ret = reader.ReadToEnd();
reader.Close();
return ret;
}
private string SendRequest(Uri UriObj, string data)
{
string _result;
var request = (HttpWebRequest)WebRequest.Create(UriObj);
request.Method = "POST";
request.ContentType = "text/xml";
var writer = new StreamWriter(request.GetRequestStream());
writer.Write(data);
writer.Close();
var response = (HttpWebResponse)request.GetResponse();
var streamResponse = response.GetResponseStream();
var streamRead = new StreamReader(streamResponse);
_result = streamRead.ReadToEnd().Trim();
streamRead.Close();
streamResponse.Close();
response.Close();
return _result;
}
Any help would be appreciated. Thanks
Varun,
[Edit -update]
Based on this XML:
<?qbmsxml version="4.5"?>
<QBMSXML>
<SignonMsgsRq>
<SignonDesktopRq>
<ClientDateTime>2012-07-25T17:13:45</ClientDateTime>
<ApplicationLogin>app.app.login.url</ApplicationLogin>
<ConnectionTicket>TGT-1-g42FGaMfOTQ82GcWFBpsuQ</ConnectionTicket>
</SignonDesktopRq>
</SignonMsgsRq>
<QBMSXMLMsgsRq>
<CustomerCreditCardChargeRq>
<TransRequestID>4540453787200</TransRequestID>
<CreditCardNumber>4111111111111111</CreditCardNumber>
<ExpirationMonth>12</ExpirationMonth>
<ExpirationYear>2016</ExpirationYear>
<IsCardPresent>false</IsCardPresent>
<Amount>10.00</Amount>
</CustomerCreditCardChargeRq>
</QBMSXMLMsgsRq>
</QBMSXML>
Here's the class structure that you'd need to deserialize into as per the example above:
[XmlRoot("QBMSXML")]
public class QbmsXml
{
[XmlElement("SignonMsgsRq")]
public SignonMsgsRq SignonMsgsRq { get; set; }
[XmlElement("QBMSXMLMsgsRq")]
public QbmsXmlMsgsRq QbmsXmlMsgsRq { get; set; }
}
public class SignonMsgsRq
{
[XmlElement("SignonDesktopRq")]
public SignonDesktopRq SignonDesktopRq { get; set; }
}
public class SignonDesktopRq
{
[XmlElement("ClientDateTime")]
public DateTime ClientDateTime { get; set; }
[XmlElement("ApplicationLogin")]
public string ApplicationLogin { get; set; }
[XmlElement("ConnectionTicket")]
public string ConnectionTicket { get; set; }
}
public class QbmsXmlMsgsRq
{
[XmlElement("CustomerCreditCardChargeRq")]
public CustomerCreditCardChargeRq CustomerCreditCardChargeRq { get; set; }
}
public class CustomerCreditCardChargeRq
{
[XmlElement("TransRequestID")]
public Int64 TransRequestID { get; set; }
[XmlElement("CreditCardNumber")]
public string CreditCardNumber { get; set; }
[XmlElement("ExpirationMonth")]
public int ExpirationMonth { get; set; }
[XmlElement("ExpirationYear")]
public int ExpirationYear { get; set; }
[XmlElement("IsCardPresent")]
public bool IsCardPresent { get; set; }
[XmlElement("Amount")]
public double Amount { get; set; }
}
Just use the xmlSerialiser along the lines of:
class Program
{
private static T DeSerialize<T>(string fromXmlFile) where T: class
{
if (!File.Exists(fromXmlFile))
{
return default(T);
}
T deserializedClass;
var serializer = new XmlSerializer(typeof(T));
// ToDo: add error catching etc
using (var reader = new StreamReader(fromXmlFile))
{
deserializedClass = (T)serializer.Deserialize(reader);
}
return deserializedClass;
}
static void Main(string[] args)
{
var yourXmlFilePath = #"d:\temp\xmltest.xml";
var deserializedClass = DeSerialize<QbmsXml>(yourXmlFilePath);
Console.WriteLine(deserializedClass
.QbmsXmlMsgsRq
.CustomerCreditCardChargeRq.Amount);
Console.Read();
}
}
hope this helps.