I am using vs 2017rc and I have compatibility issues. I can't add windows form doll to my project and when I try to convert the code from win forms to Asp k get issues. Maybe I am doing it wrong but it seem to work on vs2015.
Please I need help to solve this. Maybe I am doing it wrong. See the code below.
using DotNetBrowser;
using DotNetBrowser.WinForms;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;
namespace GetAjaxResponseBodySample
{
public partial class Form1 : Form
{
private static List<string> ajaxUrls = new List<string>();
private WinFormsBrowserView browserView;
public Form1()
{
InitializeComponent();
browserView = new WinFormsBrowserView();
browserView.Browser.Context.NetworkService.ResourceHandler = new AjaxResourceHandler();
browserView.Browser.Context.NetworkService.NetworkDelegate = new AjaxNetworkDelegate();
Controls.Add(browserView);
browserView.Browser.LoadURL("http://www.w3schools.com/xml/ajax_examples.asp");
}
private class AjaxResourceHandler : ResourceHandler
{
public bool CanLoadResource(ResourceParams parameters)
{
if (parameters.ResourceType == ResourceType.XHR)
{
Debug.WriteLine("Intercepted AJAX request: " + parameters.URL);
ajaxUrls.Add(parameters.URL);
}
return true;
}
}
private class AjaxNetworkDelegate : DefaultNetworkDelegate
{
public override void OnDataReceived(DataReceivedParams parameters)
{
if (ajaxUrls.Contains(parameters.Url))
{
Debug.WriteLine("Captured response for: " + parameters.Url);
Debug.WriteLine("MimeType = " + parameters.MimeType);
Debug.WriteLine("Charset = " + parameters.Charset);
PrintResponseData(parameters.Data);
}
}
private void PrintResponseData(byte[] data) {
Debug.WriteLine("Data = ");
var str = Encoding.Default.GetString(data);
Debug.WriteLine(str);
}
}
}
Am not concerned with the browser view... I already get the Jason I need from the Ajax response body.
It is possible to use Browser in a headless mode without creating BrowserView at all.
The following sample code works in the web application on VS2017rc with ASP.NET Core Web Application (.NET Framework) or ASP.NET Web Application (.NET Framework).
Please take into account that it is necessary to Dispose browser after the response body has been captured.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using DotNetBrowser;
using System.Diagnostics;
using System.Text;
namespace WebApplication7.Controllers
{
public class HomeController : Controller
{
private static List<string> ajaxUrls = new List<string>();
Browser browser;
public string Index()
{
Init();
return "Test page";
}
private void Init()
{
browser = BrowserFactory.Create();
browser.Context.NetworkService.ResourceHandler = new AjaxResourceHandler();
browser.Context.NetworkService.NetworkDelegate = new AjaxNetworkDelegate();
browser.LoadURL("https://www.w3schools.com/xml/ajax_examples.asp");
}
private class AjaxResourceHandler : ResourceHandler
{
public bool CanLoadResource(ResourceParams parameters)
{
if (parameters.ResourceType == ResourceType.XHR)
{
Debug.WriteLine("Intercepted AJAX request: " + parameters.URL);
ajaxUrls.Add(parameters.URL);
}
return true;
}
}
private class AjaxNetworkDelegate : DefaultNetworkDelegate
{
public override void OnDataReceived(DataReceivedParams parameters)
{
if (ajaxUrls.Contains(parameters.Url))
{
Debug.WriteLine("Captured response for: " + parameters.Url);
Debug.WriteLine("MimeType = " + parameters.MimeType);
Debug.WriteLine("Charset = " + parameters.Charset);
PrintResponseData(parameters.Data);
}
}
private void PrintResponseData(byte[] data)
{
Debug.WriteLine("Data = ");
var str = Encoding.UTF8.GetString(data);
Debug.WriteLine(str);
}
}
}
}
Related
I need to use another company's API to query data using POST requests.
The API works (= I receive all the data with no errors) when I query it from the swagger website using the UI, but when I do it from my C# program I get a 500 Internal Server Error.
Where should I be looking for the problem ? Is there a way to get a more detailed error message ?
Edit (added code) :
using System;
using System.Data.Entity;
using System.Data.Entity.Core.Mapping;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Infrastructure.Interception;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Runtime.Serialization;
using System.Text;
namespace credex_distribution_offers_to_interfaces
{
class Program
{
private const string jsonMediaType = "application/json";
static void Main()
{
FetchJSONAndInsertToDB();
}
private static bool FetchJSONAndInsertToDB()
{
var baseServiceUrl = new Uri("a valid url");
Root rootObject;
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(jsonMediaType));
try
{
string token = FetchToken(httpClient, baseServiceUrl);
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(token);
}
catch (Exception e)
{
return false;
}
try
{
rootObject = FetchDistributionLookupOffers(httpClient, baseServiceUrl, 29612, 29613, 29614, 29617, 29621);
}
catch (Exception e)
{
return false;
}
}
// database related stuff...
// ...
return true;
}
[DataContract]
public class MortgageForDistributionLookupInputDto
{
public int[] OfferNumbers { get; set; }
}
private static Root FetchDistributionLookupOffers(HttpClient aHttpClient, Uri aBaseServiceUrl, params int[] aOfferNumbers)
{
var input = new MortgageForDistributionLookupInputDto()
{
OfferNumbers = aOfferNumbers
};
var lookup = aHttpClient.PostAsync(new Uri(aBaseServiceUrl, "v1/MortgageDetails/InvestorLookupOffers"), PayloadFor(input)).Result;
if (lookup.StatusCode != HttpStatusCode.OK)
{
throw new Exception("Fetching investor lookup offers failed with HTTP status code '" + lookup.StatusCode + "' : " + lookup.ReasonPhrase + "}");
}
var obj = ValueFor<Root>(lookup.Content);
return obj;
}
private static HttpContent PayloadFor<T>(T aObject)
{
return new StringContent(aObject.SerializeJson(), Encoding.UTF8, jsonMediaType);
}
private static T ValueFor<T>(HttpContent aHttpContent)
{
//var content = aHttpContent.ReadAsStringAsync();
return aHttpContent.ReadAsStreamAsync().Result.DeSerializeJson<T>();
}
private static string FetchToken(HttpClient aHttpClient, Uri aBaseServiceUrl)
{
var login = new LoginRequest()
{
UserName = "some user name",
Password = "some password"
};
var authResult = aHttpClient.PostAsync(new Uri(aBaseServiceUrl, "api/Login"), PayloadFor(login)).Result;
if (authResult.StatusCode != HttpStatusCode.OK)
{
throw new Exception("Fetching authentication token failed. Reason : " + authResult.StatusCode + " -> " + authResult.ReasonPhrase);
}
return authResult.Content.ReadAsStringAsync().Result.Trim('"');
}
}
}
I want to load a local HTML file that is in my Xamarin.Forms project. The file name is index.html. I searched and found a lot of people talking about this but none of the answers worked for me. This is where I am right now. You can see the HTML file on the side.
Visual Studio Image #3
And this is my code for now
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
initBrowser();
}
public void initBrowser()
{
var source = new HtmlWebViewSource();
string url = DependencyService.Get<IBaseUrl>().Get();
string TempUrl = Path.Combine(url, "index.html");
source.BaseUrl = url;
string html;
try
{
using (var sr = new StreamReader(TempUrl))
{
html = sr.ReadToEnd();
source.Html = html;
}
browser.Source = source.Html;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
EDIT: My problem is that I am not able to access my index.html in the android asset folder
10-28 15:13:23.111 I/mono-stdout(13979): Could not find a part of the
path "/file:/android_asset/AboutAssets.txt". Could not find a part of
the path "/file:/android_asset/index.html".
EDIT 2: I found a way to solve my problem by just not trying to use HtmlWebViewSource. I just use the URI directly in the browser.Source
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace PreuveXamarin
{
public interface IBaseUrl { string Get(); }
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
initBrowser();
}
public void initBrowser()
{
string path = DependencyService.Get<IBaseUrl>().Get();
string url = Path.Combine(path, "index.html");
browser.Source = url;
}
}
}
I'm fairly new to .NET and c# and I'm working on a POC where I've run into an issue when a controller throws the error
System.InvalidOperation Exception {"Unable to resolve controller: TenantController"}
The Inner exception details are
No default Instance is registered and cannot be automatically determined for type 'GICS.Web.Managers.Interfaces.ITenantManager'
There is no configuration specified for GICS.Web.Managers.Interfaces.ITenantManager
1.) new TenantController(Default of ITenantManager, Default of IRemedyService)
2.) GICS.Web.Controllers.Api.TenantController
3.) Instance of GICS.Web.Controllers.Api.TenantController
4.) Container.GetInstance(GICS.Web.Controllers.Api.TenantController)
The TenantController looks as follows:
using System.Web.Mvc;
using GICS.Web.Controllers.Api.Abstracts;
using GICS.Web.Managers.Interfaces;
using GICS.Web.Services.Interfaces;
using System.Collections.Generic;
using GICS.Web.ViewModels.Tenant;
using GICS.Web.Models.Tenant;
namespace GICS.Web.Controllers.Api
{
[RoutePrefix("api/tenant")]
public class TenantController : BaseApiController
{
private readonly ITenantManager _tenantsManager;
private readonly IRemedyService _remedyService;
private string token;
public TenantController(ITenantManager tenantsManager, IRemedyService remedyService)
{
_tenantsManager = tenantsManager;
_remedyService = remedyService;
token = null;
}
[HttpGet, Route("{groupId}/{userName}")]
public JsonResult getTenants(string groupId, string UserName)
{
getToken(UserName);
JsonResult result = Json(null);
if (token != null)
{
var tenants = _tenantsManager.GetTenants(token, groupId);
List<TenantViewModel> tenantViewModelList = new List<TenantViewModel>();
foreach (Values x in tenants)
{
TenantViewModel model = new TenantViewModel(x, groupId);
tenantViewModelList.Add(model);
}
result = Json(tenantViewModelList);
}
return result;
}
}
The TenantManager interface is as follows:
using System.Collections.Generic;
using GICS.Web.Models.Tenant;
namespace GICS.Web.Managers.Interfaces
{
public interface ITenantManager
{
IEnumerable<Values> GetTenants(string token, string groupId);
}
}
And the Manager implementation is:
using GICS.Web.Managers.Abstracts;
using GICS.Web.Managers.Interfaces;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Configuration;
using System.Net;
using GICS.Web.Models.Tenant;
namespace GICS.Web.Managers
{
public class TentantManager : ManagerBase, ITenantManager
{
public IEnumerable<Models.Tenant.Values> GetTenants(string token, string groupId)
{
Tenant restEntries = null;
List<Models.Tenant.Values> tenantList = new List<Models.Tenant.Values>();
using (WebClient client = new WebClient())
{
client.Headers[HttpRequestHeader.Authorization] = token;
var baseURL = ConfigurationManager.AppSettings["RemedyBaseUrl"];
var apiPath = ConfigurationManager.AppSettings["RemedyAPIPath"];
string getURL = baseURL + apiPath + "ESN%3AAST%3ALogSysComp%5FASTPeople" + "?q=?q=%27PeopleGroup%20Form%20Entry%20ID%27%20%3D%20%22" + groupId + "%22&fields=values(Name)";
string getResponse = client.DownloadString(getURL);
restEntries = JsonConvert.DeserializeObject<Tenant>(getResponse);
foreach (Models.Tenant.Entry x in restEntries.entries)
{
tenantList.Add(x.values);
}
}
return tenantList;
}
}
}
I have other controllers in the project that follow the same approach and all are working except for this one. Anyone spot where I am going wrong here?
Thanks in advance.
I'm trying to do a webrequest from my C# Windows application to my website,
but the desired result is empty or null when called only from C# but not from website where it works as expected.
Before I do my request, I need to begin with a login request which works as expected and does indeed return the correct value.
IMPORTANT EDIT:
I tried to copypaste my PHP code in to my login.php file and it does work in C# and returns the correct count-value.
Is my HttpClient not properly configured maybe?
My PHP test code looks as following:
<?php
session_start();
if(!isset($_SESSION['user'])){ header("Location: index.php"); }
include_once 'dbconnect.php'; //contains $db
$sql = "SELECT * FROM myTable"; //contains two rows
$sql_res = mysqli_query($db, $sql);
$proxyCount = mysqli_num_rows($sql_res);
$echo "Count: ".$proxyCount;
?>
And my C# looks like this:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Net.Http;
using ModernHttpClient;
using Newtonsoft.Json;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void log(string str)
{
logbox.AppendText(str + Environment.NewLine);
}
private string host = "http://www.mywebsite.com/";
private HttpClient httpClient = new HttpClient(new NativeMessageHandler());
private async Task<string> request(string target, Dictionary<string, string> _parameters)
{
string uri = host + target;
using (HttpResponseMessage response = await httpClient.PostAsync(uri, new FormUrlEncodedContent(_parameters)))
return new StreamReader(await response.Content.ReadAsStreamAsync()).ReadToEnd();
}
private async void button1_Click(object sender, EventArgs e)
{
string loginResp = await request("login.php", new Dictionary<string, string> { { "username", "user" }, { "password", "password" } });
log(loginResp);
}
private async void button2_Click(object sender, EventArgs e)
{
string proxiesResp = await request("proxy/proxy.php", new Dictionary<string, string> { { "getAllProxyRequests", "" } });
//above returns "count: " in C#, but returns "count: 2" in webbrowser
log(proxiesResp);
}
}
}
Found the problem, it was human error.
I had the file dbconnect.php located one directory below where myProblem.php was located.
I had to change the line saying
include_once 'dbconnect.php';
to
include_once '../dbconnect.php';
I am trying to write a simple chat application with iOS and Android clients. I am following the tutorial here http://blogs.msdn.com/b/youssefm/archive/2012/07/17/building-real-time-web-apps-with-asp-net-webapi-and-websockets.aspx to use WebSockets. However, I need to be able to send messages to a single "Chatroom" rather than broadcast to all the users (in reality there will only ever be 2 users, me and the person I'm chatting with). Currently I am doing this:
using Microsoft.Web.WebSockets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
namespace ChatPractice.Controllers
{
public class ChatController : ApiController
{
public HttpResponseMessage Get(string username, int roomId)
{
HttpContext.Current.AcceptWebSocketRequest(new ChatWebSocketHandler(username, roomId));
return Request.CreateResponse(HttpStatusCode.SwitchingProtocols);
}
}
class ChatWebSocketHandler : WebSocketHandler
{
private static WebSocketCollection _chatClients = new WebSocketCollection();
private string _username;
private int _roomId;
public ChatWebSocketHandler(string username, int roomId)
{
_username = username;
_roomId = roomId;
}
public override void OnOpen()
{
_chatClients.Add(this);
}
public override void OnMessage(string message)
{
var room = _chatClients.Where(x => ((ChatWebSocketHandler)x)._roomId == _roomId);
message = _username + ": " + message;
foreach (var user in room)
user.Send(message);
//_chatClients.Broadcast(_username + ": " + message);
}
}
}
Is using linq to get the correct room here correct or is there a better way to get to it?
This is an example of a chat server using WebSockets: Chat application using Reactive Extennsions.
It uses another WebSocket framework, but the idea should be pretty much the same.
It's better to use SignalR. There's a lot of tutorials online.