I am developing a web application using ASP.NET Core 1.1 with VS.2017. I am using some custom attributes that I apply to objects like classes, structs, etc.
I was wondering if it is possible (and how) to "tag" a Razor view with one such custom attribute. I mean, those views are compiled so that probably means some sort of class is generated for each view.
Please concentrate on answering the question rather than questioning why I want to do it. There is a need -in my application- and therefore I seek a way to do it.
Related
TL;DR
What are the best practices when using .NET Razor views and AngularJS?
Context
We are developing a public website (not an intranet application) using mvc4 with razor, and we weren't very familiar with client script, so we started with what we knew: jQuery.
But now things are getting more complicated and we'd like to switch to AngularJS.
On the .NET part, we use Razor templates and UIHintAttribute (plus some custom ones) to render the right html "control". We also add custom html attributes to give extra information to the jQuery part (like title for a tooltip....)
So we already use a declarative way of setting the user interface behavior, that's why AngularJS seems a good option.
Questions
Since we already have models defined server side, and since AngularJS also uses models, wouldn't it force us to duplicate code?
How do we deal with data binding feature, since we already do some binding server side (in the views). Should we make a completely asynchronous application, making AJAX calls from AngularJS to load data, or can we mix both?
Anything else we should be aware of when trying to use both of these technologies?
I did some research on Google, but I can't find detailed ways of mixing Razor views and templates with AngularJS... Perhaps that's just not a good thing to do?
We dealt with this issue for months when working with MVC plus another JavaScript framework (Knockout). Ultimately, if you're going to be using a client-side MV* framework for rendering your user interface, you will find that mostly ditching Razor is going to be your best bet.
Most of the major MV* JavaScript frameworks, including AngularJS, assume you will be maintaining UI state and rendering your user interface based on JavaScript models or view models. Trying to mix in server-side rendering is just not going to work very well.
That's not to say there is no use for MVC when it comes to developing an Angular application. You can still take advantage of some great features like ASP.NET Bundling and Minification. And sometimes it works really well to embed JSON directly into the page using a Razor view or partial as opposed to making an additional AJAX call.
As for models, you may want to take a look at Breeze.js. It's a JavaScript library for data access that goes great with ASP.NET on the server side to share model metadata.
We wrote our own data binding mechanism that synchronizes the angular.js model with a view model on the server side. The javascript model is generated from a JSON serialization of the server-side view model to avoid the duplicate code that you were talking about.
We are using SignalR to update the client's view model from the server.
Server-side changes of the C# view model properties are sent to the client as a packet containing the path to the property, e.g. Persons[42].Address.City, and the value itself, e.g. New York. The view model inherits a base class that takes care of generating the property path, so the actual view model looks quite clean and we can concentrate on business logic.
Client-side changes of the javascript view model properties are sent to the server in the same way. To catch the change events, we encapsulate all fields of the original javascript model in get/set properties where the setter sends the update packet to the server.
Server-side methods of the view model can be invoked in a similar way. All objects in the view model have an invokeMethod function that can be used like this: Products[42].Manufacturer.invokeMethod('SendEmail', 'mailsubject', 'mailbody'). This will send a packet to the server containing the method path Products[42].Manufacturer.SendEmail and the arguments as an array of ['mailsubject','mailbody'].
In conclusion, the html view (kind of) binds to the view model on the server side where other systems, such as regular Razor views can work on the same objects.
The source code can be found here: SharpAngie.
On a number of different document types, I have to add the same 3 native Umbraco data types
content picker
TextString
TextString
It was suggested to me to see if there is a way to create a new custom data type that would basically wrap those 3 datatypes into a new datatype.
I looked at nibble.be's site and see there is a couple different ways to go about creating custom data types (using the usercontrol wrapper, or 3 class approach). However, I am not sure that a custom data type for grouping existing datatypes would be the correct route.
For one thing, we are using MVC along side Umbraco with a heavy use of Razor views. Since the document type property alias is used to acquire values from Umbraco from the content page, I don't see how this would still be possible or how you would go about getting the property value of a custom datatype that has embedded datatypes.
Would there be a working way or a better way to accomplish this solution for having to add the same fields on any document type that they are needed? I though about hierarchical approach with a document type parent with only these 3 data types (content picker and 2 textstrings), but that would mean having to put any document type that a page would need under this parent document type simply for the fact to inherit these group of properties.
If you're looking to embed multiple properties into a single datatype:
There are a number of embedded datatypes available; DataType Grid, Embedded Content, and Repeatable Custom Content are the three I know of. All three store their information as xml which allows easy access via both xslt and razor.
The DataType Grid is part of uComponents and is therefore actively developed. It is also open source and therefore contributions are encouraged. Embedded Content and Repeatable Custom Content, while still useful, don't appear to have any current support and therefore no plans for improvement. I think they are licensed as open source, but the source isn't publicly available as far as I can tell.
I don't think you can set a limit on the number of rows/items stored in the DataType Grid, like you can in Embedded Content (perhaps a feature request).
Take a look at some of these solutions before you plan on rolling your own. But if you still feel the urge to code out your own data type, I'd recommend Tim Geyssens' articles on created custom datatypes using the user control wrapper, with data editor settings, and serializing the data as xml. His "Master of Datatypes" video is also really helpful and covers those topics as well.
If you're looking to organize your properties into groups:
Tom Fulton published a new package/data type recently called Document Type Fieldsets that may fit your needs. It allows you to group fields together in a fieldset. Here's a screen shot:
I realize this is an old question, so I'm just adding this for anyone searching for this functionality in the future: This is almost exactly what we use Widget Builder for in Umbraco 6.
Widget Builder is the predecessor to Umbraco 7's Archetype which is being pushed by the core team for near universal use. I believe it's going to become a part of the core.
Internally, WidgetBuilder and Archetype store their data as JSON and make it very easy to copy a custom data type from one project to another with an import/export feature.
I used to work with Archetype for some time until I discovered Nested Content which does the same thing but much easier to work with because it nests Document Types instead of Data Types which is much easier to work with, especially for Content Editors. Plus the resulting Data Types is normal built-in Umbraco ones, not Archetype Objects which add a new layer of Entity Mapping in your views.
I need some suggestions on how to resolve the issue I am having. I have tried several different options but hit limitation after limitation. Here is a brief overview of what is going on...
We have 40 tables that hold configuration data that needed to implement CRUD operations. We must use Telerik MVC Grid and preferably the INLINE editing. We must manage the original state and the changed properties on a single object. That object will later be serialized into the database for later approval.
Instead of making 40 models, 40 views, 120 crud methods(no delete), that will all closely share the same code except the field names. I am trying to create a way to make this generic enough where we can have 40 models (maybe?), 1 view, 3 crud methods.
I am running into limitation in various areas:
WCF doesn't support generics
Telerik grid doesn't support dynamic types
WCF doesn't keep methods and private properties intact
We are using MEF also, so this is a plugin, inside of a plugin.. i know..
Adding methods to the WCF layer is not permitted...
My Idea?
I thought I would try creating a class to hold the state, well call it ManagedState. I originally wanted the table models to inherit from it and I had it linked to track changes but this was not working.
I also have now tried using the ManagedState class separately from the configuration class
and using that strictly to pass back and forth through our WCF service. Then try using that data to create the original type and hydrate it.
Really there is so much that has gone into this I am flustered. I have no particular code to share as this is an overall question of how I would implement it as I am hitting brick walls all over. I can post code in future if I get a good response to attempt another method to implement.
I see this question had a lot of views so I figured I would respond to answer my question.
I pretty much used T4 templates to generate a TelerikGrid HTMLHelper. The Telerik grid code was generated for each type unfortunately but all I had to do was call the helper and pass my type in and it used a case statement to return the correct grid.
I'm new to developing web apps using ASP.NET MVC. In fact, I'm rather new to developing web apps, regardless of technology.
Currently, I'm working on a project just to get to know the ASP.NET MVC framework better. When reading on SO and elsewhere on the internet, the consensus seems to be that the views should never deal directly with the business objects (i.e. objects implementing business logic and containing associated attributes). Instead, view models should be used. However, this introduces a couple of issues:
Where do I put my validation code?
I need to add code to map between business objects and view models.
In fact, it seems rather cumbersome and I haven't really seen anyone explaining properly why it's a bad idea passing business objects to the views. Could someone please try to explain this (or point to a good explanation)?
Just a clarification; I'm not looking for examples on how to handle the two issues with view models above but simply an explanation on why I should use view models at all.
Where do I put my validation code?
On the view models you should validate everything that's specific to the application like for example the date should be in en-US format culture, ....
I need to add code to map between business objects and view models.
That's why there are tools such as AutoMapper.
Different problems arise when you use directly your domain models in the views:
The views have specific requirements for displaying the data (localization/globalization) so you either end up with spaghetti code in your views or you put this code on your models so that they become less reusable in other applications because you have polluted them with specific presentation stuff
You have different validation requirements based on the view. Let's take for example the case of Add and Update views. In the Add view the Id property won't be needed and it won't be required because you will be inserting a new item. In the Update view the Id property would be required because you would be updating an existing item. It would be difficult to handle those specific validation rules without view models.
The models might contain properties such as IsAdmin and then I am leaving to your imagination the implication of a controller action with the following signature:
[HttpPost]
public ActionResult CreateUser(BusinessObjectUser user) { ... }
assuming that you have hidden this property from the underlying form by not including it.
The business models don't change often whereas the UI could change more often. What if your customer asks you to split your screen in two? The way you present the information changes and the way it is formatted also change. If you use your models directly into the views the spaghetiness of your views becomes worse and worse with every change.
About 60% of the question I am answering on StackOverflow in the asp.net-mvc tag wouldn't have been asked if the OP have used a view model.
Three reasons to why you should use View Models:
Reason 1: Remove logic from your Views
Reason two: Security
Reason three: Loose coupling
Below link may useful:
http://www.codeproject.com/Articles/223547/Three-reasons-to-why-you-should-use-view-models
First off, allowing the Views to have direct access to the Business Objects in ASP.NET MVC introduces some extra security concerns. ASP.NET MVC does a lot of Model binding for you when a user posts a value back to your controller. This can open you up to various kinds of attacks. By introducing a View Model in between, you can be sure that only the fields you are interesting are bound (because the ViewModel will only contain the fields you care about).
As for the other questions:
Where do I put my validation code?
I use DataAnnotations on my ViewModels directly. That allows me to use the Model validation architecture built in to ASP.NET MVC. If there's any validation beyond that I handle it in my controller.
I need to add code to map between
business objects and view models.
True. But using something like AutoMapper can greatly reduce the amount of boilerplate code that you have to write by hand.
MVC is easy to understand and has very little overhead. But those that have used the Model-View-Controller pattern for some time know that it isn't perfect. Not even close. The Model-View-ViewModel pattern offers an interesting alternative.
It is important to understand that the Model-View-ViewModel pattern extends the Model-View-Controller pattern. It isn't a dramatic paradigm shift if you are used to MVC. Even though the advantages of MVVM are subtle, they are profound.
What are some of the advantages MVVM has over MVC?
Better Separation of Concerns
Improved Testability
Transparent Communication
What is the purpose of the code behind view file in ASP.NET MVC besides setting of the generic parameter of ViewPage ?
Here's my list of reasons why code-behind can be useful taken from my own post. I'm sure there are many more.
Databinding legacy ASP.NET controls - if an alternative is not available or a temporary solution is needed.
View logic that requires recursion to create some kind of nested or hierarchical HTML.
View logic that uses temporary variables. I refuse to define local variables in my tag soup! I'd want them as properties on the view class at the very least.
Logic that is specific only to one view or model and does not belong to an HtmlHelper. As a side note I don't think an HtmlHelper should know about any 'Model' classes. Its fine if it knows about the classes defined inside a model (such as IEnumerable, but I dont think for instance you should ever have an HtmlHelper that takes a ProductModel.
HtmlHelper methods end up becoming visible from ALL your views when you type Html+dot and i really want to minimize this list as much as possible.
What if I want to write code that uses HtmlGenericControl and other classes in that namespace to generate my HTML in an object oriented way (or I have existing code that does that that I want to port).
What if I'm planning on using a different view engine in future. I might want to keep some of the logic aside from the tag soup to make it easier to reuse later.
What if I want to be able to rename my Model classes and have it automatically refactor my view without having to go to the view.aspx and change the class name.
What if I'm coordinating with an HTML designer who I don't trust to not mess up the 'tag soup' and want to write anythin beyond very basic looping in the .aspx.cs file.
If you want to sort the data based upon the view's default sort option. I really dont think the controller should be sorting data for you if you have multiple sorting options accessible only from the view.
You actually want to debug the view logic in code that actuallky looks like .cs and not HTML.
You want to write code that may be factored out later and reused elsewhere - you're just not sure yet.
You want to prototype what may become a new HtmlHelper but you haven't yet decided whether its generic enough or not to warrant creating an HtmlHelper. (basically same as previous point)
You want to create a helper method to render a partial view, but need to create a model for it by plucking data out of the main page's view and creating a model for the partial control which is based on the current loop iteration.
You believe that programming complex logic IN A SINGLE FUNCTION is an out of date and unmaintainable practice.
You did it before RC1 and didn't run into any problems !!
Yes! Some views should not need codebehind at all.
Yes! It sucks to get a stupid .designer file created in addition to .cs file.
Yes! Its kind of annoying to get those little + signs next to each view.
BUT - It's really not that hard to NOT put data access logic in the code-behind.
They are most certainly NOT evil.
Ultimately, the question you ask yourself is this:
Does this code A) Process, store, retrieve, perform operations on or analyze the data, or B) Help to display the data?
If the answer is A, it belongs in your controller. If the answer is B, then it belongs in the view.
If B, it ultimately becomes a question of style. If you have some rather long conditional operations for trying to figure out if you display something to the user, then you might hide those conditional operations in the code behind in a Property. Otherwise, it seems like most people drop the code in-line to the front end using the <% %> and <%= %> tags.
Originally, I put all my display logic inside the <% %> tags. But recently I've taken to putting anything messy (such as a lengthy conditional) in my code behind to keep my XHML clean. The trick here is discipline - it's all too tempting to start writing business logic in the code behind, which is exactly what you should not be doing in MVC.
If you're trying to move from traditional ASP.NET to ASP.NET MVC, you might aviod the code behinds until you have a feel for the practices (though it still doesn't stop you from putting business logic inside the <% %>.
There isn't a purpose. Just don't use it except for setting the model
ViewPage<Model>
See this blogpost for more info.
At this Blogpost is a working example of removing the code behind.
The only problem I'm stuck with is that it is not able to set namespaces on the class.
The codebehind provides some of the strong typing as well as the intellisense support that you get in the view. If you don't care about any of these two features, you can remove it.
For example, I typically use the NVelocity ViewEngine because it's clean and pretty straight forward.
This is a great question. Doesn't MVC exist in the ASP.NET environment, without using the specific MVC pattern.
View = aspx
Controller = aspx.cs (codebehind)
Model = POCO (Plain Old C#/VB/.NET objects)
I'm wondering why the added functionality of MVC framework is helpful. I worked significantly with Java nd MVC and Java Struts several years ago (2001), and found the concepts in MVC to be a solution for the Internet Application organization and development problems at that time, but then found that the codebehind simplified the controller concept and was quicker to develop and communicate to others. I am sure others disagree with me, and I am open to other ideas. The biggest value I see to MVC is the front controller pattern for Internet development, single entry source for Internet Application. But, on the other hand, that pattern is fairly simple to implement with current ASP.NET technologies. I have heard others say that Unit Testing is the reasoning. I can understand that also, we used JUnit with our MVC framework in 2001; but I have not been convinced that it simplifies testing to use te MVC framework.
Thanks for reading!