I am having a modal popup to create event and i want to allow only login user to see that page, save event and fetch event all are using json, but when i am going back after logout, session value is still present and all actions are getting performed, until i donot refresh the page, i want that no action should happen and session value should be cleared when i logout
public ActionResult Index()
{
if(Session["UserID"]==null)
{
return RedirectToAction("Index2","Login");
}
else
{
TempData["usersession"] = Session["UserID"].ToString();
}
return View();
}
<label id="session">#TempData["usersession"]</label>
//Javascript and Json
$(document).ready(function () {
username = $('#session').text();
});
function SaveEvent(data) {
alert(username);
$.ajax({
type: "POST",
url: '/home/SaveEvent',
data: data,
success: function (data) {
if (data.status) {
//Refresh the calendar
fetchEvent();
$('#myModalSave').modal('hide');
//alert(username);
}
},
error: function () {
alert('failed');
}
});
While i am trying to alert username when i click on save it still showing the session value
have you tried this?
Session.Abandon(); // The Abandon method destroys all the objects stored in a Session object and releases their resources.
Session.Remove("YourItem"); //just removes current values
Session.Clear();// just removes all values
https://stackoverflow.com/a/5330288/7262120
public class VerifyUserAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var user = filterContext.HttpContext.Session["UserID"];
if (user == null)
filterContext.Result = new RedirectResult(string.Format("/User/Login?targetUrl={0}",filterContext.HttpContext.Request.Url.AbsolutePath));
}
}
[VerifyUserAttribute]
public ActionResult Index()
{
if(Session["UserID"]==null)
{
return RedirectToAction("Index2","Login");
}
else
{
TempData["usersession"] = Session["UserID"].ToString();
}
return View();
}
Related
in asp.net core I made a service to add new row and another one to update row. I call the service from the controller based on JS fetch request. now I need from the service response to return partialView and some Json like that
var data = { htmlContent : '<html table row >', mode : 'insert', isSuccessful : true }
// then when I get response from the controller
.then((data) => {
jsonObj.parse(date);
// ... some logic as follows
if (jsonObj.mode == 'create')
{
if (isSuccessful === 'true') {
// ... appendChild with [jsonObj.htmlContent]
} else {
// ... show modal with [jsonObj.htmlContent]
}
} else if (jsonObj.mode == 'update') {
if (isSuccessful === 'true') {
// ... insertInto (index) with [jsonObj.htmlContent]
} else {
// ... show modal with [jsonObj.htmlContent]
}
}
} else if (jsonObj.mode == 'delete') {
if (isSuccessful === 'true') {
// ... remove element with temp message [jsonObj.htmlContent]
} else {
// ... show modal with [jsonObj.htmlContent]
}
}
});
for the service I return response class like this
// service
public addNew()
{
try(){
_dbContext.add(...
var result = _dbContext.saveChanges();
// here is the question
// this is service not ActionResult
// I need to return here html content out of partialView
// along with some other Json data
return new response{htmlContent: partialView(''), mode: 'insert', isSuccessful: true};
}catch
{
return new response{htmlContent: '<h1>something went wrong !</h1>', mode: 'insert', isSuccessful: false};
}
}
public class Response
{
public Dynamic htmlContent { get; set; }
public bool isSuccessful { get; set; }
public Crud mode { get; set; }
}
public enum Crud () {
create, review, update, delete
}
in the controller I return to js the addNew result which is Response class
// after injection I use the service here
public IActionResult manage()
{
return _myService.addNew();
}
finally and again is possible to return partialView along with some Json data from the microservice like shown above
return new response{htmlContent: partialView(''), mode: 'insert', isSuccessful: true};
I think returning partialView is not allowed without IActionResult, however geeks absolutely know someway
A PartialView can only be interpreted and resolved to HTML by a razor view.
In your case, you are calling an API directly from Javascript so you have no razor component to interpret a PartialView response.
You either need to roll with the framework and use razor view or use javascript (or jQuery) to create the html that you want.
Simple usecase - get PartialView dynamically from AJAX call to update div in my main page after input select (dropdownlist) changed value.
Steps I took:
Created view (only, wihtout PageModel) with model declared with #model ViewModelCreateOperation.
Created checkbox on main page:
<select class="form-control" asp-items="#(new SelectList(Model.allExistingOperations))" onchange="PopulateForm(this.value); return false;"></select>
created scripts on main page:
<script>
function PopulateForm(value) {
var dataToPost = "{ operationName:" + value + "}";;
$.ajax({
type: "post",
url: '#Url.Content("/MeaningOfLifeRoutedName")',
data: dataToPost ,
contentType : 'application/json; charset=UTF-8',
success: function (data) {
$('#lubieplacki').html(data);
},
error: function (xhr, ajaxOptions, thrownError) {
if (xhr.status == 404) {
alert(thrownError);
}
}
});
}
</script>
created Controller in Controllers folder to return PartialView (becouse I cannot use "return PartialView("someview", someModel)" with PageModel already used as a inherit class.
namespace MyMysteriousApplication.Controllers
{
[Route("MeaningOfLifeRoutedName")]
public class MeaningOfLifeChangesController : Controller
{
private readonly MyMysteriousApplication.Models.TTSCDBContext _context;
public MeaningOfLifeChangesController(MyMysteriousApplication.Models.TTSCDBContext context)
{
_context = context;
}
public ViewModelCreateOperation viewModelCreateOperation { get; set; }
public IActionResult Index()
{
return RedirectToPage("../Index");
}
[HttpPost]
public ActionResult getMeaningOfLife(string operationName)
{
viewModelCreateOperation = new ViewModelCreateOperation();
viewModelCreateOperation = new ViewModelCreateOperation();
viewModelCreateOperation._entitiesSelectListItem = _context.Entities
.Select(a => new Microsoft.AspNetCore.Mvc.Rendering.SelectListItem()
{
Value = a.Id.ToString(),
Text = a.EntityName
}).OrderByDescending(u => u.Text)
.ToList();
viewModelCreateOperation.MeaningOfLifeChanges = _context.MeaningOfLifeChanges.Where(u => u.OperationName.Contains(operationName)).OrderBy(u => u.ChangeId).FirstOrDefault();
return PartialView("../projectManagement/partialViewCreateNewMOL", viewModelCreateOperation);
}
}
}
Primary question:
I got null in parameters - I don't get why:
Bonus question:
I couldn't invoke my controller in any way (tried "/MeaningOfLifeChangeController/getMeaningOfLife" or "/MeaningOfLifeChange/getMeaningOfLife", with "~/MeaningOfLifeChangeController/getMeaningOfLife" and others combinations), so I added [Route("MeaningOfLifeRoutedName")] and [HttpPost] before method. I don't get why...
in Startup I have added controllers to initialize (JSON is for other stuff(API)):
services.AddControllersWithViews().
AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
options.JsonSerializerOptions.PropertyNamingPolicy = null;
options.JsonSerializerOptions.MaxDepth = 150;
}).AddRazorRuntimeCompilation();
It's not my answer, but Jiadong Meng helped me in ASP .NET Forums. I'm posting His answer:
Since the data you want to send is just a string type data, you need to stringify it like below.
var dataToPost = JSON.stringify(value);
Then in your Action, you should also add [FromBody] attribute.
public ActionResult getMeaningOfLife([FromBody]string operationName)
I have been trying to pass an object as a Post parameter to .NET asmx web service. I can pass primitive types such as int, string as parameters but I would like to pass the whole object because my class contains a lot of properties and it is very time consuming to pass each property individually.
My c# web service code is:
[WebMethod(EnableSession = true)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public ContactBLL AddContact(ContactBLL Contact)
{
//add contact and return the contact object
}
I have added following statement at the top of the web service class:
[System.Web.Script.Services.ScriptService]
I have a second function in the web service which I call when my page loads in order to get a json ContactBLL object.
[WebMethod(EnableSession = true)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public ContactBLL GetContact(int ContactID)
{
//return contact
}
I use following functions in my factory to call asmx web methods:
factory.GetContactInfo = function (ContactID) {
return $http.post(serviceBase + 'GetContact', { ContactID: ContactID }).then(function (results) {
return results.data;
});
};
factory.InsertContact = function (Contact) {
return $http.post(serviceBase + 'AddContact', { ContactBLL: Contact }).then(function (results) {
return results.data;
});
};
In my controller, the GetContact function is called when the page loads and it returns the correct data to initialise the Contact object. I then call AddContact function and pass the object to factory function. The control doesn't get to the web service and I see the 500 message in chrome with the following message:
Message: "Invalid web service call, missing value for parameter: 'Contact'."
Here is the code for the controller:
var ContactController = function ($scope, $location, $http, $window, ContactService) {
var Contact;
Initialise();
function Initialise() {
Contact = {};
GetContact(-1);
}
function GetContact(ContactID) {
ContactService.GetContactInfo(ContactID)
.then(function (data) {
//do something
}, function (error) {
$window.alert('Sorry, an error occurred: ' + error.data.message);
});
}
$scope.AddContactRecord = function () {
ContactService.InsertContact(Contact)
.then(function (data) {
//do something
}, function (error) {
$window.alert('Sorry, an error occurred: ' + error.data.message);
});
}
}
Please let me know if I am doing anything wrong or an easy way for passing tens of properties via Post call. The GetContact call works fine, however, I get error on InsertContact call.
I have found the reason for the error. I was passing the datatype (ContactBLL) instead of the name (Contact) of the paramter in the AddContact function of my factory. The correct code is below:
factory.InsertContact = function (Contact) {
return $http.post(serviceBase + 'AddContact', { Contact: Contact }).then(function (results) {
return results.data;
});
};
I have a simple function that searches for item I want in my database and retrieves it in my controller.
[HttpPost]
public ActionResult Index(string searchString)
{
var user = from m in db.Users select m;
if (!String.IsNullOrEmpty(searchString))
{
user = user.Where(s => s.UserName.Contains(searchString));
}
return View(user);
}
And then in my Javascript I send a value to search:
$('#test').click(function(e) {
e.preventDefault();
var user = "John";
$.ajax({
url: "#Url.Action("Index", "Users")",
data { "searchString": user },
type: "post",
success: function (saveResult) {
console.log(saveResult);
},
error: function(xhr, ajaxOptions, thrownError) {
console.log(xhr, ajaxOptions, thrownError);
}
})
})
However of course all this does it return my view inside the console window which is something like:
But I would like to return a json object I can use.
just use the Json Action method.
return Json(user);
Edit:
As a side note, I would also set my return Type to be JsonResult for clarity
You just return as JsonResult such as below:
public ActionResult SomeActionMethod() {
return Json(new {foo="bar", baz="Blech"});
}
How do I handle exceptions thrown in a controller when jquery ajax calls an action?
For example, I would like a global javascript code that gets executed on any kind of server exception during an ajax call which displays the exception message if in debug mode or just a normal error message.
On the client side, I will call a function on the ajax error.
On the server side, Do I need to write a custom actionfilter?
If the server sends some status code different than 200, the error callback is executed:
$.ajax({
url: '/foo',
success: function(result) {
alert('yeap');
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert('oops, something bad happened');
}
});
and to register a global error handler you could use the $.ajaxSetup() method:
$.ajaxSetup({
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert('oops, something bad happened');
}
});
Another way is to use JSON. So you could write a custom action filter on the server which catches exception and transforms them into JSON response:
public class MyErrorHandlerAttribute : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
filterContext.ExceptionHandled = true;
filterContext.Result = new JsonResult
{
Data = new { success = false, error = filterContext.Exception.ToString() },
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
and then decorate your controller action with this attribute:
[MyErrorHandler]
public ActionResult Foo(string id)
{
if (string.IsNullOrEmpty(id))
{
throw new Exception("oh no");
}
return Json(new { success = true });
}
and finally invoke it:
$.getJSON('/home/foo', { id: null }, function (result) {
if (!result.success) {
alert(result.error);
} else {
// handle the success
}
});
After googling I write a simple Exception handing based on MVC Action Filter:
public class HandleExceptionAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.Exception != null)
{
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
filterContext.Result = new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new
{
filterContext.Exception.Message,
filterContext.Exception.StackTrace
}
};
filterContext.ExceptionHandled = true;
}
else
{
base.OnException(filterContext);
}
}
}
and write in global.ascx:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleExceptionAttribute());
}
and then write this script on the layout or Master page:
<script type="text/javascript">
$(document).ajaxError(function (e, jqxhr, settings, exception) {
e.stopPropagation();
if (jqxhr != null)
alert(jqxhr.responseText);
});
</script>
Finally you should turn on custom error.
and then enjoy it :)
Unfortunately, neither of answers are good for me. Surprisingly the solution is much simpler. Return from controller:
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, e.Response.ReasonPhrase);
And handle it as standard HTTP error on client as you like.
I did a quick solution because I was short of time and it worked ok. Although I think the better option is use an Exception Filter, maybe my solution can help in the case that a simple solution is needed.
I did the following. In the controller method I returned a JsonResult with a property "Success" inside the Data:
[HttpPut]
public JsonResult UpdateEmployeeConfig(EmployeConfig employeToSave)
{
if (!ModelState.IsValid)
{
return new JsonResult
{
Data = new { ErrorMessage = "Model is not valid", Success = false },
ContentEncoding = System.Text.Encoding.UTF8,
JsonRequestBehavior = JsonRequestBehavior.DenyGet
};
}
try
{
MyDbContext db = new MyDbContext();
db.Entry(employeToSave).State = EntityState.Modified;
db.SaveChanges();
DTO.EmployeConfig user = (DTO.EmployeConfig)Session["EmployeLoggin"];
if (employeToSave.Id == user.Id)
{
user.Company = employeToSave.Company;
user.Language = employeToSave.Language;
user.Money = employeToSave.Money;
user.CostCenter = employeToSave.CostCenter;
Session["EmployeLoggin"] = user;
}
}
catch (Exception ex)
{
return new JsonResult
{
Data = new { ErrorMessage = ex.Message, Success = false },
ContentEncoding = System.Text.Encoding.UTF8,
JsonRequestBehavior = JsonRequestBehavior.DenyGet
};
}
return new JsonResult() { Data = new { Success = true }, };
}
Later in the ajax call I just asked for this property to know if I had an exception:
$.ajax({
url: 'UpdateEmployeeConfig',
type: 'PUT',
data: JSON.stringify(EmployeConfig),
contentType: "application/json;charset=utf-8",
success: function (data) {
if (data.Success) {
//This is for the example. Please do something prettier for the user, :)
alert('All was really ok');
}
else {
alert('Oups.. we had errors: ' + data.ErrorMessage);
}
},
error: function (request, status, error) {
alert('oh, errors here. The call to the server is not working.')
}
});
Hope this helps. Happy code! :P
In agreement with aleho's response here's a complete example. It works like a charm and is super simple.
Controller code
[HttpGet]
public async Task<ActionResult> ChildItems()
{
var client = TranslationDataHttpClient.GetClient();
HttpResponseMessage response = await client.GetAsync("childItems);
if (response.IsSuccessStatusCode)
{
string content = response.Content.ReadAsStringAsync().Result;
List<WorkflowItem> parameters = JsonConvert.DeserializeObject<List<WorkflowItem>>(content);
return Json(content, JsonRequestBehavior.AllowGet);
}
else
{
return new HttpStatusCodeResult(response.StatusCode, response.ReasonPhrase);
}
}
}
Javascript code in the view
var url = '#Html.Raw(#Url.Action("ChildItems", "WorkflowItemModal")';
$.ajax({
type: "GET",
dataType: "json",
url: url,
contentType: "application/json; charset=utf-8",
success: function (data) {
// Do something with the returned data
},
error: function (xhr, status, error) {
// Handle the error.
}
});
Hope this helps someone else!
For handling errors from ajax calls on the client side, you assign a function to the error option of the ajax call.
To set a default globally, you can use the function described here:
http://api.jquery.com/jQuery.ajaxSetup.