I have an API which sends error status flag, error message and object of user. Currently I am using the API response class to get these responses.
public class UsersResponse
{
public int Status { get; set; }
public string Message { get; set; }
public List<User> Users { get; set; }
}
I receive the response in the instance of the above mentioned class and later display the result on the view. I get the response in the view's code behind file.
I was wondering if this is the right way to do it? If view models are used, will it be tackled by view model? If yes, then how will it be done.
I am thinking of getting into the habit of using view models rather than fully relying on the views code behind file.
The best way to tackle such a situation will be of great help and highly appreciated.
Thanks :)
Expose a INPC property like IsBusy in the ViewModel, turn it on before accessing your long running process (better make it async), then turn it off.
You shouldn't be loading data in the code-behind, in MVVM the code-behind should be minimized and restricted to view-specific only code (e.g. if you have several platforms). Think of code behind like JS for HTML, even less than that.
It's the ViewModel that should take care of loading the data and manipulating it. ViewModel = The model of the view.
Related
My Home Model/View/Controller (which configures the initial state of the page) is working fine.
I also, though, need to respond to changes the user makes on the page (selecting an option from a select, checking a checkbox, etc.), and have not got that to work yet.
Maybe the reason I'm having problems is that I'm trying to reuse my "Home" model, which contains not only what I need for page initialization, but some other things as well. For example, my model:
public class HomeModel
{
public DataTable Units { get; set; }
public DataTable Reports { get; set; }
public DataTable UnitReportPairEmailVals { get; set; }
public DataTable UnitReportPairGenerateVals { get; set; }
. . .
}
...contains things the page needs at first ("Units"and "Reports" and the things represented by the ellipsis dots), but also things only needed later (the other two shown).
I'm wondering if at least part of my problem with getting this data back (via an Ajax call to another method in HomeController) is because I should be using a separate Model and Controller for the Ajax call.
So I'm wondering: is Model/Controller proliferation a code smell/anti-pattern, or necessary? Should I create another Model like:
public class AJAXModel
{
public DataTable UnitReportPairEmailVals { get; set; }
}
...and a corresponding separate Controller for it?
If I have a complex Model, which is used in various scenarios, it seems that every time I pass a model back as the return value (result) of an Action, a lot of superfluous/unpopulated things will also be passed back (only the members that I'm interested in at the time being populated in the Controller, thus passing back a lot of empty/null members).
So my question is, should I create spearate Models/Controllers for each "use case", or is it okay - or even better - to combine a bunch of things into one Model/Controller pair?
There's no compelling reason to limit a Model to a single Controller or to expect that a Controller has only one Model. You could write your entire app in a single Controller (really bad idea, by the way).
Generally, the division is a logical one...a bunch of actions that talk to the same set of Models in one controller. It's more to keep your brain from melting when you open the source file as anything else.
You often have multiple Views and they tend to mach name-for-name with the Actions in your controller...but this isn't strictly enforced.
When you feel like you're getting more data in the View than necessary, this can be simplified by mapping the Model to a ViewModel to simplify the code in the View. Yes, this is MVVM...and again...the brain hurts less dealing with the simpler object in the View.
You can manually map the object in your Controller, or you can use an auto-mapper to do it. There are a number to choose from...and they make the MVVM a simpler thing to do. You don't necessarily need one. They're just helpful.
I have been looking at C# MVC for a while now and really getting in to it. I have come across how to pass 2 or more Domain Models in to a View but what i need to ask is security. I have read about Over Posting and that is can be stopped with Binding inclusions and exclusions but how does this effect a ViewModel with 2 or more Model inside it. Is there still the possibility of hidden fields in the HTML that resolve to the Domain Models and are they editable.
I have been looking to make ViewModels where i give it certain things i want the user to edit but it just seems over complicated, so is there a better and easier way of doing this.
public TicketViewModel {
private Ticket _ticket;
public TicketViewModel(Ticket Ticket)
{
_ticket = Ticket;
}
public string Title
{
get
{
return _ticket.Title;
}
}
public List<Comment> Comments
{
get
{
return _ticket.Comments;
}
}
}
As you can see I create a new ViewModel with the Ticket Domain Model but the main concern that i have is returning a List of Domain Model Comments as i only want them to be read only.
Any help would be greatly appreciated.
For security:
If i get what you are asking about then
First of all the user can edit everything on the client side and we cannot do anything for this.
But for your concern if you have not added code on server side than no one will be able to change your data using your application , also you can add validation on server side.
For adding List in a ViewModel:
public class MainViewModel
{
public string Title{get;set;}
public List<Comment> ListComments {get;}
}
"i have is returning a List of Domain Model Comments as i only want them to be read only"
you can use this,
public List<Comment> Comments { get; }
Consider the ReadOnlyCollection, and the method AsReadOnly provided by List.
Your comment property can be rewritten as -
public List<Comment> Comments
{
get
{
return _ticket.Comments.AsReadOnly();
}
}
If you don't want something to be editable, just don't modify it.. I think this is unrelated to MVC.. You are in control of server code, so if you want comments to be readonly, just don't modify them in your server code. All these "models" exist as long as your HTML is being rendered on the server.
Client by itself won't be able to modify your database, only to modify it's HTML or send requests to your server.. It's your server code that actually modifies things.
Looking at this, and not knowing the context it is in, I would suggest using the domain model itself in your view and not wrapping it in the TicketViewModel. The ViewModel doesn't seem to add anything.
For the read only comments: I don't think it matters whether the collection in the ViewModel is editable. What matters is that you don't render editable controls in your view. And most important that the code in your Save (or whatever it is called) action ignores whatever comments are posted.
I was hoping someone could sort this out for me. im trying my hardest to stick to the MVVM pattern as much as possible. yes i understand that this is a pattern and not a frame work.
so far after reading this is the Impression that i have. please advise if this is the wrong approach.
My project is basically a WMI browser that stores favorite queries and run multiple queries against computers and then compare results.
The View:
Is basically the XAML portion of the project. here we would bind the controls to the Model View including itemssource selected items and anything else that is required.
So the View has no access to the model view, it does not store data or manipulate data inside the model view. it only bounds to observable collections inside the model view
The Model View:
Is where and event triggers happen from client interaction, IE: selection item change or clicking a button. the Model view then uses the data the the model has gathered arranges the data in a view able context for the view.
The Model:
Gets the data required for the end users and stores the data for when the model view requires it.
Am i even close to right on this ?
View - XAML / Control Styling / Control Creation
Model View - Data Organisation / Event management / Data Display Management
Model - Data Gathering / Remote Connections to Data sources.
Sounds fine as long as your ViewModel are not actually dealing with view (WPF-specific) code.
Think of ViewModels as technology-agnostic. In theory, you should be able to run your ViewModels in a console or Android application, therefore any references or dependencies on System.Windows (WPF-specific) classes is unacceptable in the ViewModel level.
I figured this out. was a little easier than first anticipated.
public class ParentNode
{
public ParentNode() { }
public string ParentNodeName { get; set; }
public ObservableCollection<SubNode> AddChildNodes { get; set; }
public ObservableCollection<CheckBoxSubNode> AddCheckBoxChildNodes { get; set; }
}
public class SubNode
{
public SubNode() { }
public String SubNodeName { get; set; }
}
new ParentNode() {
parentnodename = "parent"
addchildnodes = new SubNode() { Subnodename = "subnode" }
)
Then some random XAML binding to bind to the correct propertes and all was good.
My View Model still doesnt directly access the View. :)
Here's my problem:
We have an intranet asp.net mvc 3 application with a controlled set of users. We have a Person class, that contains a large amount of information, that is initially loaded and stored in the session. The data/editing for this object spans across many screens. Basically, each screen is a subset of the Person's data.
I'm trying to take advantage of the built in model binding in asp.net mvc. Should I create a data class that binds the form data from each screen and then updates my session object using a service object?
Example below: DxFormData contains a subset of the person data and will only be used as a parameter on this method.
public ActionResult Dx(DxFormData data)
{
// Update current session Person object with data passed in if modelstate is valid
var viewModel = this.GetDxViewModel();
return View(viewModel);
}
public class DxForm Data
{
public string AdmitDx { get; set; }
public string PrinDx { get; set; }
}
I'm looking for thoughts on this approach and if there's a better solution available to me. The problem that I see, is that the person class contains all the data and I'm creating another class with a subset of that data. Obviously, duplicating the properties.
Side note: I did write a custom model binder that returned the session person for binding. However, I am continually getting errors when it attempts to bind.
I don't see problem with this approach. If you try to use the Parent class as the action parameter then in each form submit action then you will get validation errors because the model is not completely filled, so you should use view models in this case and unfortunately you can't avoid duplicating properties.
I'm working on a custom validation framework for my WPF/C# application.
What I'm looking to do is to retrieve strings from the resource file where the viewmodel is declared, but in the actual validation code it self. This particular string is the same resource used by label on the editing UI Form.
My code works fine with the following syntax -
[Required(TypeRes = typeof(Resources))]
public string RequiredStringWithDesc { get; set; }
But what I"m looking for is something that is syntacticly cleaner looking. I was trying to use
const Type LocalRes = typeof(Resources);
[Required(TypeRes = LocalRes)]
public string RequiredStringWithDesc { get; set; }
Any suggestions on a simpler syntax? The old c++ DEFINE statement here would work well.
FYI: the reasons for going to this much work has to do with how we are doing localization and UI construction.
EDIT To answer a couple of questions about why are we doing this?
We are going to be using the same string from the resource file to -
On the edit screen, this is the label to identify the field.
In the datamodel, if there is a validation error, we are using this to correctly label the problem in the log file.
In the Viewmodel, we are reusing this label in the validation error message to reinforce where the problem is to the user.
This is part of a real time inspection system and some of the failure modes relate directly back to these data fields. So we can easily get the correctly localized label to apply to run-time fault messages
The general concept is that this simplifies presenting consistent messages to the user while only creating things once. With regards to validation attributes (and this question), we need to be able to get the Resource file type to load the correct message.
Create a new attribute class which inherits from the RequiredAttribute and set default values.
public class LocalizedRequiredAttribute : RequiredAttribute {
public LocalizedRequiredAttribute() { /* TypeDef = typeof(Resources);*/ }
}
public class MyModel {
[LocalizedRequired]
public string RequiredStringWithDesc { get; set; }
}