How to call a controller action method again and again in mvc - c#

I am not that much efficient in mvc. I want to continuously try pinging the IPs in the list and then render the data in Index view using Viewbag. but problem here is I have to refresh the page manually each and every time to get the current status of each and every IP.
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
List<string> IPlist = new List<string>();
IPlist.Add("10.0.1.151");
IPlist.Add("www.google.com");
IPlist.Add("192.168.0.1");
Ping myping = new Ping();
StringBuilder sc = new StringBuilder("Ping Status:");
foreach (string c in IPlist)
{
PingReply replytest = myping.Send(c, 1000);
if (replytest != null)
{
sc.Append(" Status : " + replytest.Status + " \n Time: " + replytest.RoundtripTime.ToString() + " \n Address : " + replytest.Address + " \n ");
}
else
{
sc.Append("Request Failed");
}
}
ViewBag.result = sc.ToString();
return View();
}
}

Add new action which return a JsonResult from a controller to the ajax query. Simply convert the string to JsonResult by using Json(stringvalue);
public class HomeController : Controller
{
public JsonResult GetCurrentStatus()
{
List<string> IPlist = new List<string>();
IPlist.Add("10.0.1.151");
IPlist.Add("www.google.com");
IPlist.Add("192.168.0.1");
Ping myping = new Ping();
StringBuilder sc = new StringBuilder("Ping Status:");
foreach (string c in IPlist)
{
PingReply replytest = myping.Send(c, 1000);
if (replytest != null)
{
sc.Append(" Status : " + replytest.Status + " \n Time: " + replytest.RoundtripTime.ToString() + " \n Address : " + replytest.Address + " \n ");
}
else
{
sc.Append("Request Failed");
}
}
return Json(sc.ToString());
}
}
Add javascript function which call new action. And call this function every 5000 milliseconds with setInterval. On success of ajax I am setting retrieved value to
element with id divPintStatus. You can change it as per your actual code. Also set #Url.Action as your own code.
setInterval(getCurrentStatus, 5000);
function getCurrentStatus() {
$.ajax({
url: '#Url.Action("GetCurrentStatus")', // Or '#Url.Action("GetCurrentStatus", "ControllerName")',
type: "GET",
dataType: "json",
processData: false,
contentType: false,
success: function (data) {
$('#divPintStatus').val(data);
}
});
}

Related

How to pass docx file from Controller into View using AJAX?

Hi Stack Overflow community, first post, work your magic!
The problem I'm having is that I can generate my docx file, but when I try to return it the data is coming back in a format that I've never seen before? Does anyone know what this is?
Screenshot of unidentifiable code - it looks like Wingdings
Starting with the razor view
//Start action
$('#returnDeductionSheets').click(function () {
//Retrieve date options for user to select
$.ajax({
async: true,
type: 'POST',
url: 'ReturnDeductionsSheetList',
success: function (data) {
if (data != null) {
var options = data;
//Format JSON dates into read-able date time format
function formatDate(options) {
var dateString = options.substring(6);
var currentTime = new Date(parseInt(dateString));
var month = currentTime.getMonth() + 1;
var day = currentTime.getDate();
var year = currentTime.getFullYear();
var date = day + "/" + month + "/" + year;
return date;
};
//Check if I have more than one date, then return the options via a Bootbox view
if (options.length > 1) {
bootbox.prompt({
title: "Select the Deductions Sheet you would like to print.",
inputType: 'checkbox',
inputOptions: [
{
text: 'Deductions commenced on ' + formatDate(options[3]),
value: options[2],
},
{
text: 'Deductions commenced on ' + formatDate(options[1]),
value: options[0],
}
],
callback: function (result) {
//Pass the selected option into another AJAX method to generate the document else return to the view
if (result != null) {
$.ajax({
type: 'POST',
url: '#Url.Action("DeductionsSheet", "Home")?result=' + result,
contentType: 'application/json; charset=utf-8',
success: function (data) {
if (data.fileName != "") {
//window.location = "#Url.RouteUrl(new { Controller = "Home", Action = "Download" })/?file=" + data.fileName;
window.location = '/Home/ContractSpecificDocuments?file=' + data.fileName;
}
}
});
} else {
return;
};
}
});
}
else {
I'm happy that the Bootbox code works and the value that is passed into the DeductionsSheet ActionResult in the controller so I will jump to this code.
DeductionsSheet method (top of the method)
The value comes into the method as an array which I get through the [0] index.
public ActionResult DeductionsSheet(List<object> result)
{
//BOILER PLATE CODE
/////////////////////////////////////////
XceedDeploymentLicense.SetLicense();
var dateStamp = DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss");
_replacePatterns = new Dictionary<string, string>();
int contractNumber = Convert.ToInt32(Request.Cookies["ContractNumber"].Value);
int contractContibutionHistoryId = Convert.ToInt32(result[0]);
The document is generated
DeductionsSheet method (bottom of the method)
document.SaveAs(DocumentOutputDirectory + #"\RMContributions_" + dateStamp + #".docx");
}
string fileName = "RMContributions_" + dateStamp + #".docx";
return File(new FileStream(DocumentOutputDirectory + #"\RMContributions_" + dateStamp + #".docx", FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose), "application/vnd.openxmlformats-officedocument.wordprocessingml.document", fileName);
The ActionResult finishes and returns back to the AJAX method, shown below here (same code as in Razor View block above).
success: function (data) {
if (data.fileName != "") {
//window.location = "#Url.RouteUrl(new { Controller = "Home", Action = "Download" })/?file=" + data.fileName;
window.location = '/Home/ContractSpecificDocuments?file=' + data.fileName;
}
}
I'm not sure if it's a data-type parse problem, or if something needs serializing, I'm open to all suggestions.
Now I'm not committed to this approach so if anyone can suggest an alternative as long as it works I'm happy. Ideally I would call the AJAX method and pass the data into the controller and then not return to the AJAX method, but I've not found a way of doing this.
I did try a simpler alternative whereby in the Bootbox callback I trigger the DeductionsSheet ActionResult using a jQuery trigger event but with this approach I couldn't get the data to pass into the controller.
Alternative approach using trigger event
callback: function (result) {
//Pass the selected option into another AJAX method to generate the document else return to the view
if (result != null) {
$('#deductionsSheet').trigger('click', [result]);
} else {
return;
};
}
Thanks for your help.

How to call method using jQuery in mvc razor page at 10 sec interval and append output to html

Below code read messages from iot hub one by one as it comes.
private async void MonitorEventHubAsync(DateTime startTime, CancellationToken ct, string consumerGroupName)
{
EventHubClient eventHubClient = null;
EventHubReceiver eventHubReceiver = null;
try
{
string mesageData = string.Empty;
int eventHubPartitionsCount;
string selectedDevice = "";
eventHubClient = EventHubClient.CreateFromConnectionString("activeIoTHubConnectionString", "messages/events");
mesageData = "Receiving events...\r\n";
eventHubPartitionsCount = eventHubClient.GetRuntimeInformation().PartitionCount;
string partition = EventHubPartitionKeyResolver.ResolveToPartition(selectedDevice, eventHubPartitionsCount);
eventHubReceiver = eventHubClient.GetConsumerGroup(consumerGroupName).CreateReceiver(partition, startTime);
//receive the events from startTime until current time in a single call and process them
while (true)
{
var eventData = eventHubReceiver.ReceiveAsync(TimeSpan.FromSeconds(1)).Result;
if (eventData != null)
{
var data = Encoding.UTF8.GetString(eventData.GetBytes());
var enqueuedTime = eventData.EnqueuedTimeUtc.ToLocalTime();
var connectionDeviceId = eventData.SystemProperties["iothub-connection-device-id"].ToString();
if (string.CompareOrdinal(selectedDevice.ToUpper(), connectionDeviceId.ToUpper()) == 0)
{
mesageData += $"{enqueuedTime}> Device: [{connectionDeviceId}], Data:[{data}]";
if (eventData.Properties.Count > 0)
{
mesageData += "Properties:\r\n";
foreach (var property in eventData.Properties)
{
mesageData += $"'{property.Key}': '{property.Value}'\r\n";
}
}
mesageData += "\r\n";
}
}
}
}
catch (Exception ex)
{
}
}
I want to show messages one by one on mvc cshtml page using above code, how can I do that ?
One approach I can use like below:
In cshtml
<p id="pValue"></p>
In script
var someRootPath = "#Url.Content("~")";
(function randomGenerator() {
$.ajax({
url: someRootPath + 'Home/GetValue',
success: function (data) {
$('#pValue').html(data.someValue);
},
complete: function () {
setTimeout(randomGenerator, 1000);
}
});
})();
Controller
[HttpGet]
public JsonResult GetValue()
{
return Json( // call winform method which gives message data);
}
Something like this
var someRootPath = "#Url.Content("~")";
$(function(){
randomGenerator();
setTimeout(randomGenerator, 1000);
});
function randomGenerator() {
$.ajax({
url: someRootPath + 'Home/GetValue',
success: function (data) {
$('#pValue').html(data.someValue);
}
});
}

invoke api from ajax asp.net

I have a web Api that allow me to add a multiple Image with with another parameter
(place_Id , is_Main)
I use this code bellow to upload the image
[Route("api/Image")]
[HttpPost]
public async Task<IHttpActionResult> PostImage()
{
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = HttpContext.Current.Server.MapPath("~/Images/Places");
var provider = new CustomMultipartFormDataStreamProvider(root);
try
{
// Read the form data.
var task = await Request.Content.ReadAsMultipartAsync(provider).ContinueWith<IEnumerable<FileDesc>>(t =>
{
if (t.IsFaulted || t.IsCanceled)
{
throw new HttpResponseException(HttpStatusCode.InternalServerError);
}
var fileInfo = provider.FileData.Select(d =>
{
var info = new FileInfo(d.LocalFileName);
//return new FileDesc(info.Name);
return new FileDesc(info.Name);
});
return fileInfo;
});
int placeId = int.Parse(provider.FormData["placeId"]);
bool isMain = Convert.ToBoolean(provider.FormData["isMain"]);
var listOfAttchments = task.ToList();
string attachmentsPath = Request.RequestUri.Scheme +
System.Uri.SchemeDelimiter +
Request.RequestUri.Host +
(Request.RequestUri.IsDefaultPort ? "" : ":" + Request.RequestUri.Port) +
"/Images/Places/";
Images i = new Images();
if (listOfAttchments.Count > 0)
{
foreach (var item in listOfAttchments)
{
i.FileLocation = item.name;
i.FromUser = true;
i.TableName = "Places";
i.IsMain = isMain;
i.TableId = placeId;
db.Images.Add(i);
}
}
await db.SaveChangesAsync();
return Ok(new
{
result = true,
listAttachmment = listOfAttchments
}
);
}
catch (System.Exception e)
{
return BadRequest(e.StackTrace + "\nTest" + e.Data + "\nTest" + e.InnerException + "\nTest" + e.Message + "\nTest" + e.Source + "\nTest" + e.TargetSite);
}
}
The previous api is in another domain,
and I have a web forms application , that want to upload image from it, using the previous api
var data = new FormData();
jQuery.each(jQuery('#file')[0].files, function (i, file) {
data.append(" placeId: 7, isMain: 1");
data.append('image1' + i, file);
});
$("#btn2").click(function () {
jQuery.ajax({
url: '{url}/api/api/Image',
data: data,
contentType: false,
processData: false,
method: 'POST',
type: 'POST', // For jQuery < 1.9
success: function (data) {
alert(data);
}
});
});
I used the above code to invoke it, but I have a problem,
can you help me
Please ensure that you are not receiving XSS Error message (normally other domains are configured that you will not be able to trigger calls from a different domain addresses).
In the below code, i am not sure why do you have /api/api
url: '{url}/api/api/Image',
Please post us the error message you are receiving

New Session is created for ajax call once deployed. But not on dev project why is this?

I've been on the hunt for a solution for an issue that I discovered whilst trying to deploy a project Ive been working on.
Everything works fine on the development test visual studio build but when i upload it to my iis 7 server and Ajax call that i have seems to have no session(they are null). I use the session to store my user. Ill past my code below can anyone see anything wrong with it?
public JsonResult matchMaker(string request)
{
try
{
getCurrentUser();
}
catch
{
Response.StatusCode = 500;
return null;
}
// nothing needed below cut it out as note relevant.
}
private void getCurrentUser()
{
// debug this
HttpSessionStateBase a = Session;
if (currentUser == null)
{
try
{
// If a noUserInSessionEx is throw it will redirect them to login gracefully - Should also log why
if (Session["CurrentUser"] != null)
{
currentUser = (UserModel)Session["CurrentUser"];
}
else
{
throw new noUserInSession("No user for current session");
}
}
catch
{
Response.Redirect("login");
}
}
}
On my index page where the above method is being called via javascript i have
public ActionResult Index()
{
Response.Write("Session variables: <br>") ;
for( var i=0 ; i <Session.Contents.Count ; i++){
Response.Write(Session.Contents[i].ToString() + "<br>");
}
getCurrentUser();
Response.Write(currentUser.Email);
return View();
}
Javascript is as below
function executeAJAXRequest(datain, url) {
returnObj = false;
if (url != "" && datain != "") {
var request = $.ajax({
type: "POST",
async: false,
cache:false,
url: "http://localhost:51525/ajaxRequest/" + url,
//contentType: "application/json; charset=utf-8",
dataType: "json",
data: "request=" + JSON.stringify(datain)
})
request.done(function (e) {
//console.log("Sucessful Ajax:" + datain + " TO: " + url + "\n ResponseJSON: " + arguments[2].responseText);
returnObj = eval(arguments[0]);
});
request.fail(function (textStatus) {
console.log("Failure 2 Ajax (:()\n\n Data: " + datain
+ "\n TO: " + url +
"\n ERROR: " + textStatus.statusText);
returnObj = false;
});
return returnObj;
}
else {
console.log("Failure 2 Ajax (:() No Info");
return returnObj;
}
}
It shows me that correct user is stored and displays the email
How ever my ajax is responding with the redirect to the login page.
The session has a different id to the ajax session.
Im so lost :S any help would be mega awesomeo :)
Ok so turns out the only issue I was having was I didn't have http:// in front of my address for ajax. This cause a new session to be created. Apparently not an issue when using local host thanks for the help Sergey :)

How to receive and save the data sent from client side (J-query using Ajax) to server side (ASP.net C#)?

I am trying to sent a JSON format from Client side JQuery using Ajax to ASP.net (C# code behind) and save the data. however i haven't been able to do so. I dont have much knowledge on how to handle client side request in Server-side.
Thanks in advance!
my code is as follow:
Client Side:
$.ajax(
{
type: "POST",
url: "Default.aspx/save",
data: "{'data': " + JSON.stringify(prj) + "}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
if (response.ok) {
prof.stop();
if (response.data) {
ge.loadProject(response.data);
} else {
ge.reset();
}
} else {
var errMsg = "Errors saving project\n\n";
if (response.message) {
errMsg = errMsg + response.message + "\n";
}
if (response.errorMessages.length) {
errMsg += response.errorMessages.join("\n");
}
alert(errMsg);
}
}
});
I'm not really familiar with handling JSON in code-behind so i have tried some approaches and I've got errors
code behind in C# :
[WebMethod]
public static string save (object data)
{
//String s1 = data.ToString();
//Dictionary<string, object> tmp = (Dictionary<string, object>)data;
//DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(string));
//MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(data));
//string obj = (string)ser.ReadObject(ms);
string s2 = data.ToString();
GC.GClass g = new GC.GClass();
g.Save(s2);
return s2;
}
GC.GClass code to save the data as in a file:
namespace GC
{
public class GClass
{
string fileLoc = #"c:\Users\Pouria\Desktop\sample1.txt";
public GClass()
{
}
public void Save(string data)
{
FileStream fs = null;
if (!File.Exists(fileLoc))
{
using (fs = File.Create(fileLoc))
{
}
if (File.Exists(fileLoc))
{
using (StreamWriter sw = new StreamWriter(fileLoc))
{
sw.Write(data);
}
}
}
}
}
}
and in my file in my response and my sample1.txt i get this as output:
System.Collections.Generic.Dictionary`2[System.String,System.Object]
I couldn't upload images of FireBug but these is the response tab message:
{"d":"System.Collections.Generic.Dictionary`2[System.String,System.Object]"}
and JSON tab:
"System.Collections.Generic.Dictionary`2[System.String,System.Object]"
First thing is that, you have to create a WebService1.asmx file in project. After creating the file create a method in WebService1.asmx file.
[WebMethod]
public static string save (object data)
{
//String s1 = data.ToString();
//Dictionary<string, object> tmp = (Dictionary<string, object>)data;
//DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(string));
//MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(data));
//string obj = (string)ser.ReadObject(ms);
string s2 = data.ToString();
GC.GClass g = new GC.GClass();
g.Save(s2);
return s2;
}
Script
$.ajax(
{
type: "POST",
url: "WebService1.asmx/save",
data: "{'data': " + JSON.stringify(prj) + "}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
if (response.ok) {
prof.stop();
if (response.data) {
ge.loadProject(response.data);
} else {
ge.reset();
}
} else {
var errMsg = "Errors saving project\n\n";
if (response.message) {
errMsg = errMsg + response.message + "\n";
}
if (response.errorMessages.length) {
errMsg += response.errorMessages.join("\n");
}
alert(errMsg);
}
}
});
Set a break point on Save method and run it. I think by using this you can solve your problem.

Categories