How to access a WCF REST Service inside .Net web application? - asp.net

I have a WCF web service which returns a JSON string from a Silverlight appication. I want to parse this JSON string inside a controller method in another web application. I cant create a service reference to the WCF service I created in Silverlight in the web application since it is a REST service. How can I access this WCF REST service in the other application?

You should use something like the System.Net.WebRequest to call the WCF service in your controller.
There are a plethora of examples online on how to use it properly.
Personally, I use JSON.Net or AngularJS in all of my applications.

I was able to access the web service with the following code
using System.Net;
public string GetWebServiceData()
{
try
{
string requestUrl = "requesturl";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUrl);
request.Method = WebRequestMethods.Http.Post;
request.ContentType = "application/json";
request.ContentLength = 0;
request.Expect = "application/json";
WebResponse response = request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string json = reader.ReadToEnd();
return json;
}
catch (Exception)
{
return new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(string.Empty);
}
}
}

Related

.net core 2.0 proxy requests always result in http 407 (Proxy Authentication Required)

I'm trying to make HTTP requests via a WebProxy in a .net core 2.0 web application. The code I've got works fine in .net framework so I know (believe) its not an environmental issue. I've also tried to make the request using both HttpWebRequest and HttpClient but both mechanisms always result in 407 (Proxy Authentication Required) http error in .net core. Its as if in .net core the credentials I'm supplying are always being ignored.
Here is the code I've been using:
public void Test()
{
var cred = new NetworkCredential("xxxxx", "yyyyyy");
var proxyURI = new Uri("http://xxx.xxx.xxx.xxx:80");
var destinationURI = new Uri("http://www.bbc.co.uk");
WebProxy proxy = new WebProxy(proxyURI, false) { UseDefaultCredentials = false, Credentials = cred };
MakeProxyRequestViaHttpWebRequest(proxy, destinationURI);
MakeProxyRequestViaHttpClient(proxy, destinationURI);
}
private void MakeProxyRequestViaHttpClient(WebProxy proxy, Uri destination)
{
HttpClientHandler handler = new HttpClientHandler()
{
Proxy = proxy,
UseProxy = true,
PreAuthenticate = true,
UseDefaultCredentials = false
};
HttpClient client = new HttpClient(handler);
HttpResponseMessage response = client.GetAsync(destination).Result;
if (response.IsSuccessStatusCode)
{
HttpContent content = response.Content;
string htmlData = content.ReadAsStringAsync().Result;
}
else
{
HttpStatusCode code = response.StatusCode;
}
}
private void MakeProxyRequestViaHttpWebRequest(WebProxy proxy, Uri destination)
{
HttpWebRequest req = HttpWebRequest.Create(destination) as HttpWebRequest;
req.UseDefaultCredentials = false;
req.Proxy = proxy;
req.PreAuthenticate = true;
using (WebResponse response = req.GetResponse())
{
using (StreamReader responseStream = new StreamReader(response.GetResponseStream()))
{
string htmlData = responseStream.ReadToEnd();
}
}
}
I've tried the following in .net core but the result is always 407:
Run the code in a console app
Implement IWebProxy and use that as the proxy
Set default values for other properties on WebProxy, HttpClient, etc. (removed on the example above because it works fine on .net standard)
I've run out of ideas and things to try. I have the following questions:
Does the code need to be different between .net core vs .net framework
Are there additional things that need to go into appsettings.json (ie. the config that would have gone into web.config)
Is there any additional configuration code required in Startup.cs
Should I be looking to use an external library
How would I trouble shoot what the issue is? Fiddler doesn't seem to be helping but then I haven't looked to hard at configuring it.

How to consume a secure Rest MVC web api

I'm just a beginner on the .NET world and I've created a web api (.NET 4.5.2) and I'm using the annotation [Authorize] above my controllers like shown below:
[Authorize]
public class PhasesController : ApiController
{
private TestReportEntities db = new TestReportEntities();
// GET: api/Phases
public IQueryable<Phase> GetPhase()
{
return db.Phase;
}
}
I've already created my DB and I'm using the default tables that the web.api uses to manage the access, as you can see on this image:
My tables
I've already done a method to request to my web api, in another project/solution, it's working fine when I remove the annotation [Authorize] from my web api controllers.
this is an example about how I'm requesting my api:
public int GetCurrentIdPhase(int idProject)
{
int phaseId = -1;
WebRequest request = WebRequest.Create(string.Concat(URL, string.Format("api/phases/?idProject={0}", idProject)));
using (var resp = (HttpWebResponse)request.GetResponse())
{
using (var reader = new StreamReader(resp.GetResponseStream()))
{
string objText = reader.ReadToEnd();
var phase = JsonConvert.DeserializeObject<List<Phase>>(objText);
phaseId = phase[0].id;
}
}
if (phaseId != -1)
{
return phaseId;
}
else
{
throw new Exception("Phase not found");
}
}
At the end of the day my questions are:
How can I request a token to my api (POST - www.myApi/token) using the example above?
How can I use the token, once I've got it, on every request to my API?
if you can help me I would really appreciate it.
Thanks.
I've created a method to get the Token from my Web API, this is the method:
var request = (HttpWebRequest)WebRequest.Create(string.Concat(URL, "token"));
var postData = "grant_type=password";
postData += string.Format("&userName={0}", user);
postData += string.Format("&password={0}", pass);
var data = Encoding.ASCII.GetBytes(postData);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
string objText = new StreamReader(response.GetResponseStream()).ReadToEnd();
var requestedToken = (JObject)JsonConvert.DeserializeObject(objText);
token = string.Concat(token, requestedToken["access_token"].Value<string>());
And to request something to my API all I need to do is just add the token on the header of all requests like shown on the line below:
request.Headers.Add(HttpRequestHeader.Authorization, getToke());
Hope it can help someone else who is beginning to work with .NET web API like me.
Regards.
Im assuming the "GetCurrentIdPhase" call is from an unrelated app with unrealted auth - if any auth.
The difficulty here is in using Authorize and the traidtional browser authentication flow. Here's an example of changing the pipeline a bit to use a different auth form for using console/desktop apps. You don't say where you are calling GetCurrentIdPhase from so I'll have to assume either a separate app. If its a web app and you are authenticated using the same tables, then you will have to share the token between them using for ex. the url blackice provided above.
If the app is a desktop/console/etc (not another app that the user had to auth against the same tables) then you can try this approach to change how auth is done to make it easier to access.
MVC WebAPI authentication from Windows Forms

Examine Request Headers with ServiceStack

What is the best way to inspect the Request Headers for a service endpoint?
ContactService : Service
Having read this https://github.com/ServiceStack/ServiceStack/wiki/Access-HTTP-specific-features-in-services I'm curious as to the preferred way to get to the Interface.
Thank you,
Stephen
Inside a ServiceStack Service you can access the IHttpRequest and IHttpResponse objects with:
public class ContactService : Service
{
public object Get(Contact request)
{
var headerValue = base.Request.Headers[headerKey];
//or the same thing via a more abstract (and easier to Mock):
var headerValue = base.RequestContext.GetHeader(headerKey);
}
}
The IHttpRequest is a wrapper over the underlying ASP.NET HttpRequest or HttpListenerRequest (depending if you're hosting on ASP.NET or self-hosted HttpListener). So if you're running in ASP.NET you can get the underlying ASP.NET HttpRequest with:
var aspnetRequest = (HttpRequest)base.Request.OriginalRequest;
var headerValue = aspnetRequest.Headers[headerKey];

How to call a WebService which has a querystring data?

I have a webservice which i need to call in .net application. The link looks like this.
http://www.contoso.com/student?id=12345
This will work only when its called like this. For rest of the this i dont have access. ie if i call it on a browser without the querystring it will not work. but with querystring it will return an XML data.
Now, when i call this in the .net application its not working?
How can I call this in a .NET application?
The Normal Webservice Importing methods are not working since it needs a querystring with value and we dont have access to the links which doesnt have the querystring.
How are you currently trying to download it?
A very simple way to do this is to use the HttpWebRequest and HttpWebResponse classes;
public XmlDocument GetStudentXml(int studentId)
{
XmlDocument targetXml = new XmlDocument();
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(String.Format("http://www.contoso.com/student?id={0}", studentId));
webRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;
webRequest.Accept = "text/xml";
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
using (Stream responseStream = webResponse.GetResponseStream())
{
XmlTextReader reader = new XmlTextReader(responseStream);
targetXml.Load(reader);
reader.Close();
}
webResponse.Close();
return targetXml;
}
This method simply creates a HttpWebRequest, initializes it with the URL (via String.Format so as to append the student id), some windows credentials and the expected content type.
It then calls the remote address via the GetResponse method. The response is then loaded into a stream, and an XmlTextReader is used to load the Xml data from the response stream into the XmlDocument, which is then returned to the caller.
You can also use WebClient and XDocument to achieve the same thing:
string url = String.Format("http://www.contoso.com/student?id={0}", studentId);
string remoteXml;
using (var webClient = new WebClient())
{
remoteXml = webClient.DownloadString(url);
}
XDocument doc = XDocument.Parse(remoteXml);

calling a wcf webapi service with basic authentication from an asp.net 2.0 project

I'm working on a project that uses wcf webapi to expose all it's functionality as web services. I then consume these with various views (well two for now). One of these views is a legacy asp.net 2.0 project that will eventually be phased out once this new project has feature parity. I'm trying to consume these services by adding a service reference to the project but can't get it to work because the wcf api uses basic http auth and I can't configure that in the wizard. How do I manually add the service reference to my asp.net project?
Thanks!
When working with WCF Web API, you don't use service references but the new HttpClient instead e.g.:
var client = new HttpClient();
var byteArray = Encoding.ASCII.GetBytes(userName + ":" + password);
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
var task = client.GetAsync("http://webapi/contact/1");
var contact = task.ContinueWith(
t => {
return t.Result.Content.ReadAsAsync<Contact>();
}).Unwrap().Result;
If you need to use .NET 2.0, you can use the HttpWebRequest (the HttpClient sample relies on .NET 4.0 as it is part of WCF Web API):
Uri myUri = new Uri("http://webapi/contact/1");
WebRequest myWebRequest = HttpWebRequest.Create(myUri);
HttpWebRequest myHttpWebRequest = (HttpWebRequest)myWebRequest;
NetworkCredential myNetworkCredential =
new NetworkCredential(username, password);
CredentialCache myCredentialCache = new CredentialCache();
myCredentialCache.Add(myUri, "Basic", myNetworkCredential);
myHttpWebRequest.PreAuthenticate = true;
myHttpWebRequest.Credentials = myCredentialCache;
WebResponse myWebResponse = myWebRequest.GetResponse();
Stream responseStream = myWebResponse.GetResponseStream();

Resources