I have a requirement like this,
Making fields in model as read or write basing on different roles
Suppose in a model i have 15 fields then
User1 with Role1 can edit {Fields 1 to 5; but can view(read only) Fields 6 to 15 } and
User2 with Role2 can edit {Fields 4 ,5,6; but can view(read only) Fields 1 to 3 , 7 to 15}
I googled a lot but i could not find solution
I found a link
http://www.codeproject.com/Tips/403921/Field-Based-Security-in-ASP-NET-MVC-3-for-Differen
but using articles we have to create edit templates for different controls to make it read / write
This is one of major task in the project.
Do you have any solution for this.
Thanks,
Vijay
I don't know if you ever came up with a solution to this and I'd be curious to hear if you did, but for anyone else that stumbles upon this question what I ended up doing was passing a list of the name of all the fields a user has read only access with the view model, and then in my cshtml page I check if the field is part of that list and disable the input tag based on that.
public class DataFields{
public string Field1 {get; set;}
public string Field2 {get; set;}
public string Field3 {get; set;}
public string Field4 {get; set;}
public string Field5 {get; set;}
}
public class DataFieldsViewModel{
public DataFields DataFields {get; set;}
public IEnumerable<string> ReadOnlyFields {get; set;}
}
And then on my cshtml page something like this:
#var isField1ReadOnly = Model.ReadOnlyFields.Contains(nameof(Model.DataFields.Field1));
#var isField2ReadOnly = Model.ReadOnlyFields.Contains(nameof(Model.DataFields.Field2));
#var isField3ReadOnly = Model.ReadOnlyFields.Contains(nameof(Model.DataFields.Field3));
#var isField4ReadOnly = Model.ReadOnlyFields.Contains(nameof(Model.DataFields.Field4));
#var isField5ReadOnly = Model.ReadOnlyFields.Contains(nameof(Model.DataFields.Field5));
...
<input asp-is-disabled="#(isField1ReadOnly)" asp-for"Model.DataFields.Field1">
<input asp-is-disabled="#(isField2ReadOnly)" asp-for"Model.DataFields.Field2">
asp-is-disabled is based on something like this: https://stackoverflow.com/a/34868369/4573789
Related
First time posted long time reader. I've done a lot of searching and haven't been able to find anything so please excuse me if I missed a past post or something.
In any case I used to be a .net dev and now getting back into .net core MVC. New to MVC and really liking it!
In any case my question is this... is it possible to use a view model to consolidate data? Basically I am writing a timeline from multiple sources taking only the date stamp and description from each. I am hoping to consolidate all into a timeline viewmodel, but not sure if this is appropriate.
EX:
public class order {
public guid id {get; set;}
public datetime orderDate {get; set;}
public string orderDetail {get; set;}
public int orderQuantity {get; set;}
...
}
public class goodsReceipts {
public guid id {get; set;}
public datetime receiptDate {get; set;}
public int receiptQuantity {get; set}
public order order {get; set;}
...
}
public class otherTransactionaldata {
... there are many different transactions such as goodsreceipt
}
then my view model something like this
public class transactions {
public date transactionDate {get; set;}
public string transactionDetail {get; set;}
}
So I basically want to load all transactional data such as (orders, receipts, returns...) into the view model to create a sorted timeline. Am I going down the wrong path here?
Again sorry for the dumb question. I've been reading like crazy and I'm sure I've missed something so I apologize in advance.
Thank you,
E
If I have a database and I base all my models on the database (using LINQ basically to fetch/set the data). Is it possible to only use a part of those models to create my views? Say I have three columbs in a table, and I only need two for my view, can I simply use two of the three using my database model or should I create a new model to use in my views.
And if I have to create new models, any simple way to do this? I'm using Visual Studio 2015.
Thank you
It is common to create View Models to represent a slice of your domain model when putting data in a view.
For example you may have a BookViewModel and a BookEditModel. You could show and permit editing of different fields depending on the model.
class BookViewModel
{
[ReadOnly]
public string ISBN { get; set;}
[ReadOnly]
public string Title { get; set;}
[ReadOnly]
public string Author { get; set;}
}
class BookEditModel
{
[ReadOnly]
public string ISBN { get; set;}
[Validate(...)]
public string Title { get; set;}
[Validate(...)]
public string Author { get; set;}
[ReadOnly]
public DateTime LastUpdated {get;set;}
}
If you're looking into an easy way to create these view models, there is a tool called AutoMapper that allows you to easily map between domain and view models.
I have a project where most of the globalization Information is stored in the resx. files and Dataannotations are extensively used.
But now there is a new Poco class which has a text which needs to be localized. What is the best method to do this?
I would do it like this:
public class example
{
public int ItemID {get; set;}
public string Description_en_US {get; set;}
public string Description_de_DE {get; set;}
}
My main concern is how to use this later on in the razor webpage, maybe I will build a method who select a column depending on the thread locale - or does some better mechanism exist?
Can someone please post an example on how to create a many to many relationship where the source class is also the target one, using code-first ?
Something like:
Toys * <-----> * Toys
Thank you.
Nuno Senica
I don't think this is possible with EF Code First. As a workaround, you could create the mapping table yourself:
public Toy
{
public int ToyID {get; set;}
public ICollection<ToyMapping> Toys {get; set;}
}
public ToyMapping
{
public int ToyOneID {get; set;}
public int ToyTwoID {get; set;}
public ICollection<Toy> ToyOnes {get; set;}
public ICollection<Toy> ToyTwos {get; set;}
}
I'm not sure the actual use-case for this is, otherwise I would have made better named properties.
let's say we have something like this
public class Person
{
public string Name {get; set;}
public Country Country {get; set;}
}
public class PersonViewModel
{
public Person Person {get; set;}
public SelectList Countries {get; set;}
}
can automapper be used to perform to parse from Person into PersonViewModel and back ?
Don't use AutoMapper for this - it's not worth it. For example, in the cases where you have a validation failure and you show the form again - AutoMapper is not executed here (usually). We usually go two routes:
If the list is not context-specific, create an HtmlHelper that queries some ISelectListProvider for the select list items: Html.DropDownList(). You'd use your IoC container of choice to locate the personListProvider, query for the list of items, and populate the dropdown list.
If the list is context-specific, just construct the list in the controller action
It sounds like you want to send a Person to the view via the PersonViewModel which has all the bonus info you need to generate and return a new (or updated) Person object.
If this is correct, I don't think you need automapper at all. From what I understand of automapper it is for mapping collection of related objects to a more view model type of state, but in this case, you are sending a Person to the client and trying to receive a Person back. In this case, it seems easier to use your view model to populate the page, but have the page return a Person instead (or extract the updated Person from the view model to save a few keystrokes).
EDIT: That being said, yes you should be able to use automapper to move the info around. Its just a unnecessary layer for this easy scenario.
if one chose to, you could do this:
public class Person
{
public string Name {get; set;}
public Country Country {get; set;}
public Country[] GetCountries
{
... add method for countries here
}
}
Then in your ViewModel you can have your select list pull data from that collection.
public class PersonViewModel
{
public Person Person {get; set;}
public Country[] Countries {get; set;}
public SelectList Countries { get{ .. add new select list code here getting vals from Countries..}}
}
Again, this is for context sensitive lists. You are however muddling concerns a wee bit here (should a person get a list of countries?)