how can i change menu view by user access role? - asp.net-mvc-4

I have a web application project with MVC 4 and I use Telerik panel bar and bind it by site map for my menu.but now i want to each user according to user access roles in my program see particular items of menu and hide remind menu items . how can i do this work in MVC any tips or trick would be welcome
this is link of Telerik website that i use it for creating my menu just i use it in partial view and just render its action in my layout razor code

Assume you have this global class :
public class AccessControlList{
public static bool IsAdmin {
get{
//put your code here
return false;
}
}
public static bool HasOpenFileAccess{
get{
//put your code here
return true;
}
}
}
then in your view.cshtml you may have something like this :
#(Html.Telerik().Menu()
.Name("mnuMain")
.Items(itemAdder =>
{
itemAdder.Add()
.Text("Admin Menu")
.Visible(false)
.Url("~/Home")
.Visible(AccessControlList.IsAdmin);
itemAdder.Add()
.Text("Files")
.Items(subItemAdder =>
{
subItemAdder.Add()
.Text("Open File...")
.Url("~/Files/Open")
.Visible(AccessControlList.HasOpenFileAccess)
....
complete your AccessControlList class (AccessControlList.cs file) to check if the authenticated person has your required access or not.

Related

C# XAML page dependency injection on the fly with MVVM Light

I would like some feedback to see if I'm using SimpleIoc in the correct way.
The code below works, but I'm not sure if it's best practice.
I have an UWP XAML DocumentPage class on which I want to show an IRpcDocument.
I want to use the DocumentPage for both RpcDocumentA and RpcDocumentB. The user can navigate to both types of IRpcDocument. So the application should be able to switch between the two 'on the fly'.
So I wrote my DocumentPageViewModel
public class DocumentPageViewModel : ViewModelBase
{
public IRpcDocument RpcDocument;
public DocumentPageViewModel(IRpcDocument rpcDocument)
{
RpcDocument = rpcDocument;
}
}
And my ViewModelLocator
class ViewModelLocator
{
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<DocumentPageViewModel>();
}
public DocumentPageViewModel SimpleIoc.Default.Register<DocumentPageViewModel>
{
get
{
return ServiceLocator.Current.GetInstance<SimpleIoc.Default.Register<DocumentPageViewModel>>(Guid.NewGuid().ToString());
}
}
}
When I'm navigating to the DocumentPage I call:
SimpleIoc.Default.Register<IRpcDocument , RpcDocumentA>();
await NavigationService.NavigateAsync(typeof(DocumentPage), DocumentIdParameter);
The app then navigates to the DocumentPage, constructs the RpcDocumentA, makes the necessary RPC calls to fetch the data and shows the document.
The first line tells the IoC framework it should expect an RpcDocumentA in its constructor, the second one triggers navigation. So in this case, im not registering the interface in the static ViewModelLocator().
So for each time I navigate I call SimpleIoc.Default.Register<IRpcDocument , RpcDocumentA> or SimpleIoc.Default.Register<IRpcDocument , RpcDocumentB>
This works, but is this the right way to do this? I suspect it's not.

Validation messages from custom model validation attributes are locked to first loaded language

I am working on a multi lingual website using Umbraco 7.2.4 (.NET MVC 4.5). I have pages for each language nested under home nodes with their own culture:
Home (language selection)
nl-BE
some page
some other page
my form page
fr-BE
some page
some other page
my form page
The form model is decorated with validation attributes that I needed to translate for each language. I found a Github project, Umbraco Validation Attributes that extends decoration attributes to retrieve validation messages from Umbraco dictionary items. It works fine for page content but not validation messages.
The issue
land on nl-BE/form
field labels are shown in dutch (nl-BE)
submit invalid form
validation messages are shown in dutch (nl-BE culture)
browse to fr-BE/form
field labels are shown in french (fr-BE)
submit invalid form
Expected behavior is: validation messages are shown in french (fr-BE culture)
Actual behavior is: messages are still shown in dutch (data-val-required attribute is in dutch in the source of the page)
Investigation to date
This is not a browser cache issue, it is reproducible across separate browsers, even separate computers: whoever is generating the form for the first time will lock the validation message culture. The only way to change the language of the validation messages is to recycle the Application Pool.
I doubt that the Umbraco Validation helper class is the issue here but I'm out of ideas, so any insight is appreciated.
Source code
Model
public class MyFormViewModel : RenderModel
{
public class PersonalDetails
{
[UmbracoDisplayName("FORMS_FIRST_NAME")]
[UmbracoRequired("FORMS_FIELD_REQUIRED_ERROR")]
public String FirstName { get; set; }
}
}
View
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
var model = new MyFormViewModel();
using (Html.BeginUmbracoForm<MyFormController>("SubmitMyForm", null, new {id = "my-form"}))
{
<h3>#LanguageHelper.GetDictionaryItem("FORMS_HEADER_PERSONAL_DETAILS")</h3>
<div class="field-wrapper">
#Html.LabelFor(m => model.PersonalDetails.FirstName)
<div class="input-wrapper">
#Html.TextBoxFor(m => model.PersonalDetails.FirstName)
#Html.ValidationMessageFor(m => model.PersonalDetails.FirstName)
</div>
</div>
note: I have used the native MVC Html.BeginForm method as well, same results.
Controller
public ActionResult SubmitFranchiseApplication(FranchiseFormViewModel viewModel)
{
if (!ModelState.IsValid)
{
TempData["Message"] = LanguageHelper.GetDictionaryItem("FORMS_VALIDATION_FAILED_MESSAGE");
foreach (ModelState modelState in ViewData.ModelState.Values)
{
foreach (ModelError error in modelState.Errors)
{
TempData["Message"] += "<br/>" + error.ErrorMessage;
}
}
return RedirectToCurrentUmbracoPage();
}
}
LanguageHelper
public class LanguageHelper
{
public static string CurrentCulture
{
get
{
return UmbracoContext.Current.PublishedContentRequest.Culture.ToString();
// I also tried using the thread culture
return System.Threading.Thread.CurrentThread.CurrentCulture.ToString();
}
}
public static string GetDictionaryItem(string key)
{
var value = library.GetDictionaryItem(key);
return string.IsNullOrEmpty(value) ? key : value;
}
}
So I finally found a workaround. In attempt to reduce my app to its simplest form and debug it, I ended up recreating the "UmbracoRequired" decoration attribute. The issue appeared when ErrorMessage was set in the Constructor rather than in the GetValidationRules method. It seems that MVC is caching the result of the constructor rather than invoking it again every time the form is loaded. Adding a dynamic property to the UmbracoRequired class for ErrorMessage also works.
Here's how my custom class looks like in the end.
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter,
AllowMultiple = false)]
internal class LocalisedRequiredAttribute : RequiredAttribute, IClientValidatable
{
private string _dictionaryKey;
public LocalisedRequiredAttribute(string dictionaryKey)
{
_dictionaryKey = dictionaryKey;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(
ModelMetadata metadata, ControllerContext context)
{
ErrorMessage = LanguageHelper.GetDictionaryItem(_dictionaryKey); // this needs to be set here in order to refresh the translation every time
yield return new ModelClientValidationRule
{
ErrorMessage = this.ErrorMessage, // if you invoke the LanguageHelper here, the result gets cached and you're locked to the current language
ValidationType = "required"
};
}
}

Eclipse RCP disable a view from a dialog

I have a simple RCP application. I have a perspective and three views added to it. Initially one of the view will be disabled for the users. There is a toolbar item which launches a dialog. User authenticates himself in the dialog. After successful authentication, I want to make the view editable. I could get the reference of that specific view in my dialog.But I dont know how to enable it. I could not use selection listener as I am not selecting anything. Also I saw an example about using activities extension. But that opens/closes the view and not just enable/disable it. Can someone help me? Thanks.
As I understand you, you want to show the view in one of two states: either disabled if the user is not authenticated, or enabled when the user has been authenticated.
This is actually pretty easy :-) and I have made a small example application for you that illustrates the technique: so-edi.zip
UPDATED with new link
In RCP 3.x you have to expose the View's Control's enabled state in your implementation of ViewPart:
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.part.ViewPart;
public class View extends ViewPart {
private Control control;
#Override
public void createPartControl(Composite parent) {
control = new Composite(parent, SWT.NONE);
}
#Override
public void setFocus() {
}
public void setEnabled(boolean enabled) {
control.setEnabled(enabled);
}
public boolean isEnabled() {
return control.getEnabled()
}
}

How do I navigate from one view to another in Caliburn.Micro?

So let me put it this way.
I have a LogInViewModel and a LogInView. There is a Login() method in the ViewModel that gets called if the user clicks on a button in the View. Now I want the dashboard to show if the login was successful. How do I do this? I can't find a clear answer to this in the documentation.
I assume that your dashboard is essentially your shell. In which case, you can bootstrap your LoginViewModel and in the Login method, after a successful login, you can show the DashboardViewModel and close the LoginViewModel using the Caliburn.Micro WindowManager.
Something like (using MEF):
Bootstrapper.cs
public class Bootstrapper : Caliburn.Micro.Bootstrapper<ILoginViewModel>
{
...
}
LoginViewModel.cs
public class LoginViewModel : Screen, ILoginViewModel
{
private readonly IWindowManager windowManager;
private readonly IDashboardViewModel dashboardViewModel;
[ImportingConstructor]
public LoginViewModel(IWindowManager windowManager, IDashboardViewModel dashboardViewModel)
{
this.windowManager = windowManager;
this.dashboardViewModel = dashboardViewModel;
}
public void Login()
{
// if login success...
this.windowManager.ShowDialog(this.dashboardViewModel);
this.TryClose();
}
}
I've just added a very simple login example SL4 project in my "lab repository" for Caliburn.Micro.
https://github.com/jenspettersson/Caliburn.Micro.Labs/tree/master/src/Login
It uses the Show class that Rob Eisenberg uses in his "Game Library" example to switch between views.
In the Login() method, it tells my Shell (your dashboard?) to show my LoginResultViewModel and sets the login result message.
yield return Show.Child<LoginResultViewModel>().In<IShell>().Configured(c => c.ResultMessage = "Successfully logged in!");
Check the code in my github repo.
I havent used Caliburn.Micro very much lately, so I am by no means an expert, but this way works for me.
//J
Edit: This answers how to navigate between views, if you want to show a "popup" to display if the login was successful, go with the other recomendations.

Can a SharePoint WebPart connect to a custom SharePoint WebPart

I need to consume a value passed by the default sharepoint filter webpart. I don't see how a custom sharepoint webpart can establish a connect and get data. Is this even possible?
Updated
The provider WebPart is a default SharePoint List Filter WebPart.
The consumer WebPart is a custom WebPart
This is the code I came up with, but the "connections" option is still greyed out on the SharePoint page. On the page, I have a SharePoint List Filter WebPart and my CustomPageViewer WebPart.
namespace PageViewerWithConnections.CustomPageViewer
{
[ToolboxItemAttribute(false)]
public class CustomPageViewer : System.Web.UI.WebControls.WebParts.WebPart
{
IFilterValues _filterVals;
[ConnectionConsumer("Consumer connection", "Consumer param")]
public void ConsumeFilter(IFilterValues filterValues)
{
_filterVals = filterValues;
}
Microsoft.SharePoint.WebPartPages.PageViewerWebPart objPageViewer;
protected override void CreateChildControls()
{
}
}
}
Reason's for this approach
My goal is to set a different URL to the page viewer Web Part based on the value I get from a SharePoint List Filter Web Part. It seems that the SharePoint List Filter WebPart cannot send data to a Page Viewer WebPart.
You'll need to create a consumer method on your custom webpart that takes an instance of IFilterValues as an argument and uses the ConnectionConsumerAttribute Attribute.
private IFilterValues _filterVals;
[ConnectionConsumer("Filter Consumer", "FilterConsumer")]
public void ConsumeFilter(IFilterValues filterValues)
{
_filterVals = filterValues;
}
Note that the consumption of the filter values occurs during the OnPreRender stage of the page lifecycle, so you'll need to override the OnRender method to act on any values consumed from the connection, or include the logic in the consumer method.
For more information, check out these links:
http://msdn.microsoft.com/en-us/library/ms494838(v=office.12).aspx
http://msdn.microsoft.com/en-us/library/ms469765.aspx
In the CreateChildControls you should call base.CreateChildControls();
Here is some working code:
List<IFilterValues> providers = new List<IFilterValues>();
protected override void CreateChildControls()
{
if (providers.Count > 0 && providers[0].ParameterValues != null)
{
this.FilterValue1 = providers[0].ParameterValues[0];
}
base.CreateChildControls();
}
[ConnectionConsumer("Provider WebPart", "IFilterValues", AllowsMultipleConnections = false)]
public void SetConnectionInterface(IFilterValues provider)
{
if (provider != null)
{
this.providers.Add(provider);
List<ConsumerParameter> parameters = new List<ConsumerParameter>();
parameters.Add(new ConsumerParameter("param1",
ConsumerParameterCapabilities.SupportsSingleValue | ConsumerParameterCapabilities.SupportsEmptyValue | ConsumerParameterCapabilities.SupportsAllValue));
provider.SetConsumerParameters(new ReadOnlyCollection<ConsumerParameter>(parameters));
}
}