Access code in a View via reflection - asp.net-mvc

I have an HtmlHelper CmsEntry that is used like this
<%= Html.CmsEntry("stores.buyourstuff")%>
This helper is used lots of times and I want to generate a list of all views that contain this helper.
The list should contain the Viewname and the key ("stores.buyourstuff").
Is there a tool or some sample code that already does this?

Look at official site.
Creating Custom HTML Helpers : The Official Microsoft ASP.NET Site
HtmlHelper have ViewContext property. It can access ViewData and TempData.

Related

Asp.Net MVC View function and ViewData

I have a small confusion in Asp.Net MVC
How rendering works in Asp.net MVC? We invoke View function - > Which will find the view and ask ViewEngine to parse it. Because of ViewEngine final outcome is HTML.
1)Whatever ViewData we create its available inside View. My understanding is ViewData and View function both are part of controller base class which makes ViewData available inside View function. Is it correct?
2)Finally Whats the point with WebViewPage class. ViewData keyword we use inside View(.cshtml) page is coming from the WebViewPage class. What role WebViewPage plays here.
I will really appreciate If you can point me with some good resource to understand the same
1) ViewData is merely a dictionary of objects that you can fill in the Controller and retrieve within the view. Since it is a dictionary of objects you need to cast the data back into the type it was to make full use of it.
2) WebViewPage is the base type of a razor page. It is the defined class which razor pages are compiled into at runtime. The web.config inside the views folder specifies the pageBaseType of the razor pages specifically to WebViewPage. These are two good resources regarding why its use and how you can extend it. Link1 and Link2.
Go peek inside he source code that renders the views
visit msdn

generate route url's in views or controllers

I am currently working with mvc4 and have a question around best practice.
I am passing back to my view, a number of links based on product information eg. product/1234 etc.
What is best practice, create the link using the routing engine in the controller and return the url as a property on the model object OR return the information to the view and generate the link there? I use automapper to map my DTO objects to model object, also considering creating the links during mapping.
What is the best practice with this?
You always create the link on the view.
The HTML helpers in the view can be used to ensure the link conforms to your routing rules.
You can see this in action in the many official ASP.NET MVC 4 Tutorials.
Why not in the controller or model?
The HTML helpers in the view are designed to create not just the URL, but also to wrap the URL in a fully formed anchor tag, etc. It isn't appropriate to have HTML in your model or controller as they shouldn't care how the data is displayed.
For example, the Html.ActionLink helper returns an a element.

How can I create an ASP.Net MVC Helper to inspect other inputs on a form

I would like to create an extension helper with the following signature:
public static MvcHtmlString
BindMissingFor(this HtmlHelper
htmlHelper, Expression> expression )
I would like this method to reflect through the supplied expression model and look for bind-able properties that have not already been bound on the form.
The use case is I would like to have some Views that only allow the user to interact with a portion of my Model. But, I would like to persist the entire model between multiple views (a wizard).
My current solution is to use a hidden-input for each field I don't want displayed. I'll probably do the same thing with this extension method, but I would like it to do the work for me instead of copy/pasting.
Is there a way to inspect the current form for inputs/selects from within an HtmlHelper extension method?
There is no way an html helper to know what happens in other parts of your view such as inspecting other form fields unless you pass it as argument. Also it is not very clear what you mean by look for bind-able properties that have not already been bound on the form. For persisting state in a wizard you might take a look at the Html.Serialize helper currently situated in the MVC Futures assembly. The idea behind this helper is that it allows you to serialize some model object (marked as [Serializable]) as hidden field inside a form and get its value back in a controller action using the [Deserialize] attribute. Behind the scenes it uses WebForms ViewState. You can also encrypt it. It is a good way of persisting state on the client between multiple pages.

Posting multiple values using MVC

I have a model with a property that points to a file that contains HTML. My strongly typed view to this model uses a custom HTML helper method to resolve and return the HTML from the file. Works great so far.
The HTML read from each file will contain various controls whose values I need to retrieve when the form is POSTed.
What would be the best way to have access to the POSTed control values in my controller method?
I would prefer a non jQuery solution, but I am not sure if the MVC framework can provide these values to me? Can it provide a list of key/value pairs to the controller somehow?
You could use the FormCollection in ASP.NET MVC.
public ActionResult SomeAction(FormCollection form) {
...
}
You have essentially two options.
1) Use the old fashioned Request variables as all we have done in ASP.NET web forms.
For example in your controller action method you can retrieve any value present on the form with the following method
public ActionResult SomeAction() {
var request = this.ControllerContext.HttpContext.Request;
bool boolParam = bool.Parse( request["boolParam"] ?? "false" );
}
2) Create a custom Model Binder to let the framework pack those values in a custom class object.
This method would be a little bit more difficult at the beginning because you have to create a custom Model Binder but it favour readability on your controller code. For further details on creating custom model binders give a look at the following links (you can find more with a simple search)
Custom Model Binder for Complex composite objects
Custom Model Binder and More UI Validation in ASP.NET MVC
A Custom ASP.NET MVC Model Binder for Repositories
Hope it helps
Is the content of the HTML files dynamic or known at design time? If you know it now, you could have each one post to it's own action and then strongly type the parameters.

Converting classic ASP.NET custom control to MVC

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.

Resources