Simple C# check? - c#

I am new to c# and making simple contact form, for now i got this in view
#{
var customerName = Request["customerName"];
var customerEmail = Request["customerEmail"];
var customerRequest = Request["customerRequest"];
var errorMessage = "";
var debuggingFlag = false;
try {
// Initialize WebMail helper
WebMail.SmtpServer = "your-SMTP-host";
WebMail.SmtpPort = 25;
WebMail.UserName = "your-user-name-here";
WebMail.Password = "your-account-password";
WebMail.From = "your-email-address-here";
// Send email
WebMail.Send(to: customerEmail,
subject: "Help request from - " + customerName,
body: customerRequest
);
}
catch (Exception ex ) {
errorMessage = ex.Message;
}
}
It is ok for now, but how to check in POST varibales exist i know in PHP
if (isset($_POST["customerName"]) && !empty($_POST["customerName"])) {
}
very easy, but how to do that in C#

Check it against null like:
if(Request["customerName"] != null)
{
//Post key exists
}

Related

ModelState.AddModelError is setup to display Canned message instead of real Error

In my website i had a group of people working on my site and i have this code that they put a canned message in for an error. When i debug the code it is actually a different error but displays this canned message. For instance when i put the information in the form i used an email address that already exists in the database but it is showing a message to check the password requirements. How can this be fixed to show the actual error. To me it also seems like there is a lot code going on in this that may not need to be or can be achieved cleaner Your thoughts?
Code of Post Action:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreateCompanyUser(ExpandedUserDTO ExpandedUserDTO)
{
try
{
if (ExpandedUserDTO == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var Email = ExpandedUserDTO.Email.Trim();
var UserName = ExpandedUserDTO.UserName.Trim();
var Password = ExpandedUserDTO.Password.Trim();
if (UserName == "")
{
throw new Exception("No Username");
}
if (Password == "")
{
throw new Exception("No Password");
}
// UserName is LowerCase of the Email
// UserName = Email.ToLower();
// Create user
var objNewAdminUser = new Models.ApplicationUser { UserName = UserName, Email = Email };
var AdminUserCreateResult = UserManager.Create(objNewAdminUser, Password);
if (AdminUserCreateResult.Succeeded == true)
{
string strNewRole = Convert.ToString(Request.Form["Roles"]);
if (strNewRole != "0")
{
// Put user in role
UserManager.AddToRole(objNewAdminUser.Id, strNewRole);
}
var viewModel = new Users();
{
viewModel.UsersId = Convert.ToString(Guid.NewGuid());
viewModel.Email = Email;
viewModel.FirstName = UserName;
viewModel.AspNetUsersId = objNewAdminUser.Id;
viewModel.CreatedDate = System.DateTime.Now;
viewModel.UpdatedDate = System.DateTime.Now;
};
UsersBusinessModels Login = new UsersBusinessModels();
var results = Login.insertUserWithougAsny(viewModel);
string[] roleRemove = new string[2] { "Administrator", "CompanyAdmin" };
ViewBag.Roles = GetAllRolesAsSelectList().Where(k => !roleRemove.Contains(k.Text)).ToList();
// return RedirectToAction();
Response.Redirect("/Customer/ManageUsers/" + User.Identity.GetUserId());
return PartialView();
}
else
{
ViewBag.Roles = GetAllRolesAsSelectList();
ModelState.AddModelError(string.Empty,
"Error: Failed to create the user. Check password requirements.");
return PartialView(ExpandedUserDTO);
}
}
catch (Exception ex)
{
ViewBag.Roles = GetAllRolesAsSelectList();
ModelState.AddModelError(string.Empty, "Error: " + ex);
string[] roleRemove = new string[2] { "Administrator", "CompanyAdmin" };
ViewBag.Roles = GetAllRolesAsSelectList().Where(k => !roleRemove.Contains(k.Text)).ToList();
return PartialView(ExpandedUserDTO);
}
}

C# Authorize.net Create Profile Issue

The following code is charging the card, however it is not creating the profile....any tips? I'm assuming I'm missing something, or using the wrong Type...
var opaqueData = new opaqueDataType { dataDescriptor = "COMMON.ACCEPT.INAPP.PAYMENT", dataValue = paymentNonce };
//standard api call to retrieve response
var paymentType = new paymentType { Item = opaqueData };
var transactionRequest = new transactionRequestType
{
transactionType = transactionTypeEnum.authCaptureTransaction.ToString(), // authorize and capture transaction
amount = paymentAmount,
payment = paymentType,
customer = new customerDataType()
{
type = customerTypeEnum.individual,
id = userID.ToString()
},
profile = new customerProfilePaymentType()
{
createProfile = true
}
};
var request = new createTransactionRequest { transactionRequest = transactionRequest };
// instantiate the contoller that will call the service
var controller = new createTransactionController(request);
const SslProtocols _Tls12 = (SslProtocols)0x00000C00;
const SecurityProtocolType Tls12 = (SecurityProtocolType)_Tls12;
ServicePointManager.SecurityProtocol = Tls12;
controller.Execute();
// get the response from the service (errors contained if any)
var response = controller.GetApiResponse();
UPDATE:
Since apparently OpaqueData is not allowed, I changed it to make the profile manually. I am getting the following Error: "Error: I00001 Successful."
// Add Payment method to Customer.
customerPaymentProfileType opaquePaymentProfile = new customerPaymentProfileType();
opaquePaymentProfile.payment = paymentType;
opaquePaymentProfile.customerType = customerTypeEnum.individual;
var request2 = new createCustomerPaymentProfileRequest
{
paymentProfile = opaquePaymentProfile,
validationMode = validationModeEnum.none,
customerProfileId = userID.ToString()
};
var controller2 = new createCustomerPaymentProfileController(request2);
controller2.Execute();
//Send Request to EndPoint
createCustomerPaymentProfileResponse response2 = controller2.GetApiResponse();
if (response2 != null && response2.messages.resultCode == messageTypeEnum.Ok)
{
if (response2 != null && response2.messages.message != null)
{
//Console.WriteLine("Success, createCustomerPaymentProfileID : " + response.customerPaymentProfileId);
}
}
else
{
Utility.AppendTextToFile("Error: " + response.messages.message[0].code + " " + response.messages.message[0].text, Server.MapPath("/pub/auth.txt"));
}
Update #2
Very confused as auth.net documentation says this code means success...so why don't I see the CIM payment method created??? RESPONSE CODE DOCS
Update #3
So I was printing out the main response message instead of the CIM request message, duh. The actual error was: "E00114 Invalid OTS Token."
Based on the the documentation, that error is usually from a used Key, so I am now generating 2 keys (One to process and One to store via CIM) but am now getting this error: "E00040 The record cannot be found."....Any ideas?
So the answer to this question is:
You can not auto create a payment profile using opaque card data, so the answer is to make it manually once you have a successful charge.
You can not use the same opaque card data to charge and store, as they are one time use, so for my web method I ended up passing 2 opaque data keys.
You have to make different calls for setting up a brand new customer and an existing customer just adding a new card. I have pasted an excerpt of my end solution below:
ApiOperationBase<ANetApiRequest, ANetApiResponse>.RunEnvironment = (System.Configuration.ConfigurationManager.AppSettings["Authorize-Live"].ToUpper() == "TRUE" ? AuthorizeNet.Environment.PRODUCTION : AuthorizeNet.Environment.SANDBOX);
// define the merchant information (authentication / transaction id)
ApiOperationBase<ANetApiRequest, ANetApiResponse>.MerchantAuthentication = new merchantAuthenticationType()
{
name = (System.Configuration.ConfigurationManager.AppSettings["Authorize-Live"].ToUpper() == "TRUE" ? System.Configuration.ConfigurationManager.AppSettings["Authorize-LoginID"] : System.Configuration.ConfigurationManager.AppSettings["Authorize-LoginID-SandBox"]),
ItemElementName = ItemChoiceType.transactionKey,
Item = (System.Configuration.ConfigurationManager.AppSettings["Authorize-Live"].ToUpper() == "TRUE" ? System.Configuration.ConfigurationManager.AppSettings["Authorize-TransactionKey"] : System.Configuration.ConfigurationManager.AppSettings["Authorize-TransactionKey-SandBox"])
};
if (paymentNonce.Trim() != "")
{
//set up data based on transaction
var opaqueData = new opaqueDataType { dataDescriptor = "COMMON.ACCEPT.INAPP.PAYMENT", dataValue = paymentNonce };
//standard api call to retrieve response
var paymentType = new paymentType { Item = opaqueData };
var transactionRequest = new transactionRequestType
{
transactionType = transactionTypeEnum.authCaptureTransaction.ToString(), // authorize and capture transaction
amount = paymentAmount,
payment = paymentType,
customer = new customerDataType()
{
type = customerTypeEnum.individual,
id = "YOUR_DB_USERID"
},
profile = new customerProfilePaymentType()
{
createProfile = false
}
};
var request = new createTransactionRequest { transactionRequest = transactionRequest };
// instantiate the contoller that will call the service
var controller = new createTransactionController(request);
const SslProtocols _Tls12 = (SslProtocols)0x00000C00;
const SecurityProtocolType Tls12 = (SecurityProtocolType)_Tls12;
ServicePointManager.SecurityProtocol = Tls12;
controller.Execute();
// get the response from the service (errors contained if any)
var response = controller.GetApiResponse();
//validate
if (response != null)
{
if (response.messages.resultCode == messageTypeEnum.Ok)
{
if (response.transactionResponse.messages != null)
{
responseData.Success = true;
transactionID = response.transactionResponse.transId;
string merchID = "STORED AUTHORIZE.NET CUSTOMERID, return blank string if none!";
var opaqueData2 = new opaqueDataType { dataDescriptor = "COMMON.ACCEPT.INAPP.PAYMENT", dataValue = paymentNonce2 };
//standard api call to retrieve response
var paymentType2 = new paymentType { Item = opaqueData2 };
customerPaymentProfileType opaquePaymentProfile = new customerPaymentProfileType();
opaquePaymentProfile.payment = paymentType2;
opaquePaymentProfile.customerType = customerTypeEnum.individual;
if (merchID == "")
{
// CREATE NEW AUTH.NET AIM CUSTOMER
List<customerPaymentProfileType> paymentProfileList = new List<customerPaymentProfileType>();
paymentProfileList.Add(opaquePaymentProfile);
customerProfileType customerProfile = new customerProfileType();
customerProfile.merchantCustomerId = "YOUR_DB_USERID";
customerProfile.paymentProfiles = paymentProfileList.ToArray();
var cimRequest = new createCustomerProfileRequest { profile = customerProfile, validationMode = validationModeEnum.none };
var cimController = new createCustomerProfileController(cimRequest); // instantiate the contoller that will call the service
cimController.Execute();
createCustomerProfileResponse cimResponse = cimController.GetApiResponse();
if (cimResponse != null && cimResponse.messages.resultCode == messageTypeEnum.Ok)
{
if (cimResponse != null && cimResponse.messages.message != null)
{
// STORE cimResponse.customerProfileId IN DATABASE FOR USER
}
}
else
{
for (int i = 0; i < cimResponse.messages.message.Length; i++)
Utility.AppendTextToFile("New Error (" + merchID + ") #" + i.ToString() + ": " + cimResponse.messages.message[i].code + " " + cimResponse.messages.message[i].text, Server.MapPath("/pub/auth.txt"));
}
}
else
{
// ADD PAYMENT PROFILE TO EXISTING AUTH.NET AIM CUSTOMER
var cimRequest = new createCustomerPaymentProfileRequest
{
paymentProfile = opaquePaymentProfile,
validationMode = validationModeEnum.none,
customerProfileId = merchID.Trim()
};
var cimController = new createCustomerPaymentProfileController(cimRequest);
cimController.Execute();
//Send Request to EndPoint
createCustomerPaymentProfileResponse cimResponse = cimController.GetApiResponse();
if (cimResponse != null && cimResponse.messages.resultCode == messageTypeEnum.Ok)
{
if (cimResponse != null && cimResponse.messages.message != null)
{
//Console.WriteLine("Success, createCustomerPaymentProfileID : " + response.customerPaymentProfileId);
}
}
else
{
for (int i = 0; i < cimResponse.messages.message.Length; i++)
Utility.AppendTextToFile("Add Error (" + merchID + ") #" + i.ToString() + ": " + cimResponse.messages.message[i].code + " " + cimResponse.messages.message[i].text, Server.MapPath("/pub/auth.txt"));
}
}
}
else
{
responseData.Message = "Card Declined";
responseData.Success = false;
if (response.transactionResponse.errors != null)
{
responseData.Message = response.transactionResponse.errors[0].errorText;
}
}
}
else
{
responseData.Message = "Failed Transaction";
responseData.Success = false;
if (response.transactionResponse != null && response.transactionResponse.errors != null)
{
responseData.Message = response.transactionResponse.errors[0].errorText;
}
else
{
responseData.Message = response.messages.message[0].text;
}
}
}
else
{
responseData.Message = "Failed Transaction, Try Again!";
responseData.Success = false;
}
}
else
{
// RUN PAYMENT WITH STORED PAYMENT PROFILE ID
customerProfilePaymentType profileToCharge = new customerProfilePaymentType();
profileToCharge.customerProfileId = CustomerID;
profileToCharge.paymentProfile = new paymentProfile { paymentProfileId = PaymentID };
var transactionRequest = new transactionRequestType
{
transactionType = transactionTypeEnum.authCaptureTransaction.ToString(),
amount = paymentAmount,
profile = profileToCharge
};
var request = new createTransactionRequest { transactionRequest = transactionRequest };
// instantiate the collector that will call the service
var controller = new createTransactionController(request);
controller.Execute();
// get the response from the service (errors contained if any)
var response = controller.GetApiResponse();
//validate
if (response != null)
{
if (response.messages.resultCode == messageTypeEnum.Ok)
{
if (response.transactionResponse.messages != null)
{
responseData.Success = true;
transactionID = response.transactionResponse.transId;
}
else
{
responseData.Message = "Card Declined";
responseData.Success = false;
if (response.transactionResponse.errors != null)
{
responseData.Message = response.transactionResponse.errors[0].errorText;
}
}
}
else
{
responseData.Message = "Failed Transaction";
responseData.Success = false;
if (response.transactionResponse != null && response.transactionResponse.errors != null)
{
responseData.Message = response.transactionResponse.errors[0].errorText;
}
else
{
responseData.Message = response.messages.message[0].text;
}
}
}
else
{
responseData.Message = "Failed Transaction, Try Again!";
responseData.Success = false;
}
}

"CSRF Validation failed" when invoking SaveChanges ODataClient method in ASP.NET

I am trying to implement a code to modify entities through WCF Dataservices from the OData client I have generated. I have followed the same principle that was implemented in this link - https://msdn.microsoft.com/en-us/library/dd756368(v=vs.110).aspx
I am getting "CSRF token validation failed" error during the SaveChanges method call. Please see code below:
// Define the URI of the public Northwind OData service.
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
Uri cuanUri =
new Uri("https://xxxx.xxxx.com:44300/sap/opu/odata/sap/CUAN_IMPORT_SRV/",
UriKind.Absolute);
// Create a new instance of the typed DataServiceContext.
DateTime stimestamp = new DateTime();
DateTime dob = new DateTime(1992,05,02);
CUAN_IMPORT_SRV_Entities context = new CUAN_IMPORT_SRV_Entities(cuanUri);
context.SendingRequest2 += SendBaseAuthCredsOnTheRequest;
Contact newContact = Contact.CreateContact("C160717055735", "SAP_ODATA_IMPORT", stimestamp);
//Product newProduct = Product.CreateProduct(0, "White Tea - loose", false);
newContact.CompanyId = "BLUEFIN1";
newContact.CompanyIdOrigin = "SAP_ODATA_IMPORT";
newContact.CountryDescription = "Singapore";
newContact.DateOfBirth = dob;
newContact.EMailAddress = "j_prado#yahoo.com";
newContact.EMailOptIn = "Y";
newContact.FirstName = "Jeffrey1";
newContact.FunctionDescription = "Consultant";
newContact.GenderDescription = "Male";
newContact.LastName = "Prado1";
newContact.PhoneNumber = "+6596492714";
newContact.PhoneOptin = "Y";
Company newCompany = Company.CreateCompany("BLUEFIN1", "SAP_ODATA_IMPORT", stimestamp);
newCompany.IndustryDescription = "1007";
newCompany.CompanyName = "BLUEFIN1";
Interaction newInteraction = Interaction.CreateInteraction("");
newInteraction.CommunicationMedium = "WEB";
newInteraction.ContactId = "C160717055735";
newInteraction.ContactIdOrigin = "SAP_ODATA_IMPORT";
newInteraction.InteractionType = "WEBSITE_REGISTRATION";
newInteraction.Timestamp = stimestamp;
ImportHeader newHeader = ImportHeader.CreateImportHeader("");
newHeader.Timestamp = stimestamp;
newHeader.UserName = "ENG";
newHeader.SourceSystemType = "EXT";
newHeader.SourceSystemId = "HYBRIS";
try
{
// Add the new entities to the CUAN entity sets.
context.AddToImportHeaders(newHeader);
context.AddToContacts(newContact);
context.AddToCompanies(newCompany);
context.AddToInteractions(newInteraction);
// Send the insert to the data service.
DataServiceResponse response = context.SaveChanges();
// Enumerate the returned responses.
foreach (ChangeOperationResponse change in response)
{
// Get the descriptor for the entity.
EntityDescriptor descriptor = change.Descriptor as EntityDescriptor;
if (descriptor != null)
{
Contact addedContact = descriptor.Entity as Contact;
if (addedContact != null)
{
Console.WriteLine("New contact added with ID {0}.",
addedContact.CompanyId);
}
}
}
}
catch (DataServiceRequestException ex)
{
throw new ApplicationException(
"An error occurred when saving changes.", ex);
}
}
private static void SendBaseAuthCredsOnTheRequest(object sender,
SendingRequest2EventArgs e)
{
var authHeaderValue = Convert.ToBase64String(Encoding.ASCII.GetBytes(String.Format("{0}:{1}"
, "XXXXX", "XXXXX")));
e.RequestMessage.SetHeader("Authorization", "Basic " + authHeaderValue); //this is where you pass the creds.
}
The code above fails when invoking: DataServiceResponse response = context.SaveChanges();

Controller is returning blank View in my website

public async Task<IActionResult> Contact1()
{
if (Convert.ToBoolean(HttpContext.Session.GetString("login")))
{
var pass = new ContactViewModel();
var username = HttpContext.Session.GetString("username");
Program.readname(HttpContext.Session.GetString("username"));
var names = HttpContext.Session.GetString("studentnames");
var obj1 = JsonConvert.DeserializeObject<Program.Data>(names);
if (Program.datecheck(username, DateTime.Today.Date))
{
try{
var handler = new HttpClientHandler { Credentials = new NetworkCredential(user, password) };
using (var client = Program.CreateHttpClient(handler, user, database3))
{
string check = username + Convert.ToString(DateTime.Today.Date);
var readresponse = client.GetStringAsync(check).Result;
var obj2 = JsonConvert.DeserializeObject<Program.Data>(readresponse);
}
catch(Exception ee)
{ ViewBag.m6 = ee.Message; ViewBag.attendance = "Attendace is not take yet";}
}
pass.studentattend = obj2.studentattend1;
}
}
else { ViewBag.attendance = "Attendace is not take yet"; }
pass.studentname = obj1.studentname1;
pass.studentrollno = obj1.studentrollno1;
pass.date = DateTime.Today.Date;
HttpContext.Session.SetInt32("classselect", 1);
ViewData["Message"] = "Student Attendance of Class: " + HttpContext.Session.GetString("classname1");
ViewBag.Login = HttpContext.Session.GetString("login");
ViewBag.name = HttpContext.Session.GetString("name");
ViewBag.classname1 = HttpContext.Session.GetString("classname1");
ViewBag.classname2 = HttpContext.Session.GetString("classname2");
ViewBag.classname3 = HttpContext.Session.GetString("classname3");
ViewBag.classname4 = HttpContext.Session.GetString("classname4");
return View("/Views/Home/Contact.cshtml", pass);
}
else
{
ViewData["Message"] = "Please Login First!!";
return View("/Views/Home/Login.cshtml");
}
}
The above code is runnig well in my local ISS server but when i run this on bluemix then i am getting blank page. I tried to find out the problem and get to the conclusion that if the control does not enter in the if part of that code:
if (Program.datecheck(username, DateTime.Today.Date))
{
var handler = new HttpClientHandler { Credentials = new NetworkCredential(user, password) };
using (var client = Program.CreateHttpClient(handler, user, database3))
{
string check = username + Convert.ToString(DateTime.Today.Date);
var readresponse = client.GetStringAsync(check).Result;
var obj2 = JsonConvert.DeserializeObject<Program.Data>(readresponse);
pass.studentattend = obj2.studentattend1;
}
}
else { ViewBag.attendance = "Attendace is not take yet"; }
then it will run fine.I am unable to find what is wrong in that query.

Royal Mail Shipping API C#

I'm trying to integrate the Royal Mail SOAP API into my .NET Code. I have followed the advice here Consume WCF Royal Mail API in c# Console Application and here C# WCF Namespaces Move To Header & Use NS Prefix.
I have created a custom IClientMessageFormatter to be able to attach the namespaces to the beginning of the soap envelope, but I still can't seem to get this to work. I keep receiving the following error. Could not establish trust relationship for the SSL/TLS secure channel with authority 'api.royalmail.com', and the inner exception is: The remote certificate is invalid according to the validation procedure.
I am using Visual Studio 13 and .Net version 3.5, I've tried numerous other versions but with no further progress. When I debug I can see that the normal message been passed into the RoyalMailMessage but when it runs OnWriteStartEnvelope I can't see any changes to the _message object. I've created a trace to see what soap request is been sent.
I have sent my XML request to Royal Mail support who validate that the reason it is failing is due to the namespaces not been declared in the envelope and the missing prefixes.
RoyalMail.cs
internal class RoyalMail
{
private readonly X509Certificate2 _certificate;
private readonly Config _config;
public RoyalMail()
{
_config = new Config();
_config.LoadConfig();
// Load The SSL Certificate (Check The File Exists)
var certificatePath = (Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + #"\" + _config.GetCertificateName());
if (!File.Exists(certificatePath))
{
throw new Exception(#"The Royal Mail Certificate Is Missing From The Plugins Directory. Please Place The File " + _config.GetCertificateName() + " In The Same Directory As The Plugin DLL File & Relaunch FileMaker.\n\n" + certificatePath);
}
_certificate = new X509Certificate2(certificatePath, _config.GetCertificatePassword());
// Check It's In The Certificate
var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadWrite);
if (!store.Certificates.Contains(_certificate))
{
store.Add(_certificate);
MessageBox.Show("Certificate Was Installed Into Computer Trust Store");
}
store.Close();
}
/*
*
* SOAP Service & Methods
*
*/
private shippingAPIPortTypeClient GetProxy()
{
var myBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport)
{
MaxReceivedMessageSize = 2147483647
};
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
var uri = new Uri(_config.GetEndpointUrl());
var endpointIdentity = EndpointIdentity.CreateDnsIdentity("api.royalmail.com");
var shippingClient = new shippingAPIPortTypeClient(myBinding, new EndpointAddress(uri, endpointIdentity, new AddressHeaderCollection()));
if (shippingClient.ClientCredentials != null)
shippingClient.ClientCredentials.ClientCertificate.Certificate = _certificate;
foreach (var od in shippingClient.Endpoint.Contract.Operations)
{
od.Behaviors.Add(new RoyalMailIEndpointBehavior());
}
return shippingClient;
}
private SecurityHeaderType GetSecurityHeaderType()
{
var securityHeader = new SecurityHeaderType();
var creationDate = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ");
var nonce = (new Random().Next(0, int.MaxValue)).ToString();
var hashedPassword = GetSha1(_config.GetPassword());
var concatednatedDigestInput = string.Concat(nonce, creationDate, Encoding.Default.GetString(hashedPassword));
var digest = GetSha1(concatednatedDigestInput);
var passwordDigest = Convert.ToBase64String(digest);
var encodedNonce = Convert.ToBase64String(Encoding.Default.GetBytes(nonce));
var doc = new XmlDocument();
using (var writer = doc.CreateNavigator().AppendChild())
{
writer.WriteStartDocument();
writer.WriteStartElement("wsse", "Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
writer.WriteStartElement("wsse", "UsernameToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
writer.WriteElementString("wsse", "Username", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", _config.GetUsername());
writer.WriteElementString("wsse", "Password", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", passwordDigest);
writer.WriteElementString("wsse", "Nonce", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", encodedNonce);
writer.WriteElementString("wsse", "Created", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", creationDate);
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Flush();
}
if (doc.DocumentElement != null)
{
doc.DocumentElement.RemoveAllAttributes();
var headers = doc.DocumentElement.ChildNodes.Cast<XmlElement>().ToArray();
securityHeader.Any = headers;
}
return securityHeader;
}
private integrationHeader GetIntegrationHeader()
{
var header = new integrationHeader();
var created = DateTime.Now;
var createdAt = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ");
header.dateTime = created;
header.version = int.Parse(_config.GetVersion());
header.dateTimeSpecified = true;
header.versionSpecified = true;
var idStructure = new identificationStructure {applicationId = _config.GetApplicationId()};
var nonce = new Random().Next(0, int.MaxValue).ToString();
idStructure.transactionId = CalculateMd5Hash(nonce + createdAt);
header.identification = idStructure;
return header;
}
private static byte[] GetSha1(string input)
{
return SHA1Managed.Create().ComputeHash(Encoding.Default.GetBytes(input));
}
public string CalculateMd5Hash(string input)
{
// step 1, calculate MD5 hash from input
var md5 = MD5.Create();
var inputBytes = Encoding.ASCII.GetBytes(input);
var hash = md5.ComputeHash(inputBytes);
// step 2, convert byte array to hex string
var sb = new StringBuilder();
foreach (var t in hash)
{
sb.Append(t.ToString("X2"));
}
return sb.ToString();
}
/*
* Check Response Footer For Errors & Warnings From Service
* If Error Return True So We Can Inform File maker Of Error
* Ignore Warnings For Now
*
*/
private static void CheckErrorsAndWarnings(integrationFooter integrationFooter)
{
if (integrationFooter != null)
{
if (integrationFooter.errors != null && integrationFooter.errors.Length > 0)
{
var errors = integrationFooter.errors;
foreach (var error in errors)
{
MessageBox.Show("Royal Mail Request Error: " + error.errorDescription + ". " + error.errorResolution, "Royal Mail Request Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
}
if (errors.Length > 0)
{
return;
}
}
if (integrationFooter.warnings != null && integrationFooter.warnings.Length > 0)
{
var warnings = integrationFooter.warnings;
foreach (var warning in warnings)
{
MessageBox.Show("Royal Mail Request Warning: " + warning.warningDescription + ". " + warning.warningResolution, "Royal Mail Request Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
}
}
}
}
/*
* Show Message Box With SOAP Error If We Receive A Fault Code Back From Service
*
*/
private static void ShowSoapException(FaultException e)
{
var message = e.CreateMessageFault();
var errorDetail = message.GetDetail<XmlElement>();
var errorDetails = errorDetail.ChildNodes;
var fullErrorDetails = "";
for (var i = 0; i < errorDetails.Count; i++)
{
var xmlNode = errorDetails.Item(i);
if (xmlNode != null)
fullErrorDetails += xmlNode.Name + ": " + xmlNode.InnerText + "\n";
}
MessageBox.Show("An Error Occured With Royal Mail Service: " + message.Reason + "\n\n" + fullErrorDetails, "Royal Mail SOAP Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
}
public createShipmentResponse SendCreateShipmentRequest(CreateShipmentForm shippingForm)
{
var client = GetProxy();
try
{
var request = new createShipmentRequest {integrationHeader = GetIntegrationHeader()};
var shipment = new requestedShipment();
// Shipment Type Code (Delivery or Return)
var shipmentType = new referenceDataType {code = shippingForm.ShippingType};
shipment.shipmentType = shipmentType;
// Service Type Code (1:24H 1st Class, 2: 48H 2nd Class, D: Special Delivery Guaranteed, H: HM Forces (BFPO), I: International, R: Tracked Returns, T: Tracked Domestic)
var serviceType = new referenceDataType {code = shippingForm.ServiceType};
shipment.serviceType = serviceType;
// Service Offering (See Royal Mail Service Offering Type Codes. Too Many To List)
var serviceOfferingTypeContainer = new serviceOfferingType();
var serviceOffering = new referenceDataType {code = shippingForm.ServiceOffering};
serviceOfferingTypeContainer.serviceOfferingCode = serviceOffering;
shipment.serviceOffering = serviceOfferingTypeContainer;
// Service Format Code
var serviceFormatTypeContainer = new serviceFormatType();
var serviceFormat = new referenceDataType {code = shippingForm.ServiceFormat};
serviceFormatTypeContainer.serviceFormatCode = serviceFormat;
shipment.serviceFormat = serviceFormatTypeContainer;
// Shipping Date
shipment.shippingDate = shippingForm.ShippingDate;
shipment.shippingDateSpecified = true;
shipment.signature = true;
shipment.signatureSpecified = true;
// Sender Reference Number (e.g. Invoice Number or RA Number)
shipment.senderReference = shippingForm.InvoiceNumber;
/*
* Service Enhancements
*/
var serviceEnhancements = new List<serviceEnhancementType>();
shipment.serviceEnhancements = serviceEnhancements.ToArray();
/*
* Recipient Contact Details
*/
var recipientContact = new contact();
recipientContact.complementaryName = shippingForm.Company;
recipientContact.name = shippingForm.Name;
if(!shippingForm.EmailAddress.Equals("")) {
var email = new digitalAddress {electronicAddress = shippingForm.EmailAddress};
recipientContact.electronicAddress = email;
}
if(!shippingForm.MobileNumber.Equals("")) {
var tel = new telephoneNumber();
var phoneRegex = new Regex(#"[^\d]");
tel.telephoneNumber1 = phoneRegex.Replace(shippingForm.MobileNumber, "");
tel.countryCode = "00" + shippingForm.CountryDiallingCode;
recipientContact.telephoneNumber = tel;
}
shipment.recipientContact = recipientContact;
/*
* Recipient Address
*
*/
var recipientAddress = new address
{
addressLine1 = shippingForm.AddressLine1,
addressLine2 = shippingForm.AddressLine2,
addressLine3 = shippingForm.AddressLine3,
addressLine4 = shippingForm.County,
postTown = shippingForm.Town
};
var country = new countryType();
var countryCode = new referenceDataType { code = shippingForm.CountryCode };
country.countryCode = countryCode;
recipientAddress.country = country;
recipientAddress.postcode = shippingForm.PostCode;
recipientAddress.stateOrProvince = new stateOrProvinceType {stateOrProvinceCode = new referenceDataType()};
shipment.recipientAddress = recipientAddress;
// Shipment Items
var items = new List<item> ();
foreach(var i in shippingForm.Items) {
var item = new item
{
numberOfItems = i.Products.Count.ToString(),
weight = new dimension
{
value = i.Weight*1000,
unitOfMeasure = new unitOfMeasureType {unitOfMeasureCode = new referenceDataType {code = "g"}}
}
};
items.Add(item);
}
if (shippingForm.ServiceType.Contains("international"))
{
var internationalInfo = new internationalInfo
{
shipperExporterVatNo = _config.GetVatNumber(),
documentsOnly = false,
shipmentDescription = "Invoice Number: " + shippingForm.InvoiceNumber,
invoiceDate = DateTime.Now,
termsOfDelivery = "EXW",
invoiceDateSpecified = true,
purchaseOrderRef = shippingForm.InvoiceNumber
};
var parcels = new List<parcel>();
foreach (var i in shippingForm.Items)
{
var parcel = new parcel
{
weight = new dimension
{
value = i.Weight*1000,
unitOfMeasure = new unitOfMeasureType
{
unitOfMeasureCode = new referenceDataType {code = "g"}
}
},
invoiceNumber = shippingForm.InvoiceNumber,
purposeOfShipment = new referenceDataType {code = "31"}
};
var contents = new List<contentDetail>();
foreach (var product in i.Products)
{
var contentDetail = new contentDetail
{
articleReference = product.Sku,
countryOfManufacture = new countryType
{
countryCode = new referenceDataType
{
code = product.CountryOfManufacture
}
},
currencyCode = new referenceDataType {code = product.CurrencyCode},
description = product.Name,
unitQuantity = product.Qty.ToString(),
unitValue = product.Price,
unitWeight = new dimension
{
value = Convert.ToSingle(product.Weight*1000),
unitOfMeasure = new unitOfMeasureType
{
unitOfMeasureCode = new referenceDataType {code = "g"}
}
}
};
contents.Add(contentDetail);
}
//Parcel.contentDetails = Contents.ToArray();
parcels.Add(parcel);
}
internationalInfo.parcels = parcels.ToArray();
shipment.internationalInfo = internationalInfo;
}
else
{
shipment.items = items.ToArray();
}
request.requestedShipment = shipment;
var response = client.createShipment(GetSecurityHeaderType(), request);
// Show Errors And Warnings
CheckErrorsAndWarnings(response.integrationFooter);
return response;
}
catch (TimeoutException e)
{
client.Abort();
MessageBox.Show("Request Timed Out: " + e.Message, "Request Timeout", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
}
catch (FaultException e)
{
client.Abort();
ShowSoapException(e);
}
catch (CommunicationException e)
{
client.Abort();
MessageBox.Show("A communication error has occurred: " + e.Message + " - " + e.StackTrace, "Communication Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
}
catch (Exception e)
{
client.Abort();
MessageBox.Show(e.Message, "Royal Mail Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
}
return null;
}
}
RoyalmailMessage.cs
class RoyalMailMessage : Message
{
public Message _message;
public RoyalMailMessage(Message message)
{
_message = message;
}
public override MessageHeaders Headers
{
get
{
return _message.Headers;
}
}
public override MessageProperties Properties
{
get
{
return _message.Properties;
}
}
public override MessageVersion Version
{
get
{
return _message.Version;
}
}
protected override void OnWriteStartBody(XmlDictionaryWriter writer)
{
writer.WriteStartElement("Body", "http://schemas.xmlsoap.org/soap/envelope/");
}
protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
{
_message.WriteBodyContents(writer);
}
protected override void OnWriteStartEnvelope(XmlDictionaryWriter writer)
{
writer.WriteStartElement("soapenv", "Envelope", "http://schemas.xmlsoap.org/soap/envelope/");
writer.WriteAttributeString("xmlns", "v2", null, "http://www.royalmailgroup.com/api/ship/V2");
writer.WriteAttributeString("xmlns", "v1", null, "http://www.royalmailgroup.com/integration/core/V1");
writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema");
}
}
RoyalMailMessageFormatter.cs
public class RoyalMailMessageFormatter : IClientMessageFormatter
{
private readonly IClientMessageFormatter _formatter;
public RoyalMailMessageFormatter(IClientMessageFormatter formatter)
{
_formatter = formatter;
}
public object DeserializeReply(Message message, object[] parameters)
{
return _formatter.DeserializeReply(message, parameters);
}
public Message SerializeRequest(MessageVersion messageVersion, object[] parameters)
{
var message = _formatter.SerializeRequest(messageVersion, parameters);
return new RoyalMailMessage(message);
}
}
RoyalMailIEndpointBehavior.cs
internal class RoyalMailIEndpointBehavior : IOperationBehavior
{
public void ApplyClientBehavior(OperationDescription description, ClientOperation proxy)
{
proxy.Formatter = new RoyalMailMessageFormatter(proxy.Formatter);
}
public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
}
public void Validate(OperationDescription operationDescription)
{
}
}
The error you are getting is basically because of the certificate.
Having said that, I think you should use the v2 of the API as although it is still awful, there are examples out there and you don't need to use a cert.
Rick Strahl has successfully changed the namespaces in the v2 version, see here https://weblog.west-wind.com/posts/2016/Apr/02/Custom-Message-Formatting-in-WCF-to-add-all-Namespaces-to-the-SOAP-Envelope .
There is one new Royal Mail Shipping API 2 available , after I've lost many hours try development the integration with Royal Mail I finally found a way. I'm sharing my project in the git.
https://github.com/americoa/RoyalMailShippingAPIV2

Categories

Resources