MVC razor view #model - is it possible to define multiple interfaces - asp.net-mvc

Have Interface1 and Interface2, the question is it possible to use them in partial view as following
#model Interface1, Interface2
my studio underline everything as wrong statement.
I do realize that I can define Interface which inherited from Interface1, Interface2 as a workaround this limitation. But it would be nice to know if there some special syntax to do it directly.
Thanks.

Just use a single interface that that implements 2 or more interfaces

Related

What is the VB equivalent of #model dynamic in C# Razor?

I have a View (vbhtml) in ASP.NET MVC 5 which uses a dynamic model, I know it's easy in C# to do this by writing
#model dynamic
But how can I specify this in vbhtml?
There is no equivalent of C# Dynamic in vb.net instead you can replace dynamic into Object and make sure you set option strict off.
The dynamic keyword brings Option Strict Off equivalent functionality to C#.
The key difference based on MSDN is:
If a late-bound call is made to an object that implements the
IDynamicMetaObjectProvider interface, Visual Basic binds to the
dynamic object by using that interface. If a late-bound call is made
to an object that does not implement the IDynamicMetaObjectProvider
interface, or if the call to the IDynamicMetaObjectProvider interface
fails, Visual Basic binds to the object by using the late-binding
capabilities of the Visual Basic runtime.
And since you mentioned:
The problem is with late binding not option strict
You reference a dynamic object by using late binding. In C#, you specify the type of a late-bound object as dynamic. In Visual Basic, you specify the type of a late-bound object as Object. For more information, see dynamic (C# Reference) and Early and Late Binding (Visual Basic).
You can create custom dynamic objects by using the classes in the System.Dynamic namespace. For example, you can create an ExpandoObject and specify the members of that object at run time. You can also create your own type that inherits the DynamicObject class. You can then override the members of the DynamicObject class to provide run-time dynamic functionality.
An example could be found in MSDN.
Update:
VB binder does not work with things typed as dynamic in medium trust. Try setting your app to full trust. Also The Option Strict On disallows late binding In VB.Net. If you are trying to use strongly typed helpers like Html.EditorFor while your view is not strongly typed to a class, So you need to indicate the model type in the #Page definition:
<%# Page
Language="VB"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage(Of YourApplication.YourModelClass)" %>
Then you can safely use those helper methods.
VB equivalent of #model dynamic in C# Razor is #ModelType

Calling templates using razor multiline calls

I'm starting in ASP.NET MVC/razor and I need to implement a div that will have a variable number of different buttons.
I heard something about implementing templates and calling them this way, in a razor view:
#Project.UI.ActionButtonsPanel()
.AddButton(ActionButtons.Submit)
.AddButton(ActionButtons.Cancel, ActionButtons.Reset)
.AddButton(new CustomActionButton(0, "Execute", ActionButtonGroup.Primary, "url"))
.AddButton(new CustomActionButton("Accept", ActionButtonGroup.Primary, "url"))
.HtmlAttribute(new { id=""})
.Render();
But, after a research I was not able to find anything talking about this.
Is this implementation possible? If so, how can I do this?
You need to wrap the entire expression in parentheses.

How to implement a custom view engine in ASP.Net MVC that (sorta) isn't file-based?

I've created a fairly generic view engine that I created initially without aiming toward ASP.Net MVC. Now though, I think it would be a good idea to have it to where it can at least be easily used by MVC projects. I'm wondering if my project would map well to the ASP.Net MVC style though.
The problem I'm having is that my view engine generates everything at compile-time via T4 templates. This means that everything is statically typed for the most part. Most of MVC seems to be a bit loosely typed however.
So for some view you might have this code generated:
class MyView{
public string Foo{get;set;}
public int Bar{get;set;}
public string Render(){
return "This is my view: "+Foo+(string)Bar;
}
}
And because of how it works, even if there is a views/FooView.html file, it may get processed into a class named MyView.
So how exactly is the best way to assign ViewData to say Foo and Bar of MyView? Should I just impose the limitation that you can only use a single field in the views(basically being a ViewData) or?
The other major problem I see is that MVC is almost completely file based. When you say RenderView("MyView",data); it will look in /views/ for a file named MyView.aspx or whatever(you can change where it looks and the file extension of course). The problem is that MyView could have been compiled from a file named FooView.html. Should I basically just generate a huge list for every view available with their mappings from class name to filesystem name? Or is there a better way?
Note: Because I generate all the views(and possibly could generate the MVC view engine) from a T4 template, this means I could write huge lists and other extremely tedious or bad code. But I feel like there is a better way than a huge list in this case, and that there will be underlying problems with only keeping a list.
You may extend my T4 based view engine to create your class file from your model, compile it in memory and cache it, and pass your view model to the compiled assembly via reflection.
http://mvct4viewengine.codeplex.com/

Adding Custom attributes to the page directive in asp.net-mvc

I have created a base class that derives from ViewPage with a custom public attribute that I want to be able to set in the #page directive however I am getting the following error.
Error 24 Error parsing attribute 'attrame': Type 'System.Web.Mvc.ViewPage' does not have a public property named 'attrname'.
the directive looks as so
<%# Page Title="" Language="C#" AttrName="Test" Inherits="Web.Helpers.Views.BaseViewPage" %>
The problem seems to be that it doesn't recognize the base class from the Inherits tag. I thought this should work from reading around on the internet. Has anyone else tried this or have any idea why this isn't working?
This is unfortunately not supported in ASP.NET MVC 1.0 or ASP.NET MVC 2.
The reason for this is an implementation detail of some MVC-specific parser logic that is used in ASPX/ASCX/MASTER files. If the view page's (or view master page's or view user control's) base type is a generic type there is logic that hard-codes the base class for the ASP.NET parser's sake to be just regular ViewPage (or ViewMasterPage or ViewUserControl).
Because the ASP.NET parser looks at the base class that MVC tells is, it will only ever be ViewPage, and thus it doesn't recognize the new property that you added, and thus it reports an error.
It is worth mentioning that this applies only if the base class you specify in the view page is generic. If you use a non-generic type then it should work just fine and you should be able to set values on custom properties.
I can think of two workarounds:
1) Create custom page base types for every type you need. This solution is rather easy, though cumbersome:
public class MyBasePage<TModel> : ViewPage<TModel> {
...
}
public class CustomerPage : MyBasePage<Customer> { }
public class ProductPage : MyBasePage<Product> { }
And then use only the non-generic derived types in the view pages' "inherits" attribute.
2) Copy the MVC source code (see links below) from the ViewTypeParserFilter into your project and make some small changes. The key method to change is the PreprocessDirective() method. Towards the bottom is an if() statement that overrides the "inherits" attribute to be one of a few hard-coded values. As you'll see, this code runs only if the declared base type is generic (hence my earlier comment).
It's up to you to decide exactly how you want to change this code. The key thing here is that the type name must be a type that .NET's Type.GetType() method can understand. That is, you have to use the CLR syntax for constructs such as generics and not the C# or VB syntax. For example, while in C# you can say:
System.Web.Mvc.ViewPage<Customer>
In the CLR syntax it's something like:
System.Web.Mvc.ViewPage`1[MyApp.Models.Customer]
Hopefully one of the two options above suits you.
Source code links:
ASP.NET MVC 1.0 source code download
ASP.NET MVC 2 RC source code
You need to set the base type in the web.config to get around this. Go to
/Views/Web.config
and change the
configuration/system.web/pages
and change the attribute pageBaseType to your class.
<pages pageBaseType="Web.Helpers.Views.BaseViewPage" {your other attributes here} />

Is there an equivalent to Monorail view components for the ASP.Net MVC Framework?

I make heavy use of View Components in some of the larger applications I've built in Monorail - What is the equivalent approach in ASP.Net MVC for a view component, that can support sections etc.?
Actually you have several options to create the equivalent of a ViewComponent in ASP.NET MVC, depending in the complexity of your component. I use these two approaches which are the more mvc-ish of the options I am aware of.
1:
The simplest thing is to create a ViewUserControl and display it using Html.RenderPartial with the helper. The ViewUserControl is a simple piece of markup with no backing controller (I think you can put a codebehind file if you want).
Optionally, you can pass a model object or the entire ViewData dictionary to the view when calling RenderPartial, like this:
<% Html.RenderPartial("TopBar", model); %>
"TopBar" is an ascx page. This works anywhere, in master pages and in normal views.
2:
If you want your component to have more complicated logic or to access datasources, IoC, etc, then you can use Html.RenderAction which is an extension method found in the Microsoft.Web.Mvc assembly. I am using this out of the mvccontrib distribution. It works like this, you need to create a normal controller with all the logic you need, then create some views and all of these things become your component, for example:
public class AboutComponentController : Controller {
public IRepository Repository{ get; set; }
public ActionResult Detail() {
var lastEvent = Repository.FindAll<Auditoria>().FirstOrDefault();
return View(lastEvent);
}
}
Notice how I have a reference to an IRepository which is going to be injected with IoC (Windsor in my case) and I can do anything a normal controller would do.
Now, in any page (master or normal) where you want to use your component, import Microsoft.Web.Mvc and call Html.RenderAction with the appropriate parameters. This will create a mini mvc pipeline that creates the controller, resolves the view, etc., just like a Monorail ViewComponent. I prefer to use the lambda based variation of the method, like this:
<% Html.RenderAction<AboutComponentController>(x => x.Detail("a message"));%>
Unfortunately, the only way to pass parameters is to use the method call itself, which in turn must be unique in the controller. Still needs some work to resemble a ViewComponent.
I don't use masterpages or layouts in the views of my components since they are composition elements themselves.
Remember that when using the Webforms view engine, you can have strongly typed views if you like to have intellisense when using the Model variable in code blocks.
The beauty of this is that you can mix view engines with these approaches, I usually create the components in nvelocity and display them in aspx pages, etc.
I now there can be issues with caching of the partial views but I haven't run into any so far. I am sure there are other options (like subcontrollers in mvccontrib) but this is usually enough for simple cases. Of course you can use normal ASP.net components in your aspx view pages but that would be cheating right? hehe. I hope it helps.
Phil Haack blogged about creating areas to group controllers into sub-folders/sections similar to MonoRails.

Resources