Validation on RenderAction

by 26. July 2010 18:51

Consider the following parent page Index.aspx

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<HomeData>" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<div style="background-color:Red;">
<% Html.RenderAction("SignUp", "Account"); %>
</div>
</body>
</html>

Notice the RenderAction for the following SignUp.ascx page.

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<SignUpData>" %>

<% using (Html.BeginForm("SignUp", "Account"))
{ %>
<div>
<%: Html.LabelFor(m => m.Email) %>
</div>
<div>
<%: Html.TextAreaFor(m => m.Email) %>
</div>
<div>
<%: Html.ValidationMessageFor(m => m.Email) %>
</div>
<br />
<input type="submit" />
<%} %>

My SignUpData model looks something like this:

public class SignUpData : BaseViewData
{
/// <summary>
/// The email address you are signing up with.
/// </summary>
[DataType(DataType.EmailAddress)]
[Required(ErrorMessage = "Email is required.")]
[StringLength(200, ErrorMessage = "Email must be 200 characters or less.")]
[RegularExpression(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", ErrorMessage = "Valid Email Address is required.")]
[DisplayName("Email Address")]
public string Email
{
get;
set;
}

...

 

My controller AccountController looks something like this:

[HttpPost]
public ActionResult SignUp(SignUpData data)
{
if (ModelState.IsValid)
{
return View("SignUp", data);
}

return RedirectToAction("Index", "Home", data);
//return View();

}

The problem I have is that although this all renders nicely when i enter an invalid email, it *does* set the ModelState as invalid and if u use Ajax i can get things working nicely.

However, I want this to work on the server too. I'm not sure whether there is NOW any way to pass this invalid model state such that the original Index page (top) is rendered with the RenderPartial called such that the invalid email address state is passed in and rendered - i just don't see the best practice way (sure, i can think of 50 hacks) to get the error information back on the postback (ideally it would work OOTB as it does normally).

I also disable Session state in my applications so i can't use TempData.

Tags: , ,

tech

Ideas on Global Filter Providers in MVC 3

by 23. July 2010 02:15

Today I enjoyed a session (technically i'm still listening) by Phil Haack of Microsoft at the Virtual MVC conference discussing MVC 3. He discussed Global Filter providers which will enable you to apply a filter attribute to a number of controllers in pretty much a single line of code. He also showed Conditional Filters which can be used to conditionally apply a filter based on some code check (his example was a check as to whether we were in debug mode).

I have been working with filters today and it solved something i was thinking about today. I like the idea of extending it and i suspect that (and i don't know any more about them than what i saw on the slides) conditional filters *may* solve a number of things i'd like to be able to do.

So I asked a question about using RegEx and patterns with the filters. What I mean by that is being able to read the metadata of the controller classes and methods and being able to apply filters conditionally to them.

For example:

 

  • Apply a trace filter to an methods marked with [HttpPost]
  • Apply a debug filter whenever a method in the "AccountController" or "ProfileContoller" is called.
  • ... even apply a debug filter whenever a method called "Save" is called in the "AccountController" or "ProfileContoller" is called.
These are some basic examples, but with the ability to apply global filters combined with an ability to read metadata on controllers, methods and so on (and perhaps even the state of the user or application) you can imagine a host of neat filters that could be quickly added to your code.

Further, being able to specify these rules declaratively and using a declarative service locator technique to accomplish DI for your filters could mean it would be super easy to attach filters to your applications without recompiling.

 

Tags: , , ,

tech

Adding a foreign key relation in Entity Framework 4 (EF4)

by 8. July 2010 15:52

The EF4 bits are excellent but one of the pains i have had was how to use the EF designer and add a foreign key mapping to an entity. So you have a User entity and an Address entity and the Address entity has a UserId foreign key that links to the User Id property.

I kept running into an issue that said the Address entity wasn't mapped and specifically the foreign key. I had no idea what to do to solve this. I checked the Xml behind the EDMX and found that not storage model had been created to allow that mapping. This seems odd to me. I would think it would create it when you are working in the designer and make the update upon commit!?

 

Anyway, the resolution to this is to right-click the model and say Generate Database from Model. This creates the data scripts and once executed it creates the tables in your database and at the same time updates you entity model to allow the mapping to happen. All works after that.

Tags: , ,

tech

Programmatic Screen Navigation in SketchFlow

by 8. May 2010 23:32

If you want to navigate between screens in SketchFlow you can put this class at the top level in your namespace and it will do the bulk of the work for you. The code also details the meaning of the parameters you need to pass in to make it work.

/// <summary>
/// A global navigator instance that allows programmatic 
/// navigation between screens in SketchFlow.
/// </summary>
public static class Navigator
{
    /// <summary>
    /// Adds a navigation option to the global navigator.
    /// </summary>
    /// <param name="target">The namespace qualified name of the page we are navigating to.</param>
    /// <param name="eventname">The name of the event to watch for in the "obj" parameter</param>
    /// <param name="obj">The object, such as a button.</param>
    public static void Add(string target, string eventname, DependencyObject obj)
    {
        // Create a navigation instance of the screen we are navigating to
        Microsoft.Expression.Prototyping.Behavior.NavigateToScreenAction navigateAction 
            = new Microsoft.Expression.Prototyping.Behavior.NavigateToScreenAction();
        navigateAction.TargetScreen = target;
        
        // create a trigger to fire the action
        System.Windows.Interactivity.EventTrigger clickTrigger 
            = new System.Windows.Interactivity.EventTrigger(eventname);
        clickTrigger.Actions.Add(navigateAction);            
        
        // associate the trigger with the object
        System.Windows.Interactivity.TriggerCollection triggerCollection 
            = System.Windows.Interactivity.Interaction.GetTriggers(obj);
        triggerCollection.Add(clickTrigger);            
    }
}

To use it, you can put this after InitializeComponent(); in the class on the screen you are invoking the action from.
Navigator.Add("MyScreens.Screen_1_4", "Click", this.MyButton);

Tags: , , ,

tech

Thoughts on oData

by 10. April 2010 15:38

I've heard oData uses quite a lot recently but been too bust to check it out. Well, now i've torn ligaments in my leg i'm getting time to read some of this stuff.

So, oData (Open Data Protocol) "provides a way to unlock your data and free it from silos that exist in applications today". An excellent example of its usage was demonstrated by Scott Hansleman where oData could be served from StackOverflow allowing developers to write oData queries directly against the Xml that is returned. Applying this idea to Twitter you may have something like this.

 

It got me thinking however - this is very powerful stuff and in many cases perhaps too powerful. There is a lot to be said in encapsulating functionality such as this being API's - it's easy to document, easy for developers to follow and the various flows required for an experience with the data provider can be optimized.

However, there is a very powerful middle ground you don't really get with many of the API's today. With oData you could allow others to write the API's that interact with your system. So, if your system is an oData provider you can have several other developers who understand your data well enough that they can write various API's against your data to expose a host of different kinds of services. This is different from the current model - popularized in Twitter et al - whereby all people write against a strict API and doing anything out of the box (or a bug) requires waiting for Twitter to fix their API.

In the oData model you can have many API's and you choose the one that works for you. Something like this.

 

 

Tags: , ,

tech