can't receive data from post call in my controller - asp.net-mvc

I have a html editor and I am trying to send the data via post call. I can see the data in javascript and it hits SendEmail method but in my controller request is empty. Why can't see the data in my controller?
function SelectedReceipientsViewModel() {
var self = this;
self.packageDataForEmail = function () {
var request= tinymce.get("mailTextArea").getContent();
return request;
};
self.submit = function () {
var request = self.packageDataForEmail();
$.post("SendEmail",request, function () {
}).done(function () {
}).fail(function () {
});
};
}
my controller:
[HttpPost]
public void SendEmail(string request)
{
string message = request;
......
...
}

I created DtoEblast and add my property inside. for some reason string did not work. anyways this is working code.
self.packageDataForEmail = function () {
var Request = function (tinymceText) {
this.TinymceText = tinymceText;
};
var tinymceText = tinymce.get("mailTextArea").getContent();
var request = new Request(tinymceText);
return request;
};
[HttpPost]
public void SendEmail(DtoEblast request)
{
string message = request.TinymceText;
and it was giving 500 error without this line
<script>tinymce.init({forced_root_block : "",selector:'textarea'});</script>

Related

MVC SignalR not firing from Controller Post Method

When Saving schedule to calendar it must auto update the activity logs on my notification bar in my Home Controller. It saves the data but only show when notification bar is refreshed. It seems that Hub is not starting when saved.
CalendarController.cs
[HttpPost]
public JsonResult SaveSchedule(Schedule s)
{
var userid = User.Identity.GetUserId();
var profile = _context.Profiles.Single(p => p.Id == userid);
var status = false;
if (s.Schedule_ID > 0)
{
//Update
var v = _context.Schedules.Where(a => a.Schedule_ID == s.Schedule_ID).FirstOrDefault();
if (v != null)
{
v.Shift = s.Shift;
}
}
var activitylog = new ActivityLog
{
UserId = userid,
LogDate = DateTime.Now,
Activity = ActivityHelper.GetActivityLog(4, profile.FirstName)
};
// save to data and must be shown on notification bar
_context.ActivityLogs.Add(activitylog);
_context.SaveChanges();
ActivityHub.StartLogging();
status = true;
return new JsonResult { Data = new { status = status } };
}
HomeController.cs
public JsonResult GetLogs()
{
return Json(ActivityHelper.GetActivityLogs(), JsonRequestBehavior.AllowGet);
}
ActivityHub.cs
public class ActivityHub : Hub
{
public static void StartLogging()
{
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<ActivityHub>();
//calls the signalR client part to execute javascript method
context.Clients.All.displayLog();
}
}
My CSHTML
<script>
$(function () {
var activityFromHub = $.connection.activityHub;
$.connection.hub.start().done(function () {
FetchLogs();
});
activityFromHub.client.displayLog = function () {
console.log('Hub Started');
FetchLogs();
}
function FetchLogs() {
$.ajax({
type: 'GET',
url: '/Home/GetLogs',
datatype: 'json',
success: function (data) {
$("#logs tr").remove();
data = $.parseJSON(data);
if (data.length > 0) {
.... do some append here
}
},
error: function (error) {
alert("error");
}
});
}
});
</script>
ActivityHelper.cs
static readonly string connString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
public static class ActivityHelper
{
public static string GetActivityLogs()
{
string sqlCommand = #"my select query here";
try
{
var messages = new List<ActivityLog>();
using(var connection = new SqlConnection(connString))
{
connection.Open();
using (SqlConnection con = new SqlConnection(connString))
{
SqlCommand cmd = new SqlCommand(sqlCommand, con);
if(con.State != System.Data.ConnectionState.Open)
{
con.Open();
}
cmd.Notification = null;
SqlDependency dependency = new SqlDependency(cmd);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
var reader = cmd.ExecuteReader();
while (reader.Read())
{
messages.Add(item: new ActivityLog
{
Activity = reader["Activity"] != DBNull.Value ? (string)reader["Activity"] : "",
LogDate = (DateTime)reader["LogDate"]
});
}
}
}
var jsonSerialiser = new JavaScriptSerializer();
var json = jsonSerialiser.Serialize(messages);
return json;
}
catch(Exception ex)
{
throw;
}
}
public static void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
if (e.Type == SqlNotificationType.Change)
{
SqlDependency dependency = sender as SqlDependency;
dependency.OnChange -= dependency_OnChange;
var activityHub = GlobalHost.ConnectionManager.GetHubContext<ActivityHub>();
GetActivityLogs();
}
}
}
FIRST METHOD
First Solution change your javascript code like this. If this not works move to the second method:
$(function () {
var activityFromHub = $.connection.ActivityHub;
$.connection.hub.start().done(function () {
FetchLogs();
});
activityFromHub.client.displayLog = function () {
console.log('Hub Started');
FetchLogs();
}
});
SECOND METHOD:
Each client connecting to a hub passes a unique connection id. You can retrieve this value in the Context.ConnectionId property of the hub context. And i found there is nothing happening like this. You may try this solution.
I think the simplest solution for your question is to use groups.
http://www.asp.net/signalr/overview/guide-to-the-api/working-with-groups
Your hub class would contain methods to join a group:
public Task JoinGroup(string groupName)
{
return Groups.Add(Context.ConnectionId, groupName);
}
public Task LeaveGroup(string groupName)
{
return Groups.Remove(Context.ConnectionId, groupName);
}
and your hub will be look like this:
public static void StartLogging(string groupName)
{
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<ActivityHub>();
context.Clients.Group(groupName).displayLog();
//calls the signalR client part to execute javascript method
//context.Clients.All.displayLog();
}
And change your javascript as like this:
$(function () {
var activityFromHub = $.connection.ActivityHub;
$.connection.hub.start().done(function () {
activityFromHub.server.joinGroup("Group1");
activityFromHub.server.StartLogging("Group1");
FetchLogs();
});
activityFromHub.client.displayLog = function () {
console.log('Hub Started');
FetchLogs();
}
});
I hope this will resolve your issue. If you are still facing issue. Please leave comments. Thank you.

Model Id passed through to Angular Ctrl

I have a MVV view that used the Controller below, I need to get the product Id, ie Model.Id through to the controller somehow.
I have tried the $scope.init but it is coming through as null when I am making the first Ajax call, I suspect that this ajax get is kicking off before the init is fired and setting the product id, so the ajax fails as the productId is null when the call is made. I am new to angular so if its a schoolboy error I apologise !.
Controller and HTML are shown below.
angular.module('askQuestions', [])
.controller('questionController', function ($scope, $http) {
$scope.loading = true;
$scope.addMode = false;
$scope.replyMode = false;
$scope.parentClicked = 0;
$scope.init = function (productId) {
//This function is sort of private constructor for controller
$scope.productId = productId;
$scope.getUrl = '/Api/GetProductQuestions/' + $scope.productId;
};
//Used to display the data
//$http.get('/Api/GetAllManufacturers?apiToken=6a5ce02e-0506-0a41-2f50-37327080662f').success(function (data) {
$http.get($scope.getUrl).success(function (data) {
$scope.questions = data;
$scope.loading = false;
})
.error(function () {
$scope.error = "An Error has occured while loading questions!";
$scope.loading = false;
// alert($scope.getUrl);
});
});
<div data-ng-app data-ng-controller="questionController" ng-init="init('#Model.Id')" class="container">
Your $http.get is evaluated in the instantiation of the controller. The instantiation is before your init, so the ajax call is already being made. You can easily fix this by wrapping your $http.get also in a function:
$scope.init = function (productId) {
//This function is sort of private constructor for controller
$scope.productId = productId;
$scope.getUrl = '/Api/GetProductQuestions/' + $scope.productId;
getData();
};
var getData = function() {
$http.get($scope.getUrl)
.success(function (data) {
// success
$scope.questions = data;
})
.error(function () {
// error
$scope.error = "An Error has occured while loading questions!";
})
.finally(function () {
// always
$scope.loading = false;
});
}

How to Catch An Ajax error while using Jquery UI tabs along with Custom Error handler

I am using Jquery UI tabs in my asp.net mvc web application. I have my tabs working good.
But, the problem is when ever an ajax errors happens, it should be caught and JSON response should be thrown back.
I am using an CustomError handler over riding MVC HandleError Attribute as follows:
public class CustomHandleErrorAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
{
return;
}
if (new HttpException(null, filterContext.Exception).GetHttpCode() != 500)
{
return;
}
if (!ExceptionType.IsInstanceOfType(filterContext.Exception))
{
return;
}
// if the request is AJAX return JSON else view.
if (filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
filterContext.Result = new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new
{
error = true,
message = filterContext.Exception.Message
}
};
}
else
{
var controllerName = (string)filterContext.RouteData.Values["controller"];
var actionName = (string)filterContext.RouteData.Values["action"];
var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
filterContext.Result = new ViewResult
{
ViewName = View,
MasterName = Master,
ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
TempData = filterContext.Controller.TempData
};
}
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = 500;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
}
So, if the error occurs and it is an ajax request , then the above method will throw the JSON response.
But,I am struggling to find out how to catch that JSON respnse and show it on Client Side.
Please help..I tried using ajaxoptions with UI Tabs as follows:
$(document).ready(function () {
$('#tabs').tabs({
activate: function (event, ui) {
ui.oldPanel.empty();
},
ajaxOptions: { success: Success, error: Failure }
});
$('#tabs').css('display', 'block');
$(function () {
$(this).ajaxStart(function () {
$("#ajaxLoading").show();
});
$(this).ajaxStop(function () {
$("#ajaxLoading").hide();
});
});
});
function Success(data) {
alert("Successfully loaded the tabs");
}
function Failure() {
alert("Some thing wrong had happened");
}
please help..on how to recieve that erronoeous JSON response and show an appropraite alert to the end user..
I found the solution as this:
$.ajaxSetup({
type: "GET",
cache: false,
error: function (e) {
var Error = e.responseText;
var ErrorCode= xx;
alert("Sorry, An Error has been occured while processing your request " + Error);
}
});
I have used ajaxSetup() to receive the response from Server Side.
Hope this helps...

Angular with Breeze error Cannot call method of undefined

I'm testing sample CRUD using Angular and Breeze following sample ToDo project.
But for some reason I get error Cannot call method 'getAll' of undefined.
(my odata is hosted on another localhost server, and CORS is enabled, I've tested it)
Here is my code:
Main.js:
var app = {};
app.adminMuscleGroup = angular.module('WebApp', []);
DataService:
app.adminMuscleGroup.dataService = (function (breeze, logger) {
breeze.config.initializeAdapterInstances({ dataService: "OData" });
var servicename = 'http://localhost:23758/odata/';
var manager = new breeze.EntityManager(servicename);
manager.enableSaveQueuing(true);
var dataService = {
getAll: getAll,
};
return dataService;
function getAll() {
var query = breeze.EntityQuery.from("MuscleGroup").orderBy("Name");
return manager.executeQuery(query);
}
})(breeze, app.logger);
Controller:
app.adminMuscleGroup.controller('AdminMuscleGroupCtrl', function($scope) {
var dataService = window.app.dataService;
var logger = window.app.logger;
$scope.items = [];
$scope.getAllMuscleGroups = function () {
dataService.getAll()
.then(querySucceeded)
.fail(queryFailed);
};
$scope.getAllMuscleGroups();
function querySucceeded(data) {
$scope.items = [];
data.results.forEach(function (item) {
$scope.items.push(item);
});
$scope.apply();
logger.info("Fetched all Muscle Groups");
}
function queryFailed(error) {
logger.error(error.message, "Query failed");
}
}
And here is whole error:
ypeError: Cannot call method 'getAll' of undefined
at Object.$scope.getAllMuscleGroups (http://localhost:7122/Scripts/app/AdminMuscleGroup/MuscleGroupController.js:10:21)
at new <anonymous> (http://localhost:7122/Scripts/app/AdminMuscleGroup/MuscleGroupController.js:15:12)
at invoke (http://localhost:7122/Scripts/angular/angular.js:2902:28)
at Object.instantiate (http://localhost:7122/Scripts/angular/angular.js:2914:23)
at http://localhost:7122/Scripts/angular/angular.js:4805:24
at http://localhost:7122/Scripts/angular/angular.js:4384:17
at forEach (http://localhost:7122/Scripts/angular/angular.js:137:20)
at nodeLinkFn (http://localhost:7122/Scripts/angular/angular.js:4369:11)
at compositeLinkFn (http://localhost:7122/Scripts/angular/angular.js:4015:15)
at publicLinkFn (http://localhost:7122/Scripts/angular/angular.js:3920:30) angular.js:5754
(anonymous function)
Try to inject the dataService directly to the controller
app.adminMuscleGroup.controller('AdminMuscleGroupCtrl', function($scope, dataService) {
var dataService = window.app.dataService; // -> delete this
It was stupid mistake, I've changed this line:
var dataService = window.app.dataService;
into this:
var dataService = window.app.adminMuscleGroup.dataService;
Now it works

observableArray sent as parameter to a contoller function is null

I want to pass the data in the FeatureList (observableArray) to the SaveMappings function in the TreeController. I have binded a button to the sendItems function. I put a breakpoint at the var data=p2fData line to see what I received. p2fData is null.
I changed the controller to public JsonResult SaveMappings(List p2fData). In this case p2f data shows that there is 1 element, but then its null too.
var Feature = function (featId) {
var self = this;
self.featId = featId;
self.parameters = ko.observableArray();
}
var ParameterToFeatureListViewModel = function () {
var self = this;
var newFeature = new Feature("Feature XYZ");
newFeature.parameters.push("1");
newFeature.parameters.push("2");
self.FeatureList = ko.observableArray([newFeature]);
self.sendItems = function() {
$.ajax({
type: "POST",
url: '/Tree/SaveMappings',
data: ko.toJSON(self.FeatureList),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
alert(response);
},
error: function (request, status, error) {
alert(request.statusText);
}
});
}
}
var vm = new ParameterToFeatureListViewModel()
ko.applyBindings(vm);
public class TreeController:Controller
{
public ActionResult Index(){...}
[HttpPost]
public JsonResult SaveMappings(string p2fData)
{
var data = p2fData;
return Json(data);
}
}
Please have a look # how to pass knockoutjs view model into a mvc controller
... May be it helps..

Resources