Very simple web API app - 2 methods - hard code basic authentication - asp.net-web-api

I have a very simple Web API app. Just 2 methods that put (edit or insert data) - I'd like to just hard code basic authentication into the 2 methods without hugely complicating it.
What is the minimum code I need in order to require authentication the two methods - and then how do I use this code (the APIs are called from some C# code in an MVC app).
All of the examples I find online are hugely complicated - with filters or overly elaborate authentication.
My web API methods look something like this:
public IHttpActionResult Put([FromBody]ImportObject impobj)
{
// Import data here
}
And I call it like this:
public async static Task<string> Caller(ImportObject impobj)
{
string responseString = "NA";
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Post new object, get response
var response = await client.PutAsJsonAsync("myservice/api/meth", impobj);
// Get response content string
var resContent = response.Content.ReadAsStringAsync();
// Build user response string (just for testing)
responseString =
"<br />result: " + resContent.Result.ToString() +
"<br />status: " + resContent.Status.ToString() +
"<br />StatusCode: " + response.StatusCode + "<br />";
}
// Output response string
return responseString;
}
I just want to add basic auth to both ends - as it's so simple happy to just hard code it into both methods (this will also let me see easily how it works too).
thx.

Related

client.DeleteAsync - include object in body

I have an ASP.NET MVC 5 website - in C# client code I am using HttpClient.PutAsJsonAsync(path, myObject) fine to call a Json API (the API is also mine created in Web API).
client.BaseAddress = new Uri("http://mydomain");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.PutAsJsonAsync("api/something", myObj);
I would like to do the same with a Delete verb. However client.DeleteAsync does not allow an object to be passed in the body. (I would like to record the reason for deletion alongside the Id of the item to delete in the URI).
Is there a way to do this?
You'll have to give up a little in terms of convenience since the higher-level DeleteAsync doesn't support a body, but it's still pretty straightforward to do it the "long way":
var request = new HttpRequestMessage {
Method = HttpMethod.Delete,
RequestUri = new Uri("http://mydomain/api/something"),
Content = new StringContent(JsonConvert.SerializeObject(myObj), Encoding.UTF8, "application/json")
};
var response = await client.SendAsync(request);

AndroidClientHandler and built-in Basic authentication

I'm trying to make the built-in Basic Authentication work with the Xamarin AndroidClientHandler, but with no success. The code looks like this:
https://github.com/tieto-sternell/DemoAndroidBasicAuth/blob/c6bb4d547f2456e66b25daca4951957250278ac3/DemoAndroidBasicAuth/DemoAndroidBasicAuth.Droid/TestStuff.cs#L39-L43
ICredentials credentials = new NetworkCredential(dummyUsername, dummyPassword);
var handler = new AndroidClientHandler();
handler.Credentials = credentials;
and:
https://github.com/tieto-sternell/DemoAndroidBasicAuth/blob/c6bb4d547f2456e66b25daca4951957250278ac3/DemoAndroidBasicAuth/DemoAndroidBasicAuth.Droid/TestStuff.cs#L19-L21
var client = new HttpClient(handler);
var badResponse = await client.GetAsync(basicUri) as AndroidHttpResponseMessage;
As you can see, it is pretty straight-forward and the code looks very similar to its working .Net equivalent. The response is 401, though, so I am doing something wrong.
Edit: As #jgoldberger points out below, it is possible to create the headers manually. This can be done either by adding a header to the message (github.com/tieto-sternell/DemoAndroidBasicAuth/blob/e7118f88a5b45f91207e90e9ea64c554d0ea9cd6/DemoAndroidBasicAuth/DemoAndroidBasicAuth.Droid/TestStuff.cs#L43-L48)
byte[] byteToken = System.Text.Encoding.UTF8.GetBytes(dummyUsername + ":" + dummyPassword);
var tokenValue = Convert.ToBase64String(byteToken);
var token = "Basic " + tokenValue;
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, new Uri(basicUri));
requestMessage.Headers.Add("Authorization", token.ToString());
Or by adding a header to the HttpClient (github.com/tieto-sternell/DemoAndroidBasicAuth/blob/e7118f88a5b45f91207e90e9ea64c554d0ea9cd6/DemoAndroidBasicAuth/DemoAndroidBasicAuth.Droid/TestStuff.cs#L33-L37)
byte[] byteToken = System.Text.Encoding.UTF8.GetBytes(dummyUsername + ":" + dummyPassword);
var tokenValue = Convert.ToBase64String(byteToken);
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", tokenValue);
I don't think that this is how it is supposed to work, though. I mean, when is this (github.com/xamarin/xamarin-android/blob/0c3597869bc4493895e755bda8a26f778e4fe9e0/src/Mono.Android/Xamarin.Android.Net/AuthModuleBasic.cs#L50-L52)
response += cred.UserName + ":" + cred.Password;
return new Authorization ($"{AuthenticationType} {Convert.ToBase64String (Encoding.ASCII.GetBytes (response))}");
code supposed to run in that case?
It looks to me as if the Authentication module isn't used.
The background story here is that I need to know how to make Basic work as part of a larger problem which involves Digest authentication and the custom "AuthenticationScheme.Unsupported", but we'll get there later when we've got the simpler basic auth scheme up and running.
Best regards,
Christian

WebRequest returns 404 when switching to SSL

Having built an app using PCL method in Xamarin and have had it working 100% using standard HTTP I now changed the remote test server to use SSL with self signed certs.
The app contacts a custom API for logging onto a server and querying for specific data.
I've changed the app to look at SSL now and initially got an error regarding Authentication not working or something but turned off SSL related errors for testing using:
ServicePointManager.ServerCertificateValidationCallback += (o, certificate, chain, errors) => true;
in my AppDelegate files FinishedLaunching method which got over that error.
I'm now getting a 404 / protocol error when trying to do my Login POST to the given URL.
I am using HttpWebRequest for my RESTful calls and this works fine if I change back to plain http.
Not sure why but some articles suggested using ModernHttpClient, which I did. I imported the component (also added the package using NuGet) to no avail.
Am I missing something else that I should be configuring in my code related to httpwebresponse when contacting the SSL server or is this component simply incapable of speaking to an SSL server?
My login function is as follows (Unrelated code removed/obfuscated):
public JsonUser postLogin(string csrfToken, string partnerId, string username, string password){
string userEndPoint = SingletonAppSettngs.Instance ().apiEndPoint;
userEndPoint = userEndPoint.Replace ("druid/", "");
var request = WebRequest.CreateHttp(string.Format(this.apiBaseUrl + userEndPoint + #"user/login.json"));
// Request header collection set up
request.ContentType = "application/json";
request.Headers.Add ("X-CSRF-Token", csrfToken);
// Add other configs
request.Method = "POST";
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
string json_body_content = "{\"username\":\"" + username + "\",\"password\":\"" + password + "\"}";
streamWriter.Write(json_body_content);
streamWriter.Flush();
streamWriter.Close();
}
try{
HttpWebResponse httpResponse = (HttpWebResponse)request.GetResponse();
using (StreamReader reader = new StreamReader (httpResponse.GetResponseStream ())) {
var content = reader.ReadToEnd ();
content = content.Replace ("[],", "null,");
content = content.Replace ("[]", "null");
if (content == null) {
throw new Exception ("request_post_login - content is NULL");
} else {
JsonSerializerSettings jss = new JsonSerializerSettings();
jss.NullValueHandling = NullValueHandling.Ignore;
JsonUser deserializedUser = JsonConvert.DeserializeObject<JsonUser>(content, jss);
if(content.Contains ("Hire company admin user")){
deserializedUser.user.roles.__invalid_name__5 = "Hire company admin user";
deserializedUser.user.roles.__invalid_name__2 = "authenticated user";
}
return deserializedUser;
}
}
}catch(Exception httpEx){
Console.WriteLine ("httpEx Exception: " + httpEx.Message);
Console.WriteLine ("httpEx Inner Exception: " + httpEx.InnerException.Message);
JsonUser JsonUserError = new JsonUser ();
JsonUserError.ErrorMessage = "Error occured: " + httpEx.Message;
return JsonUserError;
}
}
When making a Web Request using ModernHttpClient, I generally follow the pattern below. Another great library created by Paul Betts is refit, and can be used to simplify rest calls.
using (var client = new HttpClient(new NativeMessageHandler(false, false)))
{
client.BaseAddress = new Uri(BaseUrl, UriKind.Absolute);
var result = await Refit.RestService.For<IRestApi>(client).GetData();
}
The second parameter for NativeMessageHandler should be set to true if using a customSSLVerification.
Here's a look at IRestApi
public interface IRestApi
{
[Get("/foo/bar")]
Task<Result> GetMovies();
}
Number of things I had to do to get this to work.
The Self Signed Cert had to allow TLS 1.2
As the API is Drupal based, HTTPS had to be enabled on the server and a module installed to manage the HTTP specific pages.

Paypal Payflow Transparent Redirect, SecureToken with AJAX?

I'm working on a C# VS2012 Framework 4.5 MVC application that is trying to become PCI compliant using Payflow Pro (https://pilot-payflowpro.paypal.com). We've been using PayflowPro for years, and this is what I have to use. From my reading it seems that I should use the Transparent Redirect so I'm not posting anything private to my webserver, though I don't know if I need that with how I'm hoping to handle this. I also have a few questions...
How I think this all works:
My understanding is that you need a securetoken (communication to Paypal, trip 1). Then you post the secure data (CC, exp, security code) including the securetoken (communication to Paypal, trip 2) and receive the authorization and transactionID of the sale.
How I'm hoping to do it:
I'm intending on having a form that will have all the info (user details, shipping details, and CC info), and when the user presses the purchase button, I'll use AJAX to process trip 1 to my server (no secure user info sent). Here I'll create the URL + params and send paypal my un/pw info to retrieve the token (all from my server). The response will be returned to the client and, if successful, I'll then directly communicate via AJAX to Paypal's Gateway server, this time sending the secure CC info + token (trip #2). Based on the response to trip #2, I'll let the user know what's up with their purchase. Trip 2 shouldn't need my Paypal UN/PW info as it could easily be see on the client, and I'm including the SecureToken which SHOULD identify the original transaction. From what I've explained I don't see a need for Transparent Redirect. Or am I missing something here?
Also, what Transaction Type do I want to use? Create an 'Authorization' for trip #1, then a 'Sale' for trip #2?
So here's the nitty gritty coding type stuff:
For my R&D testing I'm building my own name/value pair parameter string (see below) and communicating to the gateway server via WebRequest through their sandbox/test url (pilot-payflowpro.paypal.com). I do get a successful response and SECURETOKEN back. Initial request (shown below) for secure token is TRXTYPE = A (Authorization), no card info is sent. Do I want to authorize first?
Here are my parameters (might include shipto info as well, but it's not listed below):
USER=myAuthUserName
&VENDOR=myAuthUserName
&PARTNER=myPartner
&PWD=myPassword
&AMT=21.43
&BILLTOFIRSTNAME=FName
&BILLTOLASTNAME=LName
&BILLTOSTREET=123 Main Street
&BILLTOSTREET2=Apt 203B
&BILLTOCITY=MyCity
&BILLTOSTATE=CA
&BILLTOZIP=77777
&BILLTOPHONENUM=4444444444
&EMAIL=myemail#somedomain.com
&CURRENCY=USD
**&TRXTYPE=A**
&SILENTTRAN=TRUE
&CREATESECURETOKEN=Y
&SECURETOKENID=a99998afe2474b1b82c8214c0824df99
As I said, I get a successful response and move to the next step of sending the secure data (CC#, EXPDATE, security code). When I remove my UN/PW/VENDOR/Partner info from the params I get an error due to invalid user authentication. But, seeing I'm dynamically building this 2nd call I can't have my paypal un/pw there. What am I missing? Anyone offer assistance with this or the other questions from above?
Please let me know if I need any clarification to be added. Thanks in advance for your time!
After spending a bunch of time with a Paypal engineer I've successfully figured out a solution for the Paypal's Payflow Transparent Redirect without hosted pages (have own payment page). Again, here's the documentation which, per the engineer, is pretty confusing: Payflow API Documentation. Also, the code isn't optimized as it was just a R&D app, but as a whole, it is working for me. Just an example and explanation, and I'm sure there are better ways of doing individual steps. Hope this helps and allows you to bypass some of the roadblocks that have been slowing down your Paypal Payflow integration.
YES, it is PCI compliant in that no secure customer data will hit your own servers. Remember that PCI compliance is pretty complicated and involved but this is big part of it. Ok, so I'll explain what I did to make this work in a MVC C# environment. I'll explain the steps here, then include code below.
CLIENT: Client finishes adding items to the cart and presses BUY button. Javascript handles the button click, doesn't submit, and takes you to the next step.
CLIENT --> SERVER: AJAX function POSTS to server method to contact Paypal for the single-use secure token. This communication identifies YOU (the merchant) to paypal with your authentication, a unique transaction id (a guid), and non secure details about the transaction (total, billing info, shipping info, return URL details). This way, all your merchant personal acct info is secure (web server to Paypal).
SERVER --> CLIENT: From the transaction above you'll receive a parameter string that contains the secure token (among other stuff, see method with example). Using this piece of info, I dynamically create my url that I'll eventually need on the client for the transparent redirect part, and send the url string back to the client.
CLIENT: Using the url that was returned in step #3, I complete the URL by adding the needed credit card parameters using jQuery.
CLIENT --> PAYPAL: This is where I didn't understand what to do. While step #2 was a post, this step will be a REDIRECT. Sure, that seems appropriate seeing it's called 'transparent redirect', but that part just didn't make sense to me. So, once your entire URL is complete, you'll literally redirect the window to Paypal for processing your transaction.
PAYPAL --> SERVER: PayPal posts back to one of the URLs you included in step 2 (to a public method on one of my controllers), and I read the response object and parse the parameters.
Easy, right? Perhaps, but for me step 5 caused me big problems. I was using a POST and didn't understand why I kept getting errors on the response. It was an html page with something about an invalid merchant or authentication. Remember to redirect, not post for step #5.
CODE:
STEP 1: onclick attribute on button to call GetToken function.
STEP 2 and STEP 3:
client-side:
function GetToken() {
$.ajax({
url: '#Url.Action("GetToken", "MyController")',
type: 'POST',
cache: 'false',
contentType: 'application/json; charset=utf-8',
dataType: 'text',
success: function (data) {
// data is already formatted in parameter string
SendCCDetailsToPaypal(data);
},
//error:
//TODO Handle the BAD stuff
});}
Server Side:
I have separate methods used to build all the parameter values needed for the token request. First three build: authentication, transaction details, transparent redirect. I keep urls and payflow acct info in a web.config file. Last method, ProcessTokenTransaction, does all the heavy lifting to contact Paypal via WebRequest, and then parse it into the URL that will be sent back to the client. This method should be refactored for a cleaner delivery, but I'll leave that up to you. ParseResponse is a method that populates a simple model that I created, and returns that model.
URL for token (sandbox): https://pilot-payflowpro.paypal.com
THIS IS DIFFERENT THAN THE TOKEN URL!! Used in the PaypalTranactionAPI config value.
URL for transaction: (sandbox) https://pilot-payflowlink.paypal.com
private string PrepareApiAuthenticationParams()
{
var paypalUser = ConfigurationManager.AppSettings["PaypalUser"];
var paypalVendor = ConfigurationManager.AppSettings["PaypalVendor"];
var paypalPartner = ConfigurationManager.AppSettings["PaypalPartner"];
var paypalPw = ConfigurationManager.AppSettings["PaypalPwd"];
//var amount = (decimal)19.53;
var apiParams = #"USER=" + paypalUser
+ "&VENDOR=" + paypalVendor
+ "&PARTNER=" + paypalPartner
+ "&PWD=" + paypalPw
+ "&TENDER=C"
+ "&TRXTYPE=A"
+ "&VERBOSITY=HIGH";
// find more appropriate place for this param
//+ "&VERBOSITY=HIGH";
return apiParams;
}
private string PrepareTransactionParams(CustomerDetail detail)
{
var currencyType = "USD";
var transactionParams = #"&BILLTOFIRSTNAME=" + detail.FirstName
+ "&BILLTOLASTNAME=" + detail.LastName
+ "&BILLTOSTREET=" + detail.Address1
+ "&BILLTOSTREET2=" + detail.Address2
+ "&BILLTOCITY=" + detail.City
+ "&BILLTOSTATE=" + detail.State
//+ "&BILLTOCOUNTRY=" + detail.Country + // NEEDS 3 digit country code
+ "&BILLTOZIP=" + detail.Zip
+ "&BILLTOPHONENUM=" + detail.PhoneNum
+ "&EMAIL=" + detail.Email
+ "&CURRENCY=" + currencyType
+ "&AMT=" + GET_VALUE_FROM_DB
+ "&ERRORURL= " + HostUrl + "/Checkout/Error"
+ "&CANCELURL=" + HostUrl + "/Checkout/Cancel"
+ "&RETURNURL=" + HostUrl + "/Checkout/Success";
// ADD SHIPTO info for address validation
return transactionParams;
}
private string PrepareTransparentParams(string requestId, string transType)
{
var transparentParams = #"&TRXTYPE=" + transType +
"&SILENTTRAN=TRUE" +
"&CREATESECURETOKEN=Y" +
"&SECURETOKENID=" + requestId;
return transparentParams;
}
// Method to build parameter string, and create webrequest object
public string ProcessTokenTransaction()
{
var result = "RESULT=0"; // default failure response
var transactionType = "A";
var secureToken = string.Empty;
var requestId = Guid.NewGuid().ToString().Replace("-", string.Empty);
var baseUrl = ConfigurationManager.AppSettings["PaypalGatewayAPI"];
var apiAuthenticationParams = PrepareApiAuthenticationParams();
// Create url parameter name/value parameter string
var apiTransactionParams = PrepareTransactionParams(detail);
// PCI compliance, Create url parameter name/value parameter string specific to TRANSAPARENT PROCESSING
var transparentParams = PrepareTransparentParams(requestId, transactionType);
var url = baseUrl;
var parameters = apiAuthenticationParams + apiTransactionParams + transparentParams;
// base api url + required
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "text/name"; // Payflow?
request.Headers.Add("X-VPS-REQUEST-ID", requestId);
byte[] bytes = Encoding.UTF8.GetBytes(parameters);
request.ContentLength = bytes.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close();
WebResponse response = request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
try
{
// sample successful response
// RESULT=0&RESPMSG=Approved&SECURETOKEN=9pOyyUMAwRUWmmv9nMn7zhQ0h&SECURETOKENID=5e3c50a4c3d54ef8b412e358d24c8915
result = reader.ReadToEnd();
var token = ParseResponse(result, requestId, transactionType);
var transactionUrl = ConfigurationManager.AppSettings["PaypalTransactionAPI"];
secureToken = transactionUrl + "?SECURETOKEN=" + token.SecureToken + "&SECURETOKENID=" + requestId;
//ameValueCollection parsedParams = HttpUtility.ParseQueryString(result);
stream.Dispose();
reader.Dispose();
}
catch (WebException ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
}
finally { request.Abort(); }
return secureToken;
}
private TokenResponse ParseResponse(string response, string requestId, string transactionType)
{
var nameValues = HttpUtility.ParseQueryString(response);
int result = -999; // invalid result to guarantee failure
int.TryParse(nameValues.Get(TokenResponse.ResponseParameters.RESULT.ToString()), out result);
// retrieving response message
var responseMessage = nameValues.Get(TokenResponse.ResponseParameters.RESPMSG.ToString());
// retrieving token value, if any
var secureToken = nameValues.Get(TokenResponse.ResponseParameters.SECURETOKEN.ToString());
var reference = nameValues.Get(TokenResponse.ResponseParameters.PNREF.ToString());
var authCode = nameValues.Get(TokenResponse.ResponseParameters.AUTHCODE.ToString());
var cscMatch = nameValues.Get(TokenResponse.ResponseParameters.CSCMATCH.ToString());
// populating model with values
var tokenResponse = new TokenResponse
{
Result = result,
ResponseMessage = responseMessage,
SecureToken = secureToken,
TransactionIdentifierToken = requestId,
TransactionType = transactionType,
ReferenceCode = reference,
AuthorizationCode = authCode,
CSCMatch = cscMatch
};
return tokenResponse;
}
STEP 4 and STEP 5:
Back to Client Side:
Here I use the URL built from the previous steps and add the final needed params (secure credit card info) using jQuery and then REDIRECT to Paypal.
function SendCCDetailsToPaypal(secureParm) {
//alert('in SendCCDetailsToPaypal:' + secureParm);
var secureInfo = '&ACCT=' + $('#ccNumber').val() + '&EXPDATE=' + $("#expMonth").val() + $("#expYear").val() + "&CSC=" + $('#ccSecurityCode').val();
secureInfo = secureParm + secureInfo;
window.location.replace(secureInfo);
}
STEP 6:
Paypal will post back to one of the following methods: Cancel, Error, or Return (name the methods anything you want in the token request). Parse the Response and look at the variables returned from Paypal, particularly the RESULT and RESPMSG. Read the documentation for specifics as you can incorporate address validation and a bunch of other features. Based on the response, display what's appropriate.
server side:
public ActionResult Cancel()
{
var result = ParseRequest(HttpUtility.UrlDecode(Request.Params.ToString()));
//return View("Return", result);
}
public ActionResult Error()
{
var result = ParseRequest(HttpUtility.UrlDecode(Request.Params.ToString()));
return View("Return", result);
}
public ActionResult Return()
{
var result = ParseRequest(HttpUtility.UrlDecode(Request.Params.ToString()));
return View("Return", result);
}
Hope this helps, and good luck! I'll answer clarification questions as I'm able. Thanks for checking this out, and remember to pay it forward.
I was able to use RichieMN's answer to get a working Transparent Redirect happening. However, the problem with doing a redirect with window.location.replace in the SendCCDetailsToPaypal function is that you're passing the data on a GET string.
This works on the PayFlow Gateway side, but when they send the customer's browser back to your ResponseURL, your Apache logs will show the whole payflowlink.paypal.com URL, including the GET string as the referrer in your Apache access logs! That GET string includes the Credit Card number and now you have just lost your PCI compliance!
To alleviate this problem, you can either put the SecureToken and SecureTokenID into your Credit Card entry form, and POST it directly to payflowlink.paypal.com, or you can rewrite the SendCCDetailsToPaypal function to build a form and submit it, like this:
function SendCCDetailsToPaypal() {
var parameters = {
"SECURETOKEN": secureToken,
"SECURETOKENID": secureTokenID,
"ACCT": $("#ccNumber").val(),
"EXPDATE": $("#expMonth").val() + $("#expYear").val(),
"CSC": $("#ccSecurityCode").val()
};
var form = $('<form></form>');
form.attr("method", "post");
form.attr("action", "https://pilot-payflowlink.paypal.com");
$.each(parameters, function(key, value) {
var field = $('<input></input>');
field.attr("type", "hidden");
field.attr("name", key);
field.attr("value", value);
form.append(field);
});
$(document.body).append(form);
form.submit();
}
Since that form transfers the data via POST, when your server gets the result POST back, the referrer does not contain any sensitive data, and your PCI compliance is maintained.

WebService ASP.NET MVC 3 Send and Receive

I've been racking my brain for a couple of days now on how to approach a new requirement.
I have two websites. The first one lets the user fill out an application. The second website is an internal website use to manage the users applications. I need to develop a "web service" that sends the application data from website 1 to website 2 and return a response to website 2 of success or failure. I have never done a web service before and I'm a bit confused on where to start. I've been reading various examples online but they all seem to be just a starting point for building a webservice... no specific examples.
So for posting the data website 1, what would my controller method look like? Do I use Json to post the data to website 2? What would and example of that look like? Is there some form of redirect in the method that points to website 2?
So for posting the response back to website 2 what would that controller method look like? I assume I would use Json again to send the response back to website 1? Is there some form of redirect in the method that points back to website 1?
I would use JSON and POST the application to the web service.
First I am assuming the application data is contained in some type of object. Use JSON.Net to serialize the object into JSON. It will look something like the following code.
var application = new Application();
string serializedApplication = JsonConvert.Serialize(application);
Second is to POST the code your endpoint(webservice, mvc action). To this you'll need to make a HTTPRequest to the endpoint. The following code is what I use to make to POST the code.
public bool Post(string url, string body)
{
//Make the post
ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;
var bytes = Encoding.Default.GetBytes(body);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
Stream stream = null;
try
{
request.KeepAlive = false;
request.ContentLength = bytes.Length;
request.ContentType = "application/x-www-form-urlencoded";
request.Timeout = -1;
request.Method = "POST";
stream = request.GetRequestStream();
stream.Write(bytes, 0, bytes.Length);
}
finally
{
if (stream != null)
{
stream.Flush();
stream.Close();
}
}
bool success = GetResponse(request);
return success;
}
public bool GetResponse(HttpWebRequest request)
{
bool success;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
{
if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.Created)
{
throw new HttpException((int)response.StatusCode, response.StatusDescription);
}
var end = string.Empty;
using (StreamReader reader = new StreamReader(responseStream))
{
end = reader.ReadToEnd();
reader.Close();
success = JsonConvert.DeserializeObject<bool>(end);
}
response.Close();
}
}
return success;
}
So now you have can POST JSON to an endpoint and receive a response the next step is to create the endpoint. The following code will get you started on an endpoint in mvc that will receive an application and process it.
[HttpPost]
public ActionResult SubmitApplication()
{
//Retrieve the POSTed payload
string body;
using (StreamReader reader = new StreamReader(Request.InputStream))
{
body = reader.ReadToEnd();
reader.Close();
}
var application = JsonConvert.Deserialize<Application>(body);
//Save the application
bool success = SaveApplication(application);
//Send the server a response of success or failure.
return Json(success);
}
The above code is a good start. Please note, I have not tested this code.
You have obviously more than one client for the data & operations. so a service is what you are looking for.
ASP.NET MVC is a good candidate for developing RESTful services. If you (and your Manager) are ready to use beta version, Then Checkout ASP.NET-Web API.
If you want to stay with a stable product, Go for MVC3. you may need to write some custom code to return the data in XML as well as JSON to server different kind of clients. There are some tutorials out there.
So create a Service (ASP.NET MVC / WCF Service) .You may then create 2 client apps, one for the external clients and another for the Internal users. Both of this apps can call methods in the Service to Create/ Read the user accounts / or whatever operation you want to do.
To make the apps more interactive and lively , you may conside including a wonderful thing called SiganalR, which helps you to get some real time data without continuosly polling the data base/ middle tier very in every n seconds !

Resources