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
Related
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
I am not able to find anything on MSDN that sheds some light on how the following feature is supposed to be used:
#{ Func<String, HelperResult> a = #<div>#item</div>; }
#a("Hey!");
Renders as:
<div>Hey!</div>
In particular am interested in knowning:
can it take more than one parameter?
can I specify the name of the variable other than #item (that goes by default)?
can I use any other type of the resulting value?
The only evidence out there is that the HelperResult type is for internal use only, which makes me think it is not supposed to be used and renders this feature undocumented giving no guarantees that it will be there in the next release.
A general question would be can I use it or not? If so, how?
Phil Haack, who was on the ASP.NET Team, at Microsoft posted this blog post regarding templated razor delegates.
Templated Razor Delegates
I'm trying to use DotNetOpenAuth with Razor/MVC3. Most of DotNetOpenAuth HTML helpers are accepting System.Web.UI.Page as one of parameters, which works fine standard using WebForms engine but does not with Razor. Is it possible to cast dynamic WebPageBase.Page into System.Web.UI.Page somehow?
Thanks, Antonin
System.Web.UI.Page is part of the Web Forms page model and is totally unrelated to Razor. A Razor page inherits from System.Web.WebPages.WebPage which isn't part of the same hierarchy. As GvS mentioned, the "Page" property is a different object in Razor. In Razor, that property is just a C# dynamic object that provides a shortcut for accessing PageData values. For example: PageData["foo"] is the same as Page.foo.
They are totally different objects. So, no, you cannot cast or convert into a System.Web.UI.Page.
But this article might help you further.
Ok, this is for me a very tough challenge. We're taking our existing ASP.NET website and converting (redesigning the PL only) to MVC. Our site is very complex. But the hard part is to convert the existing custom controls to MVC equivilant. The custom controls (I am not talking about user controls) are just of course a class currently that inherits System.Web.UI.Control and uses that object throughout. For example, we have some properties at the top of this existing custom class like so:
Dictionary<int, Control> configControls;
DropDownList kControl;
CheckBox confirmBox;
These all are variables of type Web controls in classic ASP.NET.
So I figured maybe what I could do (without building entire new custom controls from scratch) is to use the HtmlHelper object. So I tried this:
(include first the using statement that includes System.Web.MVC.Html at the top of my new custom class in our new web project)
private HtmlHelper helper;
Dictionary configControls;
helper.DropDownList
but this is not working. I guess I can't use this object just like this ?? I figured I can use HtmlHelper in the Dictionary and then make variable types off of helper. but those are just extension methods, not objects
I don't know of an equivalent to something like the generic "Control" we had available to us to inherit from such as in classic ASP.NET. Surely it won't be the same in MVC obviusly (stateless and a completely diff way of doing things) but what can I use in MVC with the same concept sort of?
So I figured maybe what I could do (without building entire new custom controls from scratch) is to use the HtmlHelper object. So I tried this:
(include first the using statement that includes System.Web.MVC.Html at the top of my new custom class in our new web project)
private HtmlHelper helper;
Dictionary configControls;
helper.DropDownList
but this is not working. I don't even know if this approach will work in my custom control. And when I try to use my helper variable, I get no extension methods unless it's inside an existing extension method where the signature has an HtmlHelper param passed in. So when I create that private variable just in my custom class outside, I get nothing in intellisense to choose from when doing "helper.". So do I need to define that object like this: ?
private HtmlHelper htmlHelper = new HtmlHelper();
but it's asking for a ViewContext and an IViewDataContainer as params. If I'm building out a custom method that knows nothing yet about its view (it shouldn't need to) because I'm simply creating strings of HMTL in this custom class to be passed to the Extension method to ultimately spit out fields then maybe I can't use HtmlHelper this way in a custom class like this.
So can I use that object in a way instead of "Control"? Maybe I can even in my dictionary variable use type object in place of control ? I don't know and then cast object to type HtmlHelper when I need to use or reference that value from the dictionary? But for now, I figured I can use HtmlHelper object in the Dictionary and then make variable types off of helper. but those are just extension methods, not objects.
I hope I am making any sense here when you read this.
I just blogged about this last night, some of this might be helpful for you.
WebForms And MVC In Harmony — Almost…
Basically it discusses some options for emulating "WebControls" using MVC.
Additionally, you can still use WebControls like you could before (granted they may not work if they need things like the ViewState). The problem I've discovered with that is you have a disconnect from the inline render code and the WebControls themselves.
I did write this method last night which let you use WebControls with inline code.
using System.Reflection;
using System.IO;
using System.Web.UI;
using System.Web;
using System.Web.Mvc;
public static class MyExtensionMethods {
//example method - renders a webcontrol to the page
public static void RenderControl(this HtmlHelper helper, Control control) {
//perform databinding if needed
MethodInfo bind = control.GetType().GetMethod("DataBind");
if (bind is System.Reflection.MethodInfo) {
bind.Invoke(control, null);
}
//render the HTML for this control
StringWriter writer = new StringWriter();
HtmlTextWriter html = new HtmlTextWriter(writer);
control.RenderControl(html);
//write the output
HttpContext.Current.Response.Write(writer.ToString());
//and cleanup the writers
html.Dispose();
writer.Dispose();
}
}
//then used like...
<% int[] numbers = { 1, 2, 3, 4, 5 }; %>
<% this.Html.RenderControl(new DataGrid() { DataSource = numbers }); %>
Just an interesting concept you might be interested in.
Short of hacking webforms controls into your MVC application, servercontrols with many methods do not map to MVC.
They are replaced by partials and controllers(or subcontrollers if you like that sort of thing).
If all you want to do is render some HTML based on a few parameters, then a Helper is what you are after. Static Class, static methods. If however, you need to keep state, and do a bunch of stateful stuff, then a partial, JS, and controller(or subcontroller) are really what you are after.
Server Controls that manage their own state really are a thing of the past in MVC.
Remember that MVC is an attempt to use the web the way it was meant to work, particularly if you bring REST into the picture. Webforms is a fudge to make the web work like windows forms.
I would create needed business logic, shared partial view (probably, with quite a lot of well structured javascript lines attached) and seperated controller.
Then i would use this bunch of code through partial request technique.
Not sure how much this will be of help but, do have a look at this series of blog post
Custom controls everywhere
Also have a look at the Catharsis project
Web-Application Framework - Catharsis - Part I - New Solution
The codeplex URL for the same is
Catharsis
This project has some good examples of control creating for 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} />