Using an asp web api in wpf - asp.net

So i have got a simple question, when using our cms we can attach a driver as an executable.
The driver we want to make is an httpreceiver or just an api endpoint. SO i tought lets use asp.net web api for it -> using version .net 4.6.1. altough asp.net application requires a webserver and is not an executable, But i read on google you can use it inside a wpf application since our cms is wpf in the first place.
So my question is is there a way i can use my mvc web api project inside a wpf application? and if not what would be the best bet to have an httpreceiver or httppost receiver into an executable?
Main reason is we want to send httppost requests to the server as a desktop application. I know it's complicated but thats how it needs to be as far as I know.
In the case where asp is not an option, what the best way to make a postreqst/ httpreceiver as a desktop application?
EDit:
the resource guide from microsoft beneath was perfectly however i still have a question:
string baseAddress = "http://localhost:9000/";
// Start OWIN host
using (WebApp.Start<Startup>(url: baseAddress))
{
// Create HttpClient and make a request to api/values
HttpClient client = new HttpClient();
string username = "test".ToUpper().Trim();
string password = "test123";
//Mock data
var body = new PostTemplate1();
body.Description = "test";
body.StateDesc = "httpdriver/username";
body.TimeStamp = DateTime.Now;
body.Message = "This is a post test";
var json = JsonConvert.SerializeObject(body);
var data = new StringContent(json, Encoding.UTF8, "application/json");
var authToken = Encoding.ASCII.GetBytes($"{username}:{password}");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(authToken));
var response = await client.PostAsync(baseAddress + #"api/Post", data);
var result = response.StatusCode;
}
As the guide says you post to url with port 9000
is there a possibility to use another port and use https?
if yes where to manage certificates for handling https?

Related

Connection closed from Facebook using http requests from ASP.net

I'm trying to make some GETs to the Facebook rest api from an ASP.net core application, but I get every time an exception because the remote host closed the connection. I tried like fourty different solutions that I found in similar questions but none of them worked. I changed the security protocol to Tls 1.2 but still got the same issue; I also tried using web client instead of http client. Then I tought it might have been the proxy of my office but cUrl worked fine; using postman I didn't get any error (even with tsl set to 1.0).
Another attempt was to try changing the keep-alive duration to avoid time-outs.
Here's the code with the HttpClient:
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
using (var httpClient = new HttpClient()){
httpClient.DefaultRequestHeaders.Add("Connection", "Keep-Alive");
httpClient.DefaultRequestHeaders.Add("Keep-Alive", "3600");
var request = new HttpRequestMessage(HttpMethod.Get,
"https://graph.facebook.com/v10.0/me?fields=id%2Cemail%2Cfirst_name%2Clast_name&access_token=" + socialLoginModel.accessToken);
request.Headers.Add("Accept", "application/json");
request.Headers.Add("User-Agent", "BriQ");
var response = await httpClient.SendAsync(request);
}
And here's the code with the WebClient:
using(var wb = new WebClient()){
var response = wb.DownloadString("https://graph.facebook.com/v10.0/me?fields=id%2Cemail%2Cfirst_name%2Clast_name&access_token=" + socialLoginModel.accessToken);
}
I'm completely out of ideas. Maybe it's something really stupid that's causing the exception but I can't figure it out alone
I'm not sure about which exception that you exactly got.
But as far as I know, if you're using .NET Core and the problem is caused by the SSL/TLS handshake failure error, then, unfortunately, setting the ServicePointManager may not work...
Because the ServicePointManager only affects the HttpWebRequest which is the default implementation of HttpClient on .NET Framework. Starting with .NET Core 2.1, the SocketsHttpHandler provides the implementation used by HttpClient.
Hence, I suppose the way to fix the issue is handling the SocketsHttpHandler:
using (var handler = new SocketsHttpHandler())
{
handler.SslOptions = new SslClientAuthenticationOptions{EnabledSslProtocols = SslProtocols.Tls12};
using (var httpClient = new HttpClient(handler))
{
// your code
}
}
Alternatively, if you prefer HttpClientHandler, you could do in this way:
using (var handler = new HttpClientHandler())
{
httpClientHandler.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;
using (var httpClient = new HttpClient(handler))
{
// your code
}
}
Refs:
How to use TLS 1.2 in ASP.NET Core 2.0
HttpClient Class

Using WebClient to get a intranet files

In our I have company intranet a server, that is responsible for storing files. Initially, the server had to operate only in an intranet environment, but now there is a need to share files with external web applications. Making this server accessible from the internet is not an option.
I want to create a ASP.NET MVC solution that uses the WebClient to get these files from the intranet server and send back them to the user through FileResult of the external app. This client would be provided with custom domain user credentials. So far I have tried to create a CredentialCache class, set correct credentials and append it to WebClients Credentials property like in the following code:
public ActionResult Download(int id, string fileName)
{
var fileService = new FilesService();
var documentUrl = fileService.GetUrlFileByFileId(id);
string filePath = "http://my.intranet.com/" + documentUrl;
var fileNameFromUrl = filePath.Substring(filePath.LastIndexOf("\\") + 1);
byte[] filedata;
CredentialCache cc = new CredentialCache();
cc.Add(new Uri("http://my.intranet.com/"),
"ntlm",
new NetworkCredential("myUserName", "myPassword", "myDomain"));
using (var client = new WebClient())
{
client.Credentials = cc;
filedata = client.DownloadData(filePath);
}
string contentType = MimeMapping.GetMimeMapping(filePath);
var cd = new ContentDisposition
{
FileName = fileName,
Inline = false
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(filedata, contentType);
}
According to the question posted in Domain credentials for a WebClient class don't work it should work, but it’s not. It’s running only if I run the problem on localhost, but when I publish my solution on a test server, it return 401 error. My question is did how to get this working? And is it possible to download files through this method?
UPDATE--- I've published my test app on another server and it started to working. Now the test app is on another server than the server That stores files. Any ideas why it's not working when both are on the same machine?
401 error is unauthorized, so perhaps the issue is related to permissions. Are you sure the user account you are using to login to that folder has the proper access?
Ok, I found the solution on this site: https://blogs.msdn.microsoft.com/distributedservices/2009/11/10/wcf-calling-wcf-service-hosted-in-iis-on-the-same-machine-as-client-throws-authentication-error/
The solution was to add an registry entry and add my web apps to this entry to allow back connections.

WCF service act as proxy for external web service

I'm working on developing proxy WCF service. So tasks that I have to achieve as part of this assignment are:
I have to capture headers and content from an incoming request (from
a web browser).
Construct a web request for external web service with headers and
content from incoming request.
Execute web request.
Capture headers/cookies/content form the Response of external web
service.
Construct response, add headers/cookies and send response back to
browser.
I'm able to manage 1, 2 , 3 and 4 with help of web and stackoverflow. But not find any solution for task 5.
Questions:
Response message from external web service is a json. How to send the same message in json format to web browser?
Response from external web service has 'set-cookie' header. How to add this to web browser response?
I'm new to WCF and Web Service world. Using System.Net.Http.HttpClient to make a call to external web service. Open to change it to any other client library to achieve tasks 1 to 5.
Code blocks:
IService1.cs
[OperationContract]
[WebInvoke(Method = "POST",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.WrappedRequest,
UriTemplate = "client/api")]
string ProxyAPI(Stream inp);
Service1.cs
public string ProxyAPI(Stream contentStream)
{
// Task 1: Capture Headers and content
// Task 2: Construct web request with headers and content from incoming request
HttpClient proxyClient = new HttpClient();
Uri extWSuri = new Uri("http://router.sdc.com:8090/service/api");
proxyClient.BaseAddress = extWSuri;
// get input reqquest headers and add to httpclient onject
WebOperationContext current = WebOperationContext.Current;
WebHeaderCollection headers = current.IncomingRequest.Headers;
string[] headerKeys = headers.AllKeys;
foreach (string keyStr in headerKeys)
{
if (keyStr.ToLower().Equals("host"))
{
proxyClient.DefaultRequestHeaders.Add(keyStr, "router.simplifydc.com:8080");
}
else if (!keyStr.ToLower().StartsWith("cont"))
{
proxyClient.DefaultRequestHeaders.Add(keyStr, headers.GetValues(keyStr));
}
}
// get input content data
StreamReader reader = new StreamReader(contentStream);
string contentData = reader.ReadToEnd();
reader.Close();
// create content for httpclient request
StringContent contentRequest = new StringContent(contentData, System.Text.Encoding.UTF8, "application/x-www-form-urlencoded");
// Task 3: execute web request
Task<HttpResponseMessage> responseTask = proxyClient.PostAsync(extWSuri, contentRequest);
responseTask.Wait();
// Task 4: Capture headers/cookies/contnet from web response
HttpResponseMessage response = responseTask.Result;
HttpResponseHeaders resHeaders = response.Headers;
Task<string> contentTask = response.Content.ReadAsStringAsync();
contentTask.Wait();
string responseMsg = contentTask.Result;
// Task 5: construct response for incoming web browser request
// ?????????????
return responseMsg;
}
If I get it right, the client application for your WCF service is a web browser. This means that it expects an HTML document as a response right? In this case, I would suggest to avoid using a WCF service.
Why don't you use an ASP.NET page which forms the HTML to return? In your ASP.NET code behind, you could execute the 4 four steps you describe. In your 5th step, you would adjust the HTML to contain the data you got in the previous steps from the external web service.
You could always construct the HTML response using the WCF service, but I cannot see why. You could use and HTML DOM parser (like this to construct the HTML response programmatically, but this would not be my first approach.
If your page requires pure data and not HTML, your WCF service could return data in JSON format. As you can see, JSON is a simple string which could be very easy to construct. It depends on the data you want to return, but it could be very easy implemented either manually, or using some specific library like Json.NET. Then your UI application would parse JSON and display data accordingly.
Hope I helped!

Dot Net Client and IIS hosted SignalR with Win auth

Is there a way to configure the .NET client so that it will work with a IIS hosted SingalR that uses Windows authentication?
If I disable windows authentication it works, but this is not an option
setting connection.Credentials = CredentialCache.DefaultCredentials does not help.
The code
public EventProxy(IEventAggregator eventAggregator, string hubUrl)
{
typeFinder = new TypeFinder<TProxyEvent>();
subscriptionQueue = new List<EventSubscriptionQueueItem>();
this.eventAggregator = eventAggregator;
var connection = new HubConnection(hubUrl);
connection.Credentials = CredentialCache.DefaultCredentials;
proxy = connection.CreateHubProxy("EventAggregatorProxyHub");
connection.Start().ContinueWith(o =>
{
SendQueuedSubscriptions();
proxy.On<object>("onEvent", OnEvent);
});
}
ContinueWith triggerst directly after Start and when the first subscription comes in I get a
The Start method must be called before data can be sent.
If I put a watch on the DefaultCredentials I can see that Username, Domain and Password are all String.Empty. Its a standard Console program, Enviroment.Username returns my username
Sure, set connection.Credentials = CredentialCache.DefaultCredentials. More details about credentials here http://msdn.microsoft.com/en-us/library/system.net.credentialcache.defaultcredentials.aspx.

Publishing with Core Service and Impersonation

I have a Tridion Core Service Web Application to publish pages. When logged into the server and running it from there via a browser client calling a web service with ajax it works fine. However, when I run the application from my desktop it does nothing, and also throws no error messages.
*Edit:
The Web App hosting the web service is running as an 'Application' under the Tridion 2011 CMS website. This is done to avoid cross-domain ajax issues/
Update: The code below is working fine - both with the impersonate and also with Nick's solution. My issue was actually in how I was calling the web service from jQuery and using the appropriate URL. I am leaving the code and question so maybe it will help others.
My code is:
string binding = "wsHttp_2011";
using (var client = new SessionAwareCoreServiceClient(binding))
{
client.Impersonate("company\\cms_svc");
// ** Get Items to Publish
List<string> itemsToPublish = GetItemsToPublish(publishItem.TcmUri, client);
PublishInstructionData instruction = new PublishInstructionData
{
ResolveInstruction = new ResolveInstructionData() { IncludeChildPublications = false },
RenderInstruction = new RenderInstructionData()
};
PublicationTargetData pubtarget = (PublicationTargetData)client.Read(publishItem.PubTargetUri, readoptions);
List<string> target = new List<string>();
target.Add(pubtarget.Id);
client.Publish(itemsToPublish.ToArray(), instruction, target.ToArray(), GetPublishPriority(publishItem.Priority), readoptions);
}
Have at look at this page on SDL Live Content, which explains various types of scenarios for connecting as different users:
http://sdllivecontent.sdl.com/LiveContent/content/en-US/SDL_Tridion_2011_SPONE/task_87284697A4BB423AAD5387BBD6884735
As per the docs, instead of impersonation you may want to establish your Core Service connection as follows using NetworkCredential:
using (ChannelFactory<ISessionAwareCoreService> factory =
new ChannelFactory<ISessionAwareCoreService>("netTcp_2011"))
{
NetworkCredential networkCredential =
new NetworkCredential("username", "password", "domain");
factory.Credentials.Windows.ClientCredential = networkCredential;
ISessionAwareCoreService client = factory.CreateChannel();
Console.WriteLine(client.GetCurrentUser().Title);
}

Resources