How to custom message on browser when internet is not connected - c#

I want to show custom message when my web application is failed to connect to internet.
Currently when my internet connectivity fails then the browser shows "unable to connect" or "server not found". so I want to show my custom message on my page.
I have written this :
bool bb = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();
if (bb == true)
{
//custom message
}
else
//meesage
But still it is not working.
How can I show that?

I think you are expecting internet connectivity from browser, if so use navigator.onLine;
<script type="text/javascript">
var isOnline = navigator.onLine;
if (!isOnline)
alert("Your custom message for no internet connectivity!!!");
</script>

Periodically call from client to server, and if there is no answer or not expecting answer - show error message.
for web forms:
create handler with implemetation of ProcessRequest like this:
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
context.Response.Write("Ok");
}
for mvc:
create action with simple result like this:
public ActionResult CheckInternetConnection()
{
return Json("Ok");
}
of course, this request handlers should not require any authorization or another pretreatment
then create js timer and method for request
var maxTime = <your interval time>;
var timer;
//write own method for check request
function performRequest() {
var xhr = new XMLHttpRequest();
// reserve 1 sec for timeout function execution
// if we didn't - you can get a situation when
// simultaneously performing more than 1 request
xhr.timeout = maxTime - 1000;
xhr.ontimeout = function {
//waiting to long
alert('<your message>');
window.clearInterval(timer);
};
xhr.open('GET', '<url of your check connection handler>', true);
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState != 4)
return;
if (xhr.responseText !== 'OK') {
//Can't access to handler
alert('<your message>');
window.clearInterval(timer);
}
}
}
//after page load start request timer
document.onload += function () {
timer = window.setInterval(performRequest, maxTime);
}
I haven't debug this code.

Related

Open browser window on click

I am using botframework 3.9 and for some reasons I can't upgrade now. I would like to know if there is a way to open a new browser window where I can render a page or fire a JavaScript function. Here is how I am opening link:
await context.PostAsync(#"please [click here](http://www.example.com/)");
This does renders the link however, I wanna open a link in JavaScript window so I can close the window programmatically or if possible if I can fire some JavaScript function.
This is actually much easier than you think. If you have a look at the WebChat README you can see there are many ways WebChat can be customized. Pay particular attention to sample 11, which you can demo here. The body of that page looks like this:
<div id="webchat" role="main"></div>
<script>
(async function () {
// In this demo, we are using Direct Line token from MockBot.
// To talk to your bot, you should use the token exchanged using your Direct Line secret.
// You should never put the Direct Line secret in the browser or client app.
// https://learn.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-direct-line-3-0-authentication
const res = await fetch('https://webchat-mockbot.azurewebsites.net/directline/token', { method: 'POST' });
const { token } = await res.json();
// We are creating our own version of Redux store, which include middleware and optional initial state.
const store = window.WebChat.createStore(
{},
({ dispatch }) => next => action => {
if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
// After connected, we will send a message by dispatching a Redux action.
dispatch({ type: 'WEB_CHAT/SEND_MESSAGE', payload: { text: 'sample:backchannel' } });
} else if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY') {
// When receiving an activity of type "event" with name of "sample:backchannel", prompt it out.
const { activity } = action.payload;
if (activity.type === 'event' && activity.name === 'sample:backchannel') {
alert(JSON.stringify(activity, null, 2));
}
}
return next(action);
}
);
window.WebChat.renderWebChat({
directLine: window.WebChat.createDirectLine({ token }),
// We will use a custom version of Redux store, which we added middleware to handle backchannel messages.
store
}, document.getElementById('webchat'));
document.querySelector('#webchat > *').focus();
})().catch(err => console.error(err));
</script>
You can see in this sample that WebChat has been modified to respond to certain activities from the bot by opening a popup window using JavaScript's alert function. The modification is done by creating a store and then passing that store as an argument to renderWebChat.
Rather than opening an alert window, you want to open a window you can close. This could be achieved if you modify the store to look like this:
let windows = {};
const store = window.WebChat.createStore(
{},
({ dispatch }) => next => action => {
if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY') {
const { activity } = action.payload;
if (activity.type === 'event') {
let url = activity.value;
if (activity.name == 'open' && !windows[url]) {
windows[url] = window.open(url);
}
if (activity.name == 'close' && windows[url]) {
windows[url].close();
windows[url] = null;
}
}
}
return next(action);
}
);
You don't have to implement it this way, but I've implemented it so that when WebChat receives an event activity named open it will open a window and when it receives an event activity named close it will close a window. It even keeps track of multiple windows so you can choose which window to close.
I've set up a bot that sends open and close events when the user types "open [url]" or "close [url]". The bot code looks like this:
var connector = new ConnectorClient(new Uri(activity.ServiceUrl));
var text = activity.Text;
var words = text.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
var firstWord = words.FirstOrDefault().ToLower();
var secondWord = words.Length > 1 ? words[1] : "https://stackoverflow.com/";
Activity reply = null;
switch (firstWord)
{
case "open":
case "close":
reply = activity.CreateReply();
reply.Type = ActivityTypes.Event;
reply.Name = firstWord;
reply.Value = secondWord;
break;
default:
reply = activity.CreateReply("Try \"open ...\" or \"close ...\"");
break;
}
await connector.Conversations.SendToConversationAsync(reply);
Hopefully you can use this information and modify it to suit your needs.

Signal R Server Client "Access-Control-Allow-Origin" missing error

I'm trying out the Signal R and built a server dll (windows service library/c#) that runs as a Windows Services. I have build also a client application (asp.net web application) to communicate with the server.
But i'm getting always the error(Firefox) "Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8080/signalr/negotiate?clientProtocol=1.5&connectionData=%5B%5D&_=1482829095207. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)."
Chrome error "
Failed to load resource: the server responded with a status of 400 (Bad Request)"
XMLHttpRequest cannot load http://localhost:8080/signalr/negotiate?clientProtocol=1.5&connectionData=%5B%5D&_=1482830200155. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:50259' is therefore not allowed access. The response had HTTP status code 400.
Note: Edge and also IE gives me errors
I have read almost every post about this subject on Stackoverflow, but non of these solutions seems to work.
The code i'm using for the server side:
namespace SignalRService
{
public class StartupConfiguration
{
public void Configuration(IAppBuilder app)
{
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
EnableDetailedErrors = true,
EnableJSONP = true,
};
map.RunSignalR(hubConfiguration);
});
}
}
}
Services.cs
public void StartService()
{
LogMessage("SignalRService started", true);
Running = true;
WebApp.Start<StartupConfiguration>(ConfigurationManager.AppSettings["SignalRServerUrl"]);
}
EnvironmentSettings.config:
<add key="SignalRServerUrl" value="http://localhost:8080"/>
Hubs.cs
namespace SignalRService.Hubs
{
[HubName("TestHub")]
public class TestHub: Hub
{
public static Dictionary<string, List<HubClient>> clients = new Dictionary<string, List<HubClient>>();
[HubMethodName("Subscribe")]
public async Task Subscribe(string Id)
{...... }}
ClientSide (Javascript/Jquery)
var signalrHubConnection;
var signalrHubConnectionProxy;
var signalRServerUrl = "http://localhost:8080";
var currentTimeout;
var count = 0;
var startSignalRConnection = function () {
console.log("Start");
signalrHubConnection = $.hubConnection(signalRServerUrl);
console.log("Running");
signalrHubConnection.logging = true;
signalrHubConnectionProxy = signalrHubConnection.createHubProxy('TestHub');
console.log("--Subscribe starting");
signalrHubConnection.start()
.done(function () {
signalrHubConnectionProxy.invoke('Subscribe', Id.toString());
console.log("Subscribe ending");
})
.fail(function (test) {
if (count < 5) {
console.log(test.toString());
clearTimeout(currentTimeout);
currentTimeout = setTimeout(function () {
count++;
startSignalRConnection();
}, 300000); // retry after 5 minutes
}
}
);
signalrHubConnectionProxy.on('IncomingMessage',
function (message) {
console.log("Message = " + message.toString());
}
);
};
Test.aspx
<script src="https://code.jquery.com/jquery-3.1.1.min.js" type="text/javascript"></script>
<script src="http://ajax.aspnetcdn.com/ajax/signalr/jquery.signalr-2.2.1.min.js"></script>
Did I something wrong?
The error implied that the SignalR url is different from the requesting url (origin). So, SignalR is on localhost, but your main website (the site that holds the client side example) obviously is accessed using "localhost".
Maybe you're accessing it using an IP (eg http://127.0.0.1/) or your PC name (eg http://badassPC/), whereas they must match under the default SignalR setting. I am pretty certain it doesn't matter if the port is different, and also doesn't matter if they are on the same domain (eg www.mysite.com and signalr.mysite.com)
Note there is a workaround that I wouldn't recommend unless you really really know what you're doing as there is a quite serious security risk otherwise: https://www.asp.net/signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client#crossdomain

Send email from Xamarin.Forms app using Dependency Service

In my app, for debugging purposes and testing purposes I need to send an email.
How do I present the mail controller, when the class that sends it does not contain a definition for PresentViewController ? The class needs to fire off the email app after the user clicks "yes" from the alert which fires.
public async Task<bool> SendEmail(Exception ex)
{
var result = await SendNotificationToRequestSendingEmail();
if (result)
{
if (MFMailComposeViewController.CanSendMail)
{
mailController = new MFMailComposeViewController();
mailController.SetToRecipients(new string[] { "test#one.com", "test#two.com" });
mailController.SetSubject("Details");
mailController.SetMessageBody($"Message: {ex.Message}" +
$"Exception: {ex.ToString()}"
, false);
mailController.Finished += (object s, MFComposeResultEventArgs args) =>
{
Console.WriteLine(args.Result.ToString());
args.Controller.DismissViewController(true, null);
};
this.PresentViewController(mailController, true, null); //this line causes the error
}
}
return true;
}
How can I fix this problem or get around it? This is called from a Xamarin Forms page.
Please take a look at this answer:
Sending e-mail from Gmail in Xamarin.Forms app
besides that you can also do it with this NuGet package:
https://www.nuget.org/packages/Xam.Plugins.Messaging/

ASP.Net Asynchronous HTTP File Upload Handler

I'm trying to make a file upload handler in C# that is asynchronous and can provide updates on progress of the file through AJAX asynchronous requests. Basically if the request is a POST it loads some information into the session and then starts the upload, if the request was a GET it returns the current state of the upload (bytes uploaded, total bytes, etc). I'm not entire sure that it needs to be an asynchronous handler but the files could be quite large so I thought that would work best. For the base async handler I used something very similar to the handler in this MSDN article. I've posted below some key sections of my code below. The issue I'm having is that I don't receive any of the GET information back until the POST has completed. I will mention that in this example I am using jQuery for GET requests and BlueImp for posting the file.
The HTML and JavaScript
<input id="somefile" type="file" />
$(function () {
name = 'MyUniqueId130';
var int = null;
$('#somefile').fileupload({
url: '/fileupload.axd?key='+name,
done: function (e, data) { clearInterval(int); }
});
$('#somefile').ajaxStart(function(){
int = setInterval(function(){
$.ajax({
url: '/fileupload.axd?key='+name,
dataType: 'json',
async: true
})
.done(function(e1, data1){
if(!e1.InProgress || e1.Complete || e1.Canceled)
clearInterval(int);
});
}, 10000)});
});
The Asynchronous Process Request Method just calls the correct method whether it's a POST or GET to one of the following then calls CompleteRequest to end the request:
private static void GetFilesStatuses(HttpContext context)
{
string key = context.Request.QueryString["key"];
//A dictionary of <string, UploadStatus> in the session
var Statuses = GetSessionStore(context);
UploadStatus ups;
if (!String.IsNullOrWhiteSpace(key))
{
if (Statuses.TryGetValue(key, out ups))
{
context.Response.StatusCode = (int)HttpStatusCode.OK;
context.Response.Write(CreateJson(ups));
}
else
{
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
}
}
else
{
context.Response.StatusCode = (int)HttpStatusCode.OK;
context.Response.Write(CreateJson(Statuses.Values));
}
}
private static void UploadFile(HttpContext context)
{
var Statuses = GetSessionStore(context);
string key = context.Request.QueryString["key"];
if (String.IsNullOrWhiteSpace(key))
{
context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
return;
}
HttpPostedFile file = context.Request.Files[0];
string extn = file.FileName.LastIndexOf('.') == -1 ? "" :
file.FileName.Substring(file.FileName.LastIndexOf('.'), (file.FileName.Length - file.FileName.LastIndexOf('.')));
string temp = GetTempFileName(path, extn);
UploadStatus status = new UploadStatus()
{
FileName = file.FileName,
TempFileName = temp,
Path = path,
Complete = false,
Canceled = false,
InProgress = false,
Success = true,
BytesLoaded = 0,
TotalBytes = file.ContentLength
};
Statuses.Add(key, status);
byte[] buffer = new byte[bufferSize];
int byteCount = 0;
using (var fStream = System.IO.File.OpenWrite(context.Request.MapPath(path + temp)))
{
uploads.Add(status);
while ((byteCount = file.InputStream.Read(buffer, 0, bufferSize)) > 0 && !status.Canceled)
{
status.InProgress = true;
status.BytesLoaded += byteCount;
fStream.Write(buffer, 0, byteCount);
}
status.Complete = !status.Canceled;
status.InProgress = false;
status.Success = true;
if (status.Canceled)
{
Statuses.Remove(temp);
}
context.Response.StatusCode = (int)HttpStatusCode.OK;
}
}
I've tried many things such as non-async handlers, async handlers, making sure the JavaScript is runnning async, but at this point I think I need some different eyes on the problem so thank you for any assistance anyone can provide.
I assume you're using the default ASP.Net Session manager and I see that you call GetSessionStore to get your session. Unfortunately the default Session manager serializes all requests when a call requires write access to the Session Store. This StackOverflow question and this MSDN arcle on Session State have some very useful information on Session State and it's locking behaviors.
Now, To take care of your problem, you're going to have to do a couple things which depend on whether you're using MVC controllers or if you're writing a custom IHttpHandler.
If you're writing your own IHttpHandler, make sure you do not have the IRequiresSessionState or IReadOnlySessionState interfaces added to your handler. In doing so, the pipeline will skip looking for a session and go straight to processing. context.Session will be null in this situation.
If you're using MVC to process the request, you'll need to decorate your controller class with the SessionState attribute passing in the SessionStateBehavior of SessionStateBehavior.Disabled.
In either case you won't be able to rely on the Session object to store your upload statuses. You can create a static ConcurrentDictionary keyed off of their SessionID (which you'll either need to pass in the upload query string or read the cookie yourself, calling Session.SessionId will just block you again) and store your upload statuses in there (which look like they're Concurrent* as well).
Another option would be to replace the SessionStateProvider with your own custom provider but that might be overkill in this situation.

Response.Redirect() doesn't work .net 4.0

On the button click I am calling a javascript function in the JS function I redirect to an aspx page and in the aspx page I want to redirect to another page (This part is not working).
response.redirect not re-directing, just posting back to current page. Any Idea why it is not working.
Here is my code :
Review.aspx:
<asp:Button ID="btnComplt" runat="server" Text="Complete" OnClientClick ="return compAsgn()" />
function compAsgn() {
if (window.confirm("Submit all images and complete the assignment?"))
window.location = "SendImages.aspx?insid=" + $("#IAssignmentId").val() + '&option=complete';
else
return false;
SendImages.aspx :
protected void Page_Load(object sender, EventArgs e)
{
assignmentId = Convert.ToInt32(Request.QueryString["insid"]);
string url = "Review.aspx?insid" + assignmentId.ToString() + "&viewOption=review";
string qstrVal = string.Empty;
qstrVal = Request.QueryString["option"].ToString().ToLower();
if (qstrVal != null && qstrVal == "complete")
{
using (ServiceClient client = new Proxies.ServiceRef.ServiceClient())
{
List<AssignmentInfo> ainfo = new List<AssignmentInfo>();
ainfo = client.GetAssignmentInfo(assignmentId);
if (ainfo.Count > 0)
{
if (ainfo[0].UploadedCount == 0)
{
// AfarSessionData class has a property called ProfileId, which is session variable.
if (AfarSessionData.ProfileId == "000000")
url = "Admin.aspx";
else
url = "HomePage.aspx";
}
}
}
}
Response.Redirect(url, false);
}
Note : When I debug I do see the control hitting the SendImages page but I see response.redirect not re-directing, just posting back to current page.
As far as I can tell, you're not doing anything to end the request. I'm not an ASP.NET guy, but I thought you should either:
Make the second argument true to effectively "hard abort" the request with an exception
Make the second argument false, but then call CompleteRequest to stop the rest of the pipeline
Some additional info related to John Skeets answer:
//ends request, no exception, calls Response.End() internally
Response.Redirect (url, true);
or
try
{
Response.Redirect (url, false);
}
catch(ThreadAbortException e)
{
//do whatever you need to
}
Here is some info on the issue:
PRB: ThreadAbortException Occurs If You Use Response.End, Response.Redirect, or Server.Transfer

Categories