How to get mvc c# user role in jQuery - c#

I have a function in jQuery to disable input based on user roles. But I don't know how to get the current ASP.Net MVC user role in jQuery.
Below is the code but it is not working:
$(function () {
if (Roles.IsUserInRole('user'))
{
$("#GenericName").prop("disabled", true);
$("#TradeName").prop("disabled", true);
$("#Form").prop("disabled", true);
$("#Strength").prop("disabled", true);
$("#IsBrandSubstitutionAllowed").prop("disabled", true);
$("#Route").prop("disabled", true);
$("#Dosages").prop("disabled", true);
$("#Unit").prop("disabled", true);
$("#PackTypes").prop("disabled", true);
$("#GeneratedDirection").prop("disabled", true);
$("#UserDirection").prop("disabled", true);
$("#StartDate").prop("disabled", true);
$("#EndDate").prop("disabled", true);
}
});

The problem: You are mixing Javascript and Razor Views.
What you have:
if (Roles.IsUserInRole('user'))
{
should actually be written as:
var userRole = '#(Roles.IsUserInRole("user") ? "true" : "false")';
if(userRole) {
...
This code #(Roles.IsUserInRole('user') ? "true" : "false") will output true or false literal string (as it's not wrapped in single or double quotes, javascript will interpreter as a boolean value) and you can just use that new assign variable.
What I normally do, is in my _Layout.cshtml view, I add a simple Global Javascript that I can easily call through my application... for example and assuming that you have a CurrentUser object on that View (through ViewData or Model):
<html>
<head>
<title>Your App</title>
<styles ... >
<script>
var AppGlobal = {
"user" = {
"name" : "#(CurrentUser.Name)",
"id" : "#(CurrentUser.Guid.ToString())",
"role" : "#(CurrentUser.Role.Name)"
},
...
};
</script>
</head>
<body>
#RenderBody()
</body>
</html>
Then it's easier, in your case to do:
if(AppGlobal.user.role === 'user') {
...

I would suggest to do an AJAX call in order to get user role.
After ajax calling, based on response received then you disable/enable inputs.
like:
$.ajax({
url: 'Controller1/Action1',
dataType: 'json',
data: {},
type: 'post',
success: function(data){
if(data.user === 'user') {
// disable inputs here !
}
}
});
and your controller called Controller1Controller:
[HttpPost]
public JsonResult Action1(){
return Json(new {
user = // put current user role here !
});
}
Also, I'd suggest to use ValidateAntiForgeryToken in order to avoid CSRF attack but seems to be fine since there are no form.

var userRole = '#(User.IsInRole("user") ? "true" : "false")';
if(userRole) {
...
In my case I had to use the if condition like this
If(userRole=="true"){
...
}
then the code hit the condition else it was skipping it.

You can only use C# code, like Roles.IsUserInRole('user') if you're writing JavaScript code in Razor view.
As a workaround, you can create an action to tell you the user's permission or maybe role, which you will need to send a request to, every time permissions are needed. You can also keep a copy of the status returned to save subsequent requests. According to your project, you can use it with more sophistication and make separate your authorization logic.

Using MVC 5.2.2, this worked for me
var userRoleAdmin = '#(Request.IsAuthenticated && User.IsInRole("Admin")) ? "true" : "false")';
if(userRoleAdmin) {
...

Related

Jquery .post method is sending a null value. How to pass actual value to controller?

I have a controller that applies to an edit view in asp.net MVC. I have an actionlink that sends the row Id to the controller which then brings back the correct row to see in the associated view.
I then have a partial view below that. That also requires a parameter in order to bring associated data from another table.
I have a Jquery .post call that runs after the page is loaded. I can alert out and show the exact value I want to send to the controller.
$(document).ready(function () {
var url = "/Home/MmsAndNotes";
var Uc = $("#Id").serialize();
alert(Uc);
$.post(url, {Id: Uc}, function (data) {
alert("what is Uc now? " + uc); //just for testing
});
})
I have also used it this way.
$(document).ready(function () {
var url = "/Home/MmsAndNotes";
var Uc = $("#Id").val();
alert(Uc);
$.post(url, Uc, function (data) {
});
})
the alerts come up and show the value I want. However, when the .post call runs, it sends a null value. Here is my controller.
public ActionResult MmsAndNotes(string Id)
{
//Declare LogisticsVM for individual policy info
LogisticsMMS_NotesVM model;
if(uc == null)
{
return Content("uc is empty.");
}
int val = Convert.ToInt32(uc);
using (Db db = new Db())
{
LogisticsMMS_NotesDTO dto = db.LogisticsMMS.Find(val);
//confirm policy exists
if (dto == null)
{
return Content("This policy cannot be found." + val);
}
model = new LogisticsMMS_NotesVM(dto);
}
return PartialView(model);
}
It always returns as uc is empty. I repeat, when the alerts come up. I get the correct value to send to the controller. But once it sends, something happens and it converts to null. HELPPPPP.. please .. I'm losing my mind over this one.
I don't know why, but changing my $.post() call to an $.ajax({}) call solved the issue. As you can see above, I had the $.post call. Using this instead,
$.ajax({
type: "POST",
url: "/Home/MmsAndNotes",
dataType: 'text',
data: { Id: Uc }
});
Solved it. I thought Jquery's shortened calls worked the same way. They certainly might, but doing it this way was the only way it worked for me.
P.S. Thanks Tyler (above) for your comments.
this solution should be work :
$(document).ready(function () {
$.ajax({
url: '/Home/MmsAndNotes',
type: 'GET',
dataType: "html",
data: { uc : $("#Id").val() },
success: function (result) {
code here
}
});
})
You need to verify if $("#Id").val() is not empty

manage serverside validaton when I use jquery post

From razor view I'm sending js object using jquery to the mvc controller. Reason why I do it using jquery post method and not razors form is that I need to manage dynamic input of certain fields. On the view certain fields (inputtextbox) are dynamically added to the view (from 0 - 10) and I manage that solution using js on the page.
var myJsObj = ...
$.ajax({
type: 'POST',
traditional: true,
contentType: 'application/json',
url: '/MyController/SomeAction',
data: JSON.stringify({ model: myJsObj}),
success: function () {
}
});
On the server side, mvc receives that model and in case of some error I want to return this object back to the view.
[HttpPost]
public ActionResult SomeAction(MyModel model)
{
if(!ModelState.IsValid)
{
ModelState.AddModelError("", "Error occured!");
return View(model);
}
return RedirectToAction("Index");
}
I have inside razor view
Html.ValidationSummary
but since I'm using jquery post I dont know how to receive back to the view and display error like I would use regular razor form. Or if you know better approach to manage dynamically added input boxes on the razor view please post. Any help please.
I think you've got a couple of options here:
If you prefer to continue to use an Ajax POST as you've shown above, then you need to take the response from the POST and inject it back into your current HTML document. For example,
$.ajax({
type: 'POST',
traditional: true,
contentType: 'application/json',
url: '/MyController/SomeAction',
data: JSON.stringify({ model: myJsObj}),
success: function (data) {
// This is the case where the MVC action found model validation
// errors, and so it is responding with an HTML document that
// shows the errors.
var returnedBodyHtml = $(data).find('body').html();
$('body').html(returnedBodyHtml);
}
});
(That's untested code up there, so you may have to debug a little bit.) But this code doesn't handle the case where the server responded with a redirect (in the case of successful validation). So, check out this post for some options there.
Your other option is to use the standard Form submit. I know you said you had some dynamically generated input controls on your page, but that doesn't mean that you can't do a Form submit. You just need to make sure that these dynamically generated elements have the correct "name" attribute on them, so that their values get mapped appropriately to the Model on the server side action that is accepting the POST. For example, if your Javascript is dynamically generating an HTML element like this, and inserting it into the form:
<input type="text" name="myDynamicallyGeneratedInput[0]" />
<input type="text" name="myDynamicallyGeneratedInput[1]" />
<input type="text" name="myDynamicallyGeneratedInput[2]" />
<input type="text" name="myDynamicallyGeneratedInput[3]" />
then your Form submit will still work, as long as on the server side, your MyModel class has that corresponding property:
class MyModel
{
public List<string> MyDynamicallyGeneratedInput {get; set;}
}
This is what I have done to display errors for dynamic inputs. First off, take a look at this post to give you a better understanding. I have modified my code to better suit my needs, but you can check if it works for your application.
use-asp-net-mvc-validation-with-jquery-ajax.
I would then consume the return result in the ajax post error callback. It returns a code 400 'Bad Request' on validation errors. The validator variable is the form validator object.
error: function (xhr, textStatus, errorThrown) {
var statusCode = parseInt(xhr.status);
if (statusCode == 400) {
var data = $.parseJSON(xhr.responseText);
var message = "";
$.each(data, function (i, item) {
var propertyName = "" + item.key + "";
if ($("input[name='" + item.key + "']").length > 0) {
var errorObj = {};
errorObj[item.key] = item.error;
validator.showErrors(errorObj);
}
else {
message += "<div>" + item.key + ": " + item.error + "</div>";
}
});
if (message != "") {
//display message
}
}
}
I hope this helps. Good luck.

Resolve Controller Path in Javascript File

I'm using a Kendo grid to display results from a webservice. The webservice is accessed in a controller and then we point the Kendo grid dataSource to the controller like so:
JavaScript
var servicePath = "/Home/Search";
var postData = { "searchTerm" : searchTerm, "targetDB" : targetDB }
var grid = $("#grid1").kendoGrid({
pageable: {
pageSize: 10
},
dataSource: {
error: function (e) {
if (e.errors !== false) {
$("#errorContainer").html(e.errors);
}
},
transport: {
read: {
url: servicePath,
dataType: "json",
data: postData,
type: "POST"
}
},
},
dataBound: function (e) {
//Do Stuff
}
});
Controller
[HttpPost]
public ActionResult Search(string searchTerm, string targetDB)
{
//Do Search and Return JSON
}
Problem
This works wonderfully when my URL is http://localhost/Home/Index but fails whenever it's something else, such as http://localhost/ (default when project is run from root). I've experienced the same problems using a jQuery .ajax call as the kendo grid service call.
Question
So my question is, how can I put in the correct service URL for the Kendo Grid (or in general when pointing to a controller) and know it will work in all path variations?
I've tried using variations of location.host to get the full URL regardless then append the controller and method, but the Kendo service call fails with no error.
I imagine I should be able to parse the url and use what I need, but I've found that when I am at the root of the webpage I can't figure out what to put to make an ajax call work. I've tried using the controller/method and the entire url? I've also tried various techniques described below.
What am I missing? Is there a convention or technique I could use instead?
Edit
I also tried putting a hidden field on the page with a value of the controller URL:
<input type="hidden" value="#Url.Action("Search", "Home"); " id="serviceURL" />
And then using that value in the JS:
var servicePath = $("#serviceURL").val();
But I found that the value of #Url.Action() (Value : Home/Search) is the same whether your url is http://localhost/ or http:localhost/Home/Index, so no luck. This still does not work when you're on the root page where the url looks something like "localhost/".
Thanks!

Redirecting to another page in ASP.NET MVC using JavaScript/jQuery

I want to redirect from one page to another page in ASP.NET MVC 3.0 using JavaScript/jQuery/Ajax. On button click event I have written JavaScript code like below.
function foo(id)
{
$.post('/Branch/Details/' + id);
}
My controller code is like this:
public ViewResult Details(Guid id)
{
Branch branch = db.Branches.Single(b => b.Id == id);
return View(branch);
}
When I click on a button it is calling the Details action inside BranchController, but it doesn't return to the Details view.
I didn't get any error or exception. It's showing status 200 OK in Firebug. What is wrong in my code and how can I redirect to the Details view page?
You are not subscribing to any success callback in your $.post AJAX call. Meaning that the request is executed, but you do nothing with the results. If you want to do something useful with the results, try:
$.post('/Branch/Details/' + id, function(result) {
// Do something with the result like for example inject it into
// some placeholder and update the DOM.
// This obviously assumes that your controller action returns
// a partial view otherwise you will break your markup
});
On the other hand if you want to redirect, you absolutely do not need AJAX. You use AJAX only when you want to stay on the same page and update only a portion of it.
So if you only wanted to redirect the browser:
function foo(id) {
window.location.href = '/Branch/Details/' + id;
}
As a side note:
You should never be hardcoding urls like this. You should always be using url helpers when dealing with urls in an ASP.NET MVC application. So:
function foo(id) {
var url = '#Url.Action("Details", "Branch", new { id = "__id__" })';
window.location.href = url.replace('__id__', id);
}
This could be done by using a hidden variable in the view and then using that variable to post from the JavaScript code.
Here is my code in the view
#Html.Hidden("RedirectTo", Url.Action("ActionName", "ControllerName"));
Now you can use this in the JavaScript file as:
var url = $("#RedirectTo").val();
location.href = url;
It worked like a charm fro me. I hope it helps you too.
You can use:
window.location.href = '/Branch/Details/' + id;
But your Ajax code is incomplete without success or error functions.
// in the HTML code I used some razor
#Html.Hidden("RedirectTo", Url.Action("Action", "Controller"));
// now down in the script I do this
<script type="text/javascript">
var url = $("#RedirectTo").val();
$(document).ready(function () {
$.ajax({
dataType: 'json',
type: 'POST',
url: '/Controller/Action',
success: function (result) {
if (result.UserFriendlyErrMsg === 'Some Message') {
// display a prompt
alert("Message: " + result.UserFriendlyErrMsg);
// redirect us to the new page
location.href = url;
}
$('#friendlyMsg').html(result.UserFriendlyErrMsg);
}
});
</script>
<script type="text/javascript">
function lnkLogout_Confirm()
{
var bResponse = confirm('Are you sure you want to exit?');
if (bResponse === true) {
////console.log("lnkLogout_Confirm clciked.");
var url = '#Url.Action("Login", "Login")';
window.location.href = url;
}
return bResponse;
}
</script>
check the code below this will be helpful for you:
<script type="text/javascript">
window.opener.location.href = '#Url.Action("Action", "EventstController")', window.close();
</script>

update field or redirect page using jquery and asp.net mvc

Im new to jquery and stuck with what i want to achieve.
Heres what I want to do using jquery and asp.net mvc.
click a submit button
this calls an action method called LogOn in the controller Account
if the call allows users to log in succesfully redirect to a url (sepecified by LogOn)
if it fails replace a div(with id="error") with "sorry error occured"
so far I tried this:
$("#submit")
.button()
.click(function () {
$.ajax({
type: "POST",
url: "Account/LogOn",
dataType: "json",
success: function (data, textStatus) {
if (data.redirect) {
// data.redirect contains the string URL to redirect to
window.location.href = data.redirect;
}
else {
// data.form contains the HTML for the replacement form
$("#error2").replaceWith(data.error);
}
}
});
});
how do I construct the relevant bits in the action method? to make this work?
and is the jquery code ok? i suspect prob not.
Thanks
If you want to redirect asp.net page at same directory , you can by Jquery/Java script by this :
$("#ctl00_iframecontent_BtnCancle").click(function () {
window.location = "IncSLAList.aspx?bi=37";
});
and
To redirect to Another page of project , can use :
window.location.href = "http://ImageUpload/Welcome.aspx?
Your jQuery is almost correct:
Don't call .button() (unless you're using jQuery UI and want to do that)
Add return false; at the end of the click handler to prevent the browser from submitting normally.
In the action, you would either return Json(new { redirect = str }) or return Json(new { error = str }).

Categories