Andrey Shchekin » ASP.Net Sat, 13 Apr 2013 23:16:21 +0000 en-US hourly 1 http://wordpress.org/?v=4.2.14 Multiple submit buttons with ASP.NET MVC: final solution /2010/03/15/multiple-submit-buttons-with-asp-net-mvc-final-solution/ /2010/03/15/multiple-submit-buttons-with-asp-net-mvc-final-solution/#comments Mon, 15 Mar 2010 18:00:00 +0000 /index.php/2010/03/15/multiple-submit-buttons-with-asp-net-mvc-final-solution/ Most people coming to ASP.NET MVC tend to have similar problems. Most of them are related to refreshed understanding of HTML+HTTP limitations. Some are mitigated by ASP.NET MVC (checkboxes), but a lot require custom solutions.

One of the more common problems I get asked about by every second person learning MVC is how to make a form with two independent submit buttons, where both should submit the same data, but a have a different processing logic. For example, form may have a Save Draft button and Publish button.

Until now, I always said that it is possible, Google/StackOverflow and find out. But I just had to build such kind of thing myself, so I finally took some time to find/build the final solution.

So, let’s look at the solutions available online.

StackOverflow question “How do you handle multiple submit buttons in ASP.NET MVC Framework?” is the starting point, but it does not provide a good solution for the situation where you need to send same data for both buttons, except the solution to switch by button name, which is duct-taping.

Post “ASP.NET MVC — Multiple buttons in the same form” by David Findley is much more interesting, since his AcceptParameterAttribute is very similar to my solution. However, this has several (small) shortcomings: first, you have to specify what is actually an action you want to do in an attribute. So even if you name your action “SaveDraft”, you will still need to specify AcceptParameter(Name=“button”, Value=“saveDraft”). Another thing is need to put [ActionName] on your actions, which is understandable, but a bit confusing for people who do not yet know the idea.

So, I wanted to build the solution that would require at most one attribute, and where the name of action method corresponds to the attributes of the button. Also, since <input> value is the thing being shown in the button, and <button> value has issues in IE, I decided to go with name attribute and ignore value completely (which seems to be consistent with David Findley’s commenters).

Now, the solution. Basically, instead of using ActionMethodSelectorAttribute, I am using ActionNameSelectorAttribute, which allows me to pretend the action name is whatever I want it to be. Fortunately, ActionNameSelectorAttribute does not just make me specify action name, instead I can choose whether the current action matches request.

So there is my class (btw I am not too fond of the name):

public class HttpParamActionAttribute : ActionNameSelectorAttribute {
    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo) {
        if (actionName.Equals(methodInfo.Name, StringComparison.InvariantCultureIgnoreCase))
            return true;

        if (!actionName.Equals("Action", StringComparison.InvariantCultureIgnoreCase))
            return false;
        
        var request = controllerContext.RequestContext.HttpContext.Request;
        return request[methodInfo.Name] != null;
    }
}

How to use it? Just have a form similar to this:

<% using (Html.BeginForm("Action", "Post")) { %>
  <!— …form fields… -->
  <input type="submit" name="saveDraft" value="Save Draft" />
  <input type="submit" name="publish" value="Publish" />
<% } %>

and controller with two methods

public class PostController : Controller {
    [HttpParamAction]
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult SaveDraft() {
        //…
    }

    [HttpParamAction]
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Publish() {
        //…
    }
}

As you see, the attribute does not require you to specify anything at all. Also, name of the buttons are translated directly to the method names. Additionally (I haven’t tried that) these should work as normal actions as well, so you can post to any of them directly.

There is some room for improvements (hardcoded “action” as a default action name), but in general I’m satisfied with this solution.

]]>
/2010/03/15/multiple-submit-buttons-with-asp-net-mvc-final-solution/feed/ 89
Putting Web snapshots to practical use /2008/09/28/putting-web-snapshots-to-practical-use/ /2008/09/28/putting-web-snapshots-to-practical-use/#comments Sun, 28 Sep 2008 10:50:04 +0000 /index.php/2008/09/28/putting-web-snapshots-to-practical-use/ I was always interested if the service that, for example, WebSnapr provides is practically useful. Having snapshots of a linked pages looks very cool indeed, but does not really provide much information, at least for me.

But recently I have found a nice use case for a similar service. For tables in my IoC Frameworks posts, I was using parts of a Zoho spreadsheet embedded through an iframe. However, Google Code wikis do not allow iframe embedding.

The easy solution was to use built-in wiki table markup, but in this case I would lose all color coding and ability to download the whole sheet as Excel. The interesting solution was to embed snapshot of an iframe, as an image. This would also allow me to solve the iframe problem for RSS readers that do not support them.

My original idea was to use Firefox or Chrome (via Chromium project) to do the snapshots, but I have not managed to use the Mono.Mozilla on Windows and I was too lazy to dive into Chromium.

IE was the simplest remaining choice, so using information from the great article of Peter Bromberg, I have built my own implementation of web snapshotting service. The main difference between my snapshots and other services is that my service can actually determine the correct size of the snapshot.

For example, this is a snapshot of my IoC frameworks table:

You can click it to see the source of the snapshot. As you can see, it has correct size (instead of being fixed to 1024×768 or another screen size). On an unrelated note, it is an updated version of framework comparison, now including LinFu (which was updated to pass all feature tests).

In Google Code it looks like this.

Additional interesting usage for this would be iframe-widget embedding to locations that do not support iframes. For example, it is possible to embed a list of RSS feed headers or twitter messages in Google Code using this technique.

You can svn-download source code from Google Code. It is really bare for now, no good error-handling and no resizing support (all snapshots are always displayed in full size). However it may be a good starting point.

Looking at this project, I think that it would be very interesting to have a .NET wrapper for Chrome APIs that would allow anyone to automate Chrome, which probably will make snapshot extraction much faster and not COM-reliant.

]]>
/2008/09/28/putting-web-snapshots-to-practical-use/feed/ 8
Some thoughts on ASP.NET AJAX Roadmap /2008/07/19/some-thoughts-on-aspnet-ajax-roadmap/ /2008/07/19/some-thoughts-on-aspnet-ajax-roadmap/#comments Sat, 19 Jul 2008 15:59:48 +0000 /index.php/2008/07/19/some-thoughts-on-aspnet-ajax-roadmap/ Coming from a vacation, I have just discovered a new ASP.NET AJAX roadmap. A post by Matt Berseth starts with a summary of discussion done so far.

I have some personal opinions on the question of ASP.NET AJAX since our team worked with it a lot. So I decided to write a post instead of just commenting existing discussion.

I think I have a slightly different approach to this framework, as compared to other posters. I do not have to choose jQuery/prototype/mootools over ASP.NET AJAX. It is obvious that chaining in jQuery makes life easier, and extending element whenever possible is also a friendly approach.

However, I will still use ASP.NET AJAX for the interoperability with ASP.NET architecture — I can have a JavaScript part for any control I have, and pass values between C# and JavaScript. Also the component lifecycle (being able to handle component references easily) is a large win for me.

What I do not like is the cumbersome get_/set_ requirement without a built-in shortcut (I described one solution earlier) and cumbersome event subscription.

Event Subscription

So, let’s start with this roadmap sample:

   1:  $query("textarea.rich")
   2:    .addHandler("focus", function(e) {
   3:      Sys.Debug.trace("focused into " + (e.eventTarget.id || "?"));
   4:    })
   5:    .setStyle("width", function() {
   6:      return (document.body.clientWidth — 10) + "px";
   7:    })
   8:    .create(Contoso.UI.RichTextBehavior, {
   9:      showToolbar: true,
  10:      fonts: ["Arial", "Times", "Courier"]
  11:    });

What we have now in our project for event subscription is similar to this

   1:  with (Auto.Events) {
   2:    when(textarea).gets('focus').call('textarea_got_focus').on(this);
   3:    when(list).has('changed').call(function() { alert('list_changed'); })
   4:  }

Which also alters dispose to remove the event handler (which is something very tedious to do manually).

So the thing I most dislike in new ASP.NET AJAX syntax is that it is not readable (just plain chaining). I see Event.Behavior as a beautiful solution, jQuery’s as acceptable one (not a language, just more precise naming shortcuts), and ASP.NET AJAX as not really usable.

Same goes to $listen — I just can not remember the correct order of arguments unless looking directly to the documentation or IntelliSense.

But I think that $listen is a great idea, and the solution should be very interesting (considering that IE does not support DOM mutation events).

Templates

Most popular post in my blog is about client-side databinding. I can not show a solution that we have built to solve this issue (we have built it specifically for a project which sources I can not show), so this post is somewhat useless.

I am very hopeful about ASP.NET AJAX’s UI Templates, but I am also thinking about several problems we encountered.  The first one is performance — it is absolutely necessary to pre-cache template binding function. The second one is binding repeated template with server controls.

There is a sample in the roadmap document:

   1:  <!--* for (var i = 0; i < features.length; i++) { *-->
   2:    <span>{{ features[i].name }}</span>
   3:    <!--* 
   4:      $create(Contoso.Tooltip, {
   5:        text: features[i].description
   6:      }, {}, {}, $element);
   7:    *-->
   8:  <!--* } *-->

but I am not sure if it is possible to do this:

   1:  <!--* for (var i = 0; i < features.length; i++) { *-->
   2:    <my:Label Text="{{ features[i].name }}" />
   3:  <!--* } *-->

where my:Label is a ASP.NET AJAX control. It was one the most complex problem for our client:Repeater, so I am interested if this would be implemented.

Now, in contrary to Matt Berseth, I am not really concerned with INotifyPropertyChanged, because it is extremely easy to write a meta-helper to auto-implement it for any given object or prototype in JavaScript.

What I am concerned with with is an idea to “expose methods such as insertRow” for Client DataSource. I do not have any rows in presentational model or my JavaScript arrays, so I strongly dislike this terminology.

The dream feature for me would be a Continuous LINQ for JavaScript, where you can dynamically bind to a dynamically filtered collection, bind to products.where(function(p) { return p.Cost > 5; }). We did a basic implementation for this kind of thing, and found it extremely useful for rich web application. You can have a live model behind a complex page, and never explicitly think of updating any part of the page when some collection in the model got changed.

Animation

I am not really interested in that — other frameworks do this kind of thing easier. And if ASP.NET AJAX is going to imitate jQuery syntax, as some people want, why not just use jQuery or mootools?

Other features

I think that built-in Drag&Drop may make my life easier, looking forward to it. Also, ASP.NET MVC integration has always been a must, it is nice to see it is coming.

All IDE changes are also very welcome.

Summary

In general, I like the proposed changes.

I have a feeling that Microsoft should add more meta helpers as Auto.properties. It is easy to do, but not obvious for the people who are not doing a lot of JavaScript. Also the auto-INotifyPropertyChanged and built-in ObservableCollection would fix databinding cumbersomeness in the same situation.

Also, I am interested in how are the specific technical challenges solved, but it too early to think about that right now.

]]>
/2008/07/19/some-thoughts-on-aspnet-ajax-roadmap/feed/ 3
Metaprogramming in JavaScript: Auto properties for ASP.NET AJAX /2007/10/08/metaprogramming-in-javascript-auto-properties-for-aspnet-ajax/ /2007/10/08/metaprogramming-in-javascript-auto-properties-for-aspnet-ajax/#comments Mon, 08 Oct 2007 19:20:05 +0000 /index.php/2007/10/08/metaprogramming-in-javascript-auto-properties-for-aspnet-ajax/ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: Consolas, "Courier New", Courier, Monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

Sometimes, large company is no better than several independent companies.
I always get this thought when looking at ASP.NET AJAX property accessors.

For people not familiar with the matter:
Microsoft ASP.NET AJAX requires developer to use property accessors to encapsulate javascript fields.
This would be a great idea, if only Microsoft IE supported javascript getters and setters.
Mozilla supports them, and Opera will in 9.50, but IE does not (they are not standard).
Also, IE does not have any hacky way to achieve the same effect (except in VBScript, which seems to be limited).

So in ASP.NET AJAX each property requires two functions named get_propertyName and set_propertyName.

Fortunately, javascript is very powerful in class member manipulation.
So I do not have to write things like this:

MyControl.prototype = {
    get_text : function() {
        return this._text;
    },

    set_text : function(value) {
        this._text = value;
    }
}

And I do not have to wait for auto properties as it is the case for C#.

Instead I just made an helper object named Auto and do things this way:

MyControl.prototype = {…}
Auto.properties(MyControl.prototype, [
    'text',
    'value',
    …
]);

Code for this helper can be very simple.
(in actual project I have additional complexity like Auto support for INotifyPropertyChanged).

var Auto = {
    property : function(prototype, name) {
        var getter = function() { return this['_' + name]; };
        prototype['get_' + name] = prototype['get_' + name] || getter;

        var setter = function(value) { this['_' + name] = value; };
        prototype['set_' + name] = prototype['set_' + name] || setter;
    },

    properties : function(prototype, names) {
        names.forEach(function(name) { 
            Auto.property(prototype, name);
        });
    }
}

This also requires forEach method on Array, but that one is pretty obvious.

I like to show this code when I hear about Javascript being assembly language and whatever-to-javascript compilation.

]]>
/2007/10/08/metaprogramming-in-javascript-auto-properties-for-aspnet-ajax/feed/ 1
Client-side databinding with ASP.Net AJAX Futures /2007/06/21/client-side-databinding-with-aspnet-ajax-futures/ /2007/06/21/client-side-databinding-with-aspnet-ajax-futures/#comments Wed, 20 Jun 2007 22:29:52 +0000 /index.php/2007/06/21/client-side-databinding-with-aspnet-ajax-futures/ Recently I got an optimization problem in ASP.Net.
To be short, I had a Repeater with custom (somewhat complex) template on my Page, and I wanted to reload it asynchronously.

The first solution was XP and didin’t consider performance at all: wrap Repeater inside an UpdatePanel.
The problem was that the entire Page had to be repopulated on server just to get to the Repeater.

That gave me a choice of two headaches:

  1. Put all Page/Controls data into ViewState and bloat bandwidth.
  2. Query all additional data on the reload request and increase load on database to get data that will be thrown away.

To be honest, I could solve (2) with server-side cache, but, in my opinion, caching does not make ugly solutions any better, just faster.

So, naturally, my thought was to query the data-only WebService and then populate the Repeater on client.

And it was interesting to find out that Microsoft already has a client-side data binding solution within ASP.Net AJAX Futures.
I have found an excellent article on this matter by Xianzhong Zhu, “Unveil the Data Binding Architecture inside Microsoft ASP.NET Ajax 1.0″ (Part 1, Part 2).

I will now give a quick summary on the overall client-side binding architecture.
In essence it is quite similar to the smart DataSource controls of ASP.Net 2.0:
There is a DataSource javascript component and a ListView javascript control with html template.
ListView passes data from/to DataSource control, and DataSource talks with a JSON Web Service as a backend.
Controls and their relations are described in text/xml-script (Futures-only feature).

Everything seems quite straightforward and easy to use, I was quite happy to find it.
One thing that bothers me is the performance of text/xml-script (it is parsed on client).
But it is a concern not related to the current story.
The other question is what to do when I want to databind a complex list (consisting of several embedded server user controls) ?
I am going to find it out real soon.

Along the way, I have also noticed Sys.Preview.Data also introduces DataSets/DataTables to javascript.
That is quite funny. Personally, I never really considered DataSets acceptable anywhere above Persistence layer.
But I already thought about Persistence/DataAccess concept in javascript when I saw Gears.
And DataSets seem to fit ‘nicely’ to some GoogleGearsDataSource (it would be quite an experience to actually see one in real code).

Well, javascript O/R Mapper, anyone ?

]]>
/2007/06/21/client-side-databinding-with-aspnet-ajax-futures/feed/ 1
Typed Repeater — ASP.Net Hack /2007/03/17/typed-repeater-aspnet-hack/ /2007/03/17/typed-repeater-aspnet-hack/#comments Sat, 17 Mar 2007 00:42:56 +0000 /index.php/2007/03/17/typed-repeater-%e2%80%94-aspnet-hack/ I wrote an article on Code Project about the way to implement generics in ITemplate.
I thought about including the whole article as a blog entry, but I am still fighting with code highlighting in blog.

Interesting fact about the Repeater solution is that you can use it to build any kind of generic asp.net control that will be perfectly specifiable in mark-up.
I am writing a GenericeControlBuilder that will not be specific to the single control type, but I didn’t have enough time to finish it yet.

The interesting question is how to implement fully generic TemplateContainerAttribute. Dynamic creation of the attribute is not a problem at all — solved in the article.
But the question is how to know right TemplateContainer type in a GenericControlBuilder that has no hardcoded information about the control it creates.
I consider adding another attribute that will specify how control type arguments map to the TemplateContainer type arguments.

public class Repeater {
    …

    [GenericTemplateContainer(typeof(RepeaterItem<>), UseParentTypeArguments=true)]
    public ITemplate ItemTemplate

    …
}

This is just to show the basic idea — this syntax is way too limiting.

]]>
/2007/03/17/typed-repeater-aspnet-hack/feed/ 2