Search Results

Search found 16680 results on 668 pages for 'python datetime'.

Page 471/668 | < Previous Page | 467 468 469 470 471 472 473 474 475 476 477 478  | Next Page >

  • How do I tell NHibernate to load a component as not null even when all its properties are null?

    - by SharePoint Newbie
    Hi, I have a Date class which wraps over the DateTime? class (aids in mocking DateTime.Now, our domain ,etc). The Date class class only has one protected property : DateTime? date public class Date { protected DateTime? date; } // mapping in hbm <component name="CompletedOn"> <property column="StartedOn" name="date" access="field" not-null="false" /> </component> From the nhibernate docs: Like all value types, components do not support shared references. The null value semantics of a component are ad hoc. When reloading the containing object, NHibernate will assume that if all component columns are null, then the entire component is null. This should be okay for most purposes. Can I override this behaviour? I want my Date class to be instantiated even if date is null. Thanks,

    Read the article

  • Getting the time interval between typing characters in a TextBox, in C#

    - by sama
    I have a form that has a TextBox and a Label and I want to get the time of the first character entered in the textbox. Then if the user enters more than ten charcaters, the time between the first charcter entered and the tenth charcter entered is displayed in the label. Can any one help me please? I'm using C# Here is the code but I cannot complete it and I have many things that need to be written but I don't know how to continue. using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; namespace n { public partial class Form1 : Form { int count=0; public Form1() { InitializeComponent(); } private void textBox1_TextChanged(object sender, EventArgs e) { DateTime t1 = new DateTime();// the time when entering the first charcter DateTime t2 = new DateTime(); t2 = System.DateTime.Now - t1; int index = textBox1.SelectionStart; Point p; p = textBox1.GetPositionFromCharIndex(index); Thread t = new Thread(counttext); t.Start(); label1.Text = "t2"; } private int counttext() { while (textBox1.Text.Length < 10) { count++; if (count == 10) return count; } } } }

    Read the article

  • How to maintain ComboBox.SelectedItem reference when DataSource is resorted?

    - by Dave
    This really seems like a bug to me, but perhaps some databinding gurus can enlighten me? (My WinForms databinding knowledge is quite limited.) I have a ComboBox bound to a sorted DataView. When the properties of the items in the DataView change such that items are resorted, the SelectedItem in my ComboBox does not keep in-sync. It seems to point to someplace completely random. Is this a bug, or am I missing something in my databinding? Here is a sample application that reproduces the problem. All you need is a Button and a ComboBox: public partial class Form1 : Form { private DataTable myData; public Form1() { this.InitializeComponent(); this.myData = new DataTable(); this.myData.Columns.Add("ID", typeof(int)); this.myData.Columns.Add("Name", typeof(string)); this.myData.Columns.Add("LastModified", typeof(DateTime)); this.myData.Rows.Add(1, "first", DateTime.Now.AddMinutes(-2)); this.myData.Rows.Add(2, "second", DateTime.Now.AddMinutes(-1)); this.myData.Rows.Add(3, "third", DateTime.Now); this.myData.DefaultView.Sort = "LastModified DESC"; this.comboBox1.DataSource = this.myData.DefaultView; this.comboBox1.ValueMember = "ID"; this.comboBox1.DisplayMember = "Name"; } private void saveStuffButton_Click(object sender, EventArgs e) { DataRowView preUpdateSelectedItem = (DataRowView)this.comboBox1.SelectedItem; // OUTPUT: SelectedIndex = 0; SelectedItem.Name = third Debug.WriteLine(string.Format("SelectedIndex = {0:N0}; SelectedItem.Name = {1}", this.comboBox1.SelectedIndex, preUpdateSelectedItem["Name"])); this.myData.Rows[0]["LastModified"] = DateTime.Now; DataRowView postUpdateSelectedItem = (DataRowView)this.comboBox1.SelectedItem; // OUTPUT: SelectedIndex = 2; SelectedItem.Name = second Debug.WriteLine(string.Format("SelectedIndex = {0:N0}; SelectedItem.Name = {1}", this.comboBox1.SelectedIndex, postUpdateSelectedItem["Name"])); // FAIL! Debug.Assert(object.ReferenceEquals(preUpdateSelectedItem, postUpdateSelectedItem)); } }

    Read the article

  • Lock thread using somthing other than a object

    - by Scott Chamberlain
    when using a lock does the thing you are locking on have to be a object. For example is this legal static DateTime NextCleanup = DateTime.Now; const TimeSpan CleanupInterval = new TimeSpan(1, 0, 0); private static void DoCleanup() { lock ((object)NextCleanup) { if (NextCleanup < DateTime.Now) { NextCleanup = DateTime.Now.Add(CleanupInterval); System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(cleanupThread)); } } return; } EDIT-- From reading SLaks' responce I know the above code would be not valid but would this be? static MyClass myClass = new MyClass(); private static void DoCleanup() { lock (myClass) { // } return; }

    Read the article

  • AutoMapper : Site wide usage of IValueFormatter for given types

    - by CRice
    It is my understanding I can configure AutoMapper in the following way and during mapping it should format all source model dates to the rules defined in the IValueFormatter and set the result to the mapped model. ForSourceType<DateTime>().AddFormatter<StandardDateFormatter>(); ForSourceType<DateTime?>().AddFormatter<StandardDateFormatter>(); I get no effect for my mapped class with this. It only works when I do the following: Mapper.CreateMap<Member, MemberForm>().ForMember(x => x.DateOfBirth, y => y.AddFormatter<StandardDateFormatter>()); I am mapping DateTime? Member.DateOfBirth to string MemberForm.DateOfBirth. The formatter basically creates a short date string from the date. Is there something I am missing when setting the default formatter for a given type? Thanks public class StandardDateFormatter : IValueFormatter { public string FormatValue(ResolutionContext context) { if (context.SourceValue == null) return null; if (!(context.SourceValue is DateTime)) return context.SourceValue.ToNullSafeString(); return ((DateTime)context.SourceValue).ToShortDateString(); } }

    Read the article

  • Adding format to properties

    - by chris
    I have an object with a couple of DateTime properties: public DateTime Start_Date { get; set; } public DateTime? End_Date { get; set; } I would like to set a format for each of these, along the lines of Start_Date.ToString("M/d/yyyy hh:mm tt") Do I have to code the get, or is there an elegant way to do this?

    Read the article

  • How do I add values from two separate queries in SQL

    - by fishhead
    Below is my attempt at adding two values from separate select statements...it's not working, and I can't see why. I'm looking for some direction. select (v1.Value + v2.Value) as total from ( (Select Max(Value) as [Value] from History WHERE Datetime>='Apr 11 2010 6:05AM' and Datetime<='Apr 11 2010 6:05PM' and Tagname ='RWQ272017DTD' ) as v1 (Select Max(Value) as [Value] from History WHERE Datetime>='Apr 11 2010 6:05AM' and Datetime<='Apr 11 2010 6:05PM' and Tagname ='RU282001DTD' ) as v2 ) EDIT: Boy do I feel foolish...I asked the same question a few days ago...now I can't delete this.

    Read the article

  • Pattern or recommneded refactoring for method

    - by iKode
    I've written a method that looks like this: public TimeSlotList processTimeSlots (DateTime startDT, DateTime endDT, string bookingType, IList<Booking> normalBookings, GCalBookings GCalBookings, List<DateTime> otherApiBookings) { { ..... common process code ...... while (utcTimeSlotStart < endDT) { if (bookingType == "x") { //process normal bookings using IList<Booking> normalBookings } else if (bookingType == "y") { //process google call bookings using GCalBookings GCalBookings } else if (bookingType == "z" { //process other apibookings using List<DateTime> otherApiBookings } } } So I'm calling this from 3 different places, each time passing a different booking type, and each case passing the bookings I'm interested in processing, as well as 2 empty objects that aren't used for this booking type. I'm not able to get bookings all into the same datatype, which would make this easier and each booking type needs to be processed differently, so I'm not sure how I can improve this. Any ideas?

    Read the article

  • undefined method `events' for #<ActiveRecord::Relation:0x4177518> -rails 3.0.3

    - by brg
    I am having this unexplained NoMethodError with undefined method `events' for #. I don't know why since my model association are well defined and the event table has the foreign keys for the user table. I tried using this fix but it failed: Rails 3 ActiveRecord::Relation random associations behavior event.rb class Event < ActiveRecord::Base belongs_to :user attr_accessible :event_name, :Starts_at, :finish, :tracks end user.rb class User < ActiveRecord::Base has_many :events, :dependent = :destroy attr_accessible :name, :event_attributes accepts_nested_attributes_for :events, :allow_destroy = true end schema.rb ActiveRecord::Schema.define(:version = 20101201180355) do create_table "events", :force = true do |t| t.string "event_name" t.string "tracks" t.datetime "starts_at" t.datetime "finish" t.datetime "created_at" t.datetime "updated_at" t.integer "user_id" end end error message NoMethodError in Users#index undefined method `events' for # Extracted source (around line #10): 7: <%= sortable "Tracks" % 8: 10: <% @users.events.each do |event| % 11: <% debugger % 12: 13: <%= event.starts_at % Trace of template inclusion: app/views/users/index.html.erb Rails.root: C:/rails_project1/events_manager Application Trace | Framework Trace | Full Trace app/views/users/_event_user.html.erb:10:in _app_views_users__event_user_html_erb__412443848_34308540_1390678' app/views/users/index.html.erb:7:in_app_views_users_index_html_erb___603337143_34316016_0'

    Read the article

  • C# : How to round-off hours based on Minutes(hours+0 if min<30, hours+1 otherwise) ?

    - by infant programmer
    I need to round-off the hours based on the minutes in a dateTime variable. The condition is : if minutes are less than 30, then minutes must be set to zero and no changes to hours, Else if minutes =30, then hours must be set to hours+1 and minutes are again set to zero. Seconds are ignored. example: 11/08/2008 04:30:49 should become 11/08/2008 05:00:00 and 11/08/2008 04:29:49 should become 11/08/2008 04:00:00 I have written a Code which works perfectly fine, but just wanted to know a better method if could be written and also would appreciate alternative method(s). string date1 = "11/08/2008 04:30:49"; DateTime startTime; DateTime.TryParseExact(date1, "MM/dd/yyyy HH:mm:ss", null, System.Globalization.DateTimeStyles.None, out startTime); if (Convert.ToInt32((startTime.Minute.ToString())) > 29) { startTime = DateTime.Parse(string.Format("{0}/{1}/{2} {3}:{4}:{5}", startTime.Month.ToString(), startTime.Day.ToString(), startTime.Year.ToString(), startTime.Hour.ToString(), "00", "00")); startTime = startTime.Add(TimeSpan.Parse("01:00:00")); Console.WriteLine("startTime is :: {0}", startTime.ToString("MM/dd/yyyy HH:mm:ss")); } else { startTime = DateTime.Parse(string.Format("{0}/{1}/{2} {3}:{4}:{5}", startTime.Month.ToString(), startTime.Day.ToString(), startTime.Year.ToString(), startTime.Hour.ToString(), "00", "00")); Console.WriteLine("startTime is :: {0}", startTime.ToString("MM/dd/yyyy HH:mm:ss")); }

    Read the article

  • How to get timestamp of tick precision in .NET / C#?

    - by Hermann
    Up until now I used DateTime.Now for getting timestamps, but I noticed that if you print DateTime.Now in a loop you will see that it increments in descrete jumps of approx. 15 ms. But for certain scenarios in my application I need to get the most accurate timestamp possible, preferably with tick (=100 ns) precision. Any ideas? Update: Apparently, StopWatch / QueryPerformanceCounter is the way to go, but it can only be used to measure time, so I was thinking about calling DateTime.Now when the application starts up and then just have StopWatch run and then just add the elapsed time from StopWatch to the initial value returned from DateTime.Now. At least that should give me accurate relative timestamps, right? What do you think about that (hack)? NOTE: StopWatch.ElapsedTicks is different from StopWatch.Elapsed.Ticks! I used the former assuming 1 tick = 100 ns, but in this case 1 tick = 1 / StopWatch.Frequency. So to get ticks equivalent to DateTime use StopWatch.Elapsed.Ticks. I just learned this the hard way. NOTE 2: Using the StopWatch approach, I noticed it gets out of sync with the real time. After about 10 hours, it was ahead by 5 seconds. So I guess one would have to resync it every X or so where X could be 1 hour, 30 min, 15 min, etc. I am not sure what the optimal timespan for resyncing would be since every resync will change the offset which can be up to 20 ms.

    Read the article

  • Class with property referenced with dll not serializing

    - by djerry
    Hey guys, I got this class TapiCall. It has 4 properties : 2 datetimes, 1 string and an object. The object is a class that's referenced by Atapi3.dll, so i cannot alter it. My class TapiCall looks like this : [DataContract] public class TapiCall { private DateTime start, end; private TCall call; private string status; [DataMember] public string Status { get { return status; } set { status = value; } } [DataMember] public TCall Call { get { return call; } set { call = value; } } [DataMember] public DateTime End { get { return end; } set { end = value; } } [DataMember] public DateTime Start { get { return start; } set { start = value; } } public TapiCall() { } public TapiCall(DateTime start, DateTime end, TCall call) { this.Start = start; this.End = end; this.Call = call; } } Now when i use my visual studio command line, to generate my proxy class, it generates an error. When i remove TapiCall from the method in my app, i can rebuild my proxy again, so i know [OperationContract] void StuurUpdatedCall(TapiCall tpCall); is causing the problem. My question now is can i Serialize a class that's referenced by a dll? Thanks in advance.

    Read the article

  • how to get width of column in charting ColumnSeries. I have not DataPointStyle. It takes the default

    - by KK
    how to get width of column in charting ColumnSeries. I have not DataPointStyle. It takes the default I have set the itemssource to col.ItemsSource = new KeyValuePair[]{ new KeyValuePair(DateTime.Now.AddMonths(1), 100), new KeyValuePair(DateTime.Now.AddMonths(2), 200), new KeyValuePair(DateTime.Now.AddMonths(3), 300), new KeyValuePair(DateTime.Now.AddMonths(4), 400) }; I get 4 column with some even width. How to I print its value .... its taking it by default ... thank you.

    Read the article

  • Help with a algorithm in linq to resolve a query

    - by Deumber
    I have been some time thinking how to resolve this problem, but out of ideas i prefer expose it for help. I have 2 tables (linq to sql) A and B, A have a many relation with B, so A have a property EntitySet of B A have the following properties: CreateDate (Datetime) ModificateDate (Datetime) Bs (EntitySet<B>) B have the following properties: CreateDate (Datetime) ModificateDate (Datetime) All that i want is return a ordered collection of A by the Max date between : A.CreateDate, A.ModificateDate, The Max B.CreateDate of all B in A The Max B.ModificateDate of all B in A if i someone need a little example, just ask for it.

    Read the article

  • create a model in create action from a class

    - by Pontek
    As a newbie to rails I can't find how to solve my issue ^^ I want to create a VideoPost from a form with a text field containing a video url (like youtube) I'm getting information on the video thanks to the gem https://github.com/thibaudgg/video_info And I want to save thoses information using a model of mine (VideoInformation). But I don't know how the create process should work. Thanks for any help ! I'm trying to create a VideoPost in VideoPostsController like this : def create video_info = VideoInfo.new(params[:video_url]) video_information = VideoInformation.create(video_info) #undefined method `stringify_keys' for #<Youtube:0x00000006a24120> if video_information.save @video_post = current_user.video_posts.build(video_information) end end My VideoPost model : # Table name: video_posts # # id :integer not null, primary key # user_id :integer # video_information_id :integer # created_at :datetime not null # updated_at :datetime not null My VideoInformation model (which got same attributes name than VideoInfo gem) : # Table name: video_informations # # id :integer not null, primary key # title :string(255) # description :text # keywords :text # duration :integer # video_url :string(255) # thumbnail_small :string(255) # thumbnail_large :string(255) # created_at :datetime not null # updated_at :datetime not null

    Read the article

  • Exploding a range of dates with LINQ

    - by Robert Gowland
    If I have a pair of dates, and I want to generate a list of all the dates between them (inclusive), I can do something like: System.DateTime s = new System.DateTime(2010, 06, 05); System.DateTime e = new System.DateTime(2010, 06, 09); var list = Enumerable.Range(0, (e - s).Days) .Select(value => s.AddDays(value)); What I'm stuck on is that I've got a list of pairs of dates that I want to explode into a list of all the dates between them. Example: {2010-05-06, 2010-05-09}, {2010-05-12, 2010-05-15} should result in {2010-05-06, 2010-05-07, 2010-05-08, 2010-05-09, 2010-05-12, 2010-05-13, 2010-05-14, 2010-05-15} Note the pairs of dates are guaranteed not to overlap each other.

    Read the article

  • Finding 'free' times in MySQL

    - by James Inman
    Hi, I've got a table as follows: mysql> DESCRIBE student_lectures; +------------------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------------+----------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | course_module_id | int(11) | YES | MUL | NULL | | | day | int(11) | YES | | NULL | | | start | datetime | YES | | NULL | | | end | datetime | YES | | NULL | | | cancelled_at | datetime | YES | | NULL | | | lecture_type_id | int(11) | YES | | NULL | | | lecture_id | int(11) | YES | | NULL | | | student_id | int(11) | YES | | NULL | | | created_at | datetime | YES | | NULL | | | updated_at | datetime | YES | | NULL | | +------------------+----------+------+-----+---------+----------------+ I'm essentially wanting to find times when a lecture doesn't happen - so to do this I'm thinking a query to group overlapping lectures together (so, for example, 9am-10am and 10am-11am lectures will be shown as a single 9am-11am lecture). There may be more than two lectures back-to-back. I've currently got this: SELECT l.start, l2.end FROM student_lectures l LEFT JOIN student_lectures l2 ON ( l2.start = l.end ) WHERE l.student_id = 1 AND l.start >= '2010-04-26 09:00:00' AND l.end <= '2010-04-30 19:00:00' AND l2.end IS NOT NULL AND l2.end != l.start GROUP BY l.start, l2.end ORDER BY l.start, l2.start Which returns: +---------------------+---------------------+ | start | end | +---------------------+---------------------+ | 2010-04-26 09:00:00 | 2010-04-26 11:00:00 | | 2010-04-26 10:00:00 | 2010-04-26 12:00:00 | | 2010-04-26 10:00:00 | 2010-04-26 13:00:00 | | 2010-04-26 13:15:00 | 2010-04-26 16:15:00 | | 2010-04-26 14:15:00 | 2010-04-26 16:15:00 | | 2010-04-26 15:15:00 | 2010-04-26 17:15:00 | | 2010-04-26 16:15:00 | 2010-04-26 18:15:00 | ...etc... The output I'm looking for from this would be: +---------------------+---------------------+ | start | end | +---------------------+---------------------+ | 2010-04-26 09:00:00 | 2010-04-26 13:00:00 | | 2010-04-26 13:15:00 | 2010-04-26 18:15:00 | Any help appreciated, thanks!

    Read the article

  • Trying to get paperclip to refresh or reprocess..

    - by Trip
    I have over time, changed the size for thumbs of the class Deal. Through these changes, users were uploading to the site, so there are few people who have different sized thumbs. I wanted to reprocress or refresh these, so I went to into my root and typed: $ rake paperclip:refresh class=Deal Did nothing for the thumb sizes.. Then I : irb Deal.find(987).reprocess! Returned this : NoMethodError: undefined method `reprocess!' for #<Deal:0xb68a0988> from /data/HQ_Channel/releases/20100607130346/vendor/rails/activerecord/lib/active_record/attribute_methods.rb:260:in `method_missing' from (irb):7 My deal class is this : => Deal(id: integer, organization_id: integer, deal: string, value: string, what: string, description: string, image_file_name: string, image_content_type: string, image_file_size: integer, image_updated_at: datetime, created_at: datetime, updated_at: datetime, deal_image_file_name: string, deal_image_content_type: string, deal_image_file_size: integer, deal_image_uploaded_at: datetime) What can i do to have it reprocess the original to make the thumb the correct size in the current thumb size params?

    Read the article

  • Roundoff Timespan to 15 min interval

    - by s-a-n
    I have a property in my code where users can enter a timespan in HH:mm like 10:32 10:44 15:45 I want to round off in my property to the nearest 15mins but i dont have datetime here. I only need to do it with Timespan 10:32 to 10:30 10:44 to 10:45 15:45 to 15:45 01:02 to 01:00 02:11 to 02:15 03:22 to 03:25 23:52 to 00:00 Tried all these solutions but they involve Datetime in them How can I round up the time to the nearest X minutes? Is there a simple function for rounding a DateTime down to the nearest 30 minutes, in C#? DotNet Roundoff datetime to last 15 minutes

    Read the article

  • Single entity with single view or two views in mvc3 vs2010?

    - by user2905798
    I have the following entity model public class Employee { public int Employee ID{get;set;} public string employeename{get;set;} public datetime employeeDOb{get;set;} public datetime? employeeDateOfJoin{get;set;} public string empFamilyname{get;set;} public datetime empFamilyDob{get;set;} } here I have to design a view for collecting employee information and employee family information. Since I am working on already available data, where in empFamilyDob was not mandatory. But now it is being made mandatory, the previous data doesn't contain EmpFamilyDob. So naturally I have added this new property EmpFamilyDob to the Model and made it required through DataAnnotations. Now there are two set of views to be developed. 1. A view which simply allows to collect the employee information without employee family information. i.e, empFamilyName and EmpFamilyDob.--This view is used by the Hr section to insert empplyee details Since the empFamilyname and EmpFamilyDob being now made mandatory, some other section will edit the data and update the EmpFamilyName and EmpFamilyDob as and when the information about employee family details are received. I have action controller for CreateNew and Edit Which is being generated by using the default model. There are two user actions being performed. 1.When the user clicks the Create new -- he will be able to update only the Employee information 2.As and when the other section receives the employee family details they update the familyname and family date of birth. i.e, EmployeeFamilyname and EmployeFamilyDob. While creating new record the uses should be able to update employee information only and while editing the information he should be able to update the employeefamily information. Since I have a single view with most of these fields as required and not allowing null , How can I achieve this in a sincle view? I have recorrected the model like this public class Employee { public int Employee ID{get;set;} public string employeename{get;set;} public datetime employeeDOb{get;set;} public datetime? employeeDateOfJoin{get;set;} public string empFamilyname{get;set;} public datetime? empFamilyDob{get;set;} } Now by default I hope the createnew action would insert null value for empFamilyname(string datatype) and empFamilyDob . In the Edit action the user should be made to enter empFamilyname and empFamilyDob(mandatory). As there is every chance that the user might edit other information about the employee(like employeeDob) I don't want to go for partial views. Can you help me out with some illustration. Thanks in advance

    Read the article

  • Value [...] not a valid choice, django-updown

    - by tamara
    I am trying to implemet django-updown https://github.com/weluse/django-updown. When I try to add vote trough the admin panel it says Value 1 not a valid choice. This is the models.py from the application: _SCORE_TYPE_CHOICES = ( ('-1', 'DISLIKE'), ('1', 'LIKE'), ) SCORE_TYPES = dict((value, key) for key, value in _SCORE_TYPE_CHOICES) class Vote(models.Model): content_type = models.ForeignKey(ContentType, related_name="updown_votes") object_id = models.PositiveIntegerField() key = models.CharField(max_length=32) score = models.SmallIntegerField(choices=_SCORE_TYPE_CHOICES) user = models.ForeignKey(User, blank=True, null=True, related_name="updown_votes") ip_address = models.IPAddressField() date_added = models.DateTimeField(default=datetime.datetime.now, editable=False) date_changed = models.DateTimeField(default=datetime.datetime.now, editable=False) Do you have an idea what could be wrong?

    Read the article

  • Do these methods have same output?

    - by devrimbaris
    protected synchronized boolean isTimeoutOccured(Duration timeoutDuration) { DateTime now = new DateTime(); if (timeoutOccured == false) { if (new Duration(requestTime.getMillis(), now.getMillis()).compareTo(timeoutDuration) > 0) { timeoutOccured = true; } } return timeoutOccured; } protected boolean isTimeoutOccured2(Duration timeoutDuration) { return atomicTimeOut.compareAndSet(false, new Duration(requestTime.getMillis(), new DateTime().getMillis()).compareTo(timeoutDuration) > 0); }

    Read the article

  • C#: My World Clock

    - by Bruce Eitman
    [Placeholder:  I will post the entire project soon] I have been working on cleaning my office of 8 years of stuff from several engineers working on many projects.  It turns out that we have a few extra single board computers with displays, so at the end of the day last Friday I though why not create a little application to display the time, you know, a clock.  How difficult could that be?  It turns out that it is quite simple – until I decided to gold plate the project by adding time displays for our offices around the world. I decided to use C#, which actually made creating the main clock quite easy.   The application was simply a text box and a timer.  I set the timer to fire a couple of times a second, and when it does use a DateTime object to get the current time and retrieve a string to display. And I could have been done, but of course that gold plating came up.   Seems simple enough, simply offset the time from the local time to the location that I want the time for and display it.    Sure enough, I had the time displayed for UK, Italy, Kansas City, Japan and China in no time at all. But it is October, and for those of us still stuck with Daylight Savings Time, we know that the clocks are about to change.   My first attempt was to simply check to see if the local time was DST or Standard time, then change the offset for China.  China doesn’t have Daylight Savings Time. If you know anything about the time changes around the world, you already know that my plan is flawed – in a big way.   It turns out that the transitions in and out of DST take place at different times around the world.   If you didn’t know that, do a quick search for “Daylight Savings” and you will find many WEB sites dedicated to tracking the time changes dates, and times. Now the real challenge of this application; how do I programmatically find out when the time changes occur and handle them correctly?  After a considerable amount of research it turns out that the solution is to read the data from the registry and parse it to figure out when the time changes occur. Reading Time Change Information from the Registry Reading the data from the registry is simple, using the data is a little more complicated.  First, reading from the registry can be done like:             byte[] binarydata = (byte[])Registry.GetValue("HKEY_LOCAL_MACHINE\\Time Zones\\Eastern Standard Time", "TZI", null);   Where I have hardcoded the registry key for example purposes, but in the end I will use some variables.   We now have a binary blob with the data, but it needs to be converted to use the real data.   To start we will need a couple of structs to hold the data and make it usable.   We will need a SYSTEMTIME and REG_TZI_FORMAT.   You may have expected that we would need a TIME_ZONE_INFORMATION struct, but we don’t.   The data is stored in the registry as a REG_TZI_FORMAT, which excludes some of the values found in TIME_ZONE_INFORMATION.     struct SYSTEMTIME     {         internal short wYear;         internal short wMonth;         internal short wDayOfWeek;         internal short wDay;         internal short wHour;         internal short wMinute;         internal short wSecond;         internal short wMilliseconds;     }       struct REG_TZI_FORMAT     {         internal long Bias;         internal long StdBias;         internal long DSTBias;         internal SYSTEMTIME StandardStart;         internal SYSTEMTIME DSTStart;     }   Now we need to convert the binary blob to a REG_TZI_FORMAT.   To do that I created the following helper functions:         private void BinaryToSystemTime(ref SYSTEMTIME ST, byte[] binary, int offset)         {             ST.wYear = (short)(binary[offset + 0] + (binary[offset + 1] << 8));             ST.wMonth = (short)(binary[offset + 2] + (binary[offset + 3] << 8));             ST.wDayOfWeek = (short)(binary[offset + 4] + (binary[offset + 5] << 8));             ST.wDay = (short)(binary[offset + 6] + (binary[offset + 7] << 8));             ST.wHour = (short)(binary[offset + 8] + (binary[offset + 9] << 8));             ST.wMinute = (short)(binary[offset + 10] + (binary[offset + 11] << 8));             ST.wSecond = (short)(binary[offset + 12] + (binary[offset + 13] << 8));             ST.wMilliseconds = (short)(binary[offset + 14] + (binary[offset + 15] << 8));         }             private REG_TZI_FORMAT ConvertFromBinary(byte[] binarydata)         {             REG_TZI_FORMAT RTZ = new REG_TZI_FORMAT();               RTZ.Bias = binarydata[0] + (binarydata[1] << 8) + (binarydata[2] << 16) + (binarydata[3] << 24);             RTZ.StdBias = binarydata[4] + (binarydata[5] << 8) + (binarydata[6] << 16) + (binarydata[7] << 24);             RTZ.DSTBias = binarydata[8] + (binarydata[9] << 8) + (binarydata[10] << 16) + (binarydata[11] << 24);             BinaryToSystemTime(ref RTZ.StandardStart, binarydata, 4 + 4 + 4);             BinaryToSystemTime(ref RTZ.DSTStart, binarydata, 4 + 16 + 4 + 4);               return RTZ;         }   I am the first to admit that there may be a better way to get the settings from the registry and into the REG_TXI_FORMAT, but I am not a great C# programmer which I have said before on this blog.   So sometimes I chose brute force over elegant. Now that we have the Bias information and the start date information, we can start to make sense of it.   The bias is an offset, in minutes, from local time (if already in local time for the time zone in question) to get to UTC – or as Microsoft defines it: UTC = local time + bias.  Standard bias is an offset to adjust for standard time, which I think is usually zero.   And DST bias is and offset to adjust for daylight savings time. Since we don’t have the local time for a time zone other than the one that the computer is set to, what we first need to do is convert local time to UTC, which is simple enough using:                 DateTime.Now.ToUniversalTime(); Then, since we have UTC we need to do a little math to alter the formula to: local time = UTC – bias.  In other words, we need to subtract the bias minutes. I am ahead of myself though, the standard and DST start dates really aren’t dates.   Instead they indicate the month, day of week and week number of the time change.   The dDay member of SYSTEM time will be set to the week number of the date change indicating that the change happens on the first, second… day of week of the month.  So we need to convert them to dates so that we can determine which bias to use, and when to change to a different bias.   To do that, I wrote the following function:         private DateTime SystemTimeToDateTimeStart(SYSTEMTIME Time, int Year)         {             DayOfWeek[] Days = { DayOfWeek.Sunday, DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday, DayOfWeek.Saturday };             DateTime InfoTime = new DateTime(Year, Time.wMonth, Time.wDay == 1 ? 1 : ((Time.wDay - 1) * 7) + 1, Time.wHour, Time.wMinute, Time.wSecond, DateTimeKind.Utc);             DateTime BestGuess = InfoTime;             while (BestGuess.DayOfWeek != Days[Time.wDayOfWeek])             {                 BestGuess = BestGuess.AddDays(1);             }             return BestGuess;         }   SystemTimeToDateTimeStart gets two parameters; a SYSTEMTIME and a year.   The reason is that we will try this year and next year because we are interested in start dates that are in the future, not the past.  The function starts by getting a new Datetime with the first possible date and then looking for the correct date. Using the start dates, we can then determine the correct bias to use, and the next date that time will change:             NextTimeChange = StandardChange;             CurrentBias = TimezoneSettings.Bias + TimezoneSettings.DSTBias;             if (DSTChange.Year != 1 && StandardChange.Year != 1)             {                 if (DSTChange.CompareTo(StandardChange) < 0)                 {                     NextTimeChange = DSTChange;                     CurrentBias = TimezoneSettings.StdBias + TimezoneSettings.Bias;                 }             }             else             {                 // I don't like this, but it turns out that China Standard Time                 // has a DSTBias of -60 on every Windows system that I tested.                 // So, if no DST transitions, then just use the Bias without                 // any offset                 CurrentBias = TimezoneSettings.Bias;             }   Note that some time zones do not change time, in which case the years will remain set to 1.   Further, I found that the registry settings are actually wrong in that the DST Bias is set to -60 for China even though there is not DST in China, so I ignore the standard and DST bias for those time zones. There is one thing that I have not solved, and don’t plan to solve.  If the time zone for this computer changes, this application will not update the clock using the new time zone.  I tell  you this because you may need to deal with it – I do not because I won’t let the user get to the control panel applet to change the timezone. Copyright © 2012 – Bruce Eitman All Rights Reserved

    Read the article

  • Using the West Wind Web Toolkit to set up AJAX and REST Services

    - by Rick Strahl
    I frequently get questions about which option to use for creating AJAX and REST backends for ASP.NET applications. There are many solutions out there to do this actually, but when I have a choice - not surprisingly - I fall back to my own tools in the West Wind West Wind Web Toolkit. I've talked a bunch about the 'in-the-box' solutions in the past so for a change in this post I'll talk about the tools that I use in my own and customer applications to handle AJAX and REST based access to service resources using the West Wind West Wind Web Toolkit. Let me preface this by saying that I like things to be easy. Yes flexible is very important as well but not at the expense of over-complexity. The goal I've had with my tools is make it drop dead easy, with good performance while providing the core features that I'm after, which are: Easy AJAX/JSON Callbacks Ability to return any kind of non JSON content (string, stream, byte[], images) Ability to work with both XML and JSON interchangeably for input/output Access endpoints via POST data, RPC JSON calls, GET QueryString values or Routing interface Easy to use generic JavaScript client to make RPC calls (same syntax, just what you need) Ability to create clean URLS with Routing Ability to use standard ASP.NET HTTP Stack for HTTP semantics It's all about options! In this post I'll demonstrate most of these features (except XML) in a few simple and short samples which you can download. So let's take a look and see how you can build an AJAX callback solution with the West Wind Web Toolkit. Installing the Toolkit Assemblies The easiest and leanest way of using the Toolkit in your Web project is to grab it via NuGet: West Wind Web and AJAX Utilities (Westwind.Web) and drop it into the project by right clicking in your Project and choosing Manage NuGet Packages from anywhere in the Project.   When done you end up with your project looking like this: What just happened? Nuget added two assemblies - Westwind.Web and Westwind.Utilities and the client ww.jquery.js library. It also added a couple of references into web.config: The default namespaces so they can be accessed in pages/views and a ScriptCompressionModule that the toolkit optionally uses to compress script resources served from within the assembly (namely ww.jquery.js and optionally jquery.js). Creating a new Service The West Wind Web Toolkit supports several ways of creating and accessing AJAX services, but for this post I'll stick to the lower level approach that works from any plain HTML page or of course MVC, WebForms, WebPages. There's also a WebForms specific control that makes this even easier but I'll leave that for another post. So, to create a new standalone AJAX/REST service we can create a new HttpHandler in the new project either as a pure class based handler or as a generic .ASHX handler. Both work equally well, but generic handlers don't require any web.config configuration so I'll use that here. In the root of the project add a Generic Handler. I'm going to call this one StockService.ashx. Once the handler has been created, edit the code and remove all of the handler body code. Then change the base class to CallbackHandler and add methods that have a [CallbackMethod] attribute. Here's the modified base handler implementation now looks like with an added HelloWorld method: using System; using Westwind.Web; namespace WestWindWebAjax { /// <summary> /// Handler implements CallbackHandler to provide REST/AJAX services /// </summary> public class SampleService : CallbackHandler { [CallbackMethod] public string HelloWorld(string name) { return "Hello " + name + ". Time is: " + DateTime.Now.ToString(); } } } Notice that the class inherits from CallbackHandler and that the HelloWorld service method is marked up with [CallbackMethod]. We're done here. Services Urlbased Syntax Once you compile, the 'service' is live can respond to requests. All CallbackHandlers support input in GET and POST formats, and can return results as JSON or XML. To check our fancy HelloWorld method we can now access the service like this: http://localhost/WestWindWebAjax/StockService.ashx?Method=HelloWorld&name=Rick which produces a default JSON response - in this case a string (wrapped in quotes as it's JSON): (note by default JSON will be downloaded by most browsers not displayed - various options are available to view JSON right in the browser) If I want to return the same data as XML I can tack on a &format=xml at the end of the querystring which produces: <string>Hello Rick. Time is: 11/1/2011 12:11:13 PM</string> Cleaner URLs with Routing Syntax If you want cleaner URLs for each operation you can also configure custom routes on a per URL basis similar to the way that WCF REST does. To do this you need to add a new RouteHandler to your application's startup code in global.asax.cs one for each CallbackHandler based service you create: protected void Application_Start(object sender, EventArgs e) { CallbackHandlerRouteHandler.RegisterRoutes<StockService>(RouteTable.Routes); } With this code in place you can now add RouteUrl properties to any of your service methods. For the HelloWorld method that doesn't make a ton of sense but here is what a routed clean URL might look like in definition: [CallbackMethod(RouteUrl="stocks/HelloWorld/{name}")] public string HelloWorld(string name) { return "Hello " + name + ". Time is: " + DateTime.Now.ToString(); } The same URL I previously used now becomes a bit shorter and more readable with: http://localhost/WestWindWebAjax/HelloWorld/Rick It's an easy way to create cleaner URLs and still get the same functionality. Calling the Service with $.getJSON() Since the result produced is JSON you can now easily consume this data using jQuery's getJSON method. First we need a couple of scripts - jquery.js and ww.jquery.js in the page: <!DOCTYPE html> <html> <head> <link href="Css/Westwind.css" rel="stylesheet" type="text/css" /> <script src="scripts/jquery.min.js" type="text/javascript"></script> <script src="scripts/ww.jquery.min.js" type="text/javascript"></script> </head> <body> Next let's add a small HelloWorld example form (what else) that has a single textbox to type a name, a button and a div tag to receive the result: <fieldset> <legend>Hello World</legend> Please enter a name: <input type="text" name="txtHello" id="txtHello" value="" /> <input type="button" id="btnSayHello" value="Say Hello (POST)" /> <input type="button" id="btnSayHelloGet" value="Say Hello (GET)" /> <div id="divHelloMessage" class="errordisplay" style="display:none;width: 450px;" > </div> </fieldset> Then to call the HelloWorld method a little jQuery is used to hook the document startup and the button click followed by the $.getJSON call to retrieve the data from the server. <script type="text/javascript"> $(document).ready(function () { $("#btnSayHelloGet").click(function () { $.getJSON("SampleService.ashx", { Method: "HelloWorld", name: $("#txtHello").val() }, function (result) { $("#divHelloMessage") .text(result) .fadeIn(1000); }); });</script> .getJSON() expects a full URL to the endpoint of our service, which is the ASHX file. We can either provide a full URL (SampleService.ashx?Method=HelloWorld&name=Rick) or we can just provide the base URL and an object that encodes the query string parameters for us using an object map that has a property that matches each parameter for the server method. We can also use the clean URL routing syntax, but using the object parameter encoding actually is safer as the parameters will get properly encoded by jQuery. The result returned is whatever the result on the server method is - in this case a string. The string is applied to the divHelloMessage element and we're done. Obviously this is a trivial example, but it demonstrates the basics of getting a JSON response back to the browser. AJAX Post Syntax - using ajaxCallMethod() The previous example allows you basic control over the data that you send to the server via querystring parameters. This works OK for simple values like short strings, numbers and boolean values, but doesn't really work if you need to pass something more complex like an object or an array back up to the server. To handle traditional RPC type messaging where the idea is to map server side functions and results to a client side invokation, POST operations can be used. The easiest way to use this functionality is to use ww.jquery.js and the ajaxCallMethod() function. ww.jquery wraps jQuery's AJAX functions and knows implicitly how to call a CallbackServer method with parameters and parse the result. Let's look at another simple example that posts a simple value but returns something more interesting. Let's start with the service method: [CallbackMethod(RouteUrl="stocks/{symbol}")] public StockQuote GetStockQuote(string symbol) { Response.Cache.SetExpires(DateTime.UtcNow.Add(new TimeSpan(0, 2, 0))); StockServer server = new StockServer(); var quote = server.GetStockQuote(symbol); if (quote == null) throw new ApplicationException("Invalid Symbol passed."); return quote; } This sample utilizes a small StockServer helper class (included in the sample) that downloads a stock quote from Yahoo's financial site via plain HTTP GET requests and formats it into a StockQuote object. Lets create a small HTML block that lets us query for the quote and display it: <fieldset> <legend>Single Stock Quote</legend> Please enter a stock symbol: <input type="text" name="txtSymbol" id="txtSymbol" value="msft" /> <input type="button" id="btnStockQuote" value="Get Quote" /> <div id="divStockDisplay" class="errordisplay" style="display:none; width: 450px;"> <div class="label-left">Company:</div> <div id="stockCompany"></div> <div class="label-left">Last Price:</div> <div id="stockLastPrice"></div> <div class="label-left">Quote Time:</div> <div id="stockQuoteTime"></div> </div> </fieldset> The final result looks something like this:   Let's hook up the button handler to fire the request and fill in the data as shown: $("#btnStockQuote").click(function () { ajaxCallMethod("SampleService.ashx", "GetStockQuote", [$("#txtSymbol").val()], function (quote) { $("#divStockDisplay").show().fadeIn(1000); $("#stockCompany").text(quote.Company + " (" + quote.Symbol + ")"); $("#stockLastPrice").text(quote.LastPrice); $("#stockQuoteTime").text(quote.LastQuoteTime.formatDate("MMM dd, HH:mm EST")); }, onPageError); }); So we point at SampleService.ashx and the GetStockQuote method, passing a single parameter of the input symbol value. Then there are two handlers for success and failure callbacks.  The success handler is the interesting part - it receives the stock quote as a result and assigns its values to various 'holes' in the stock display elements. The data that comes back over the wire is JSON and it looks like this: { "Symbol":"MSFT", "Company":"Microsoft Corpora", "OpenPrice":26.11, "LastPrice":26.01, "NetChange":0.02, "LastQuoteTime":"2011-11-03T02:00:00Z", "LastQuoteTimeString":"Nov. 11, 2011 4:20pm" } which is an object representation of the data. JavaScript can evaluate this JSON string back into an object easily and that's the reslut that gets passed to the success function. The quote data is then applied to existing page content by manually selecting items and applying them. There are other ways to do this more elegantly like using templates, but here we're only interested in seeing how the data is returned. The data in the object is typed - LastPrice is a number and QuoteTime is a date. Note about the date value: JavaScript doesn't have a date literal although the JSON embedded ISO string format used above  ("2011-11-03T02:00:00Z") is becoming fairly standard for JSON serializers. However, JSON parsers don't deserialize dates by default and return them by string. This is why the StockQuote actually returns a string value of LastQuoteTimeString for the same date. ajaxMethodCallback always converts dates properly into 'real' dates and the example above uses the real date value along with a .formatDate() data extension (also in ww.jquery.js) to display the raw date properly. Errors and Exceptions So what happens if your code fails? For example if I pass an invalid stock symbol to the GetStockQuote() method you notice that the code does this: if (quote == null) throw new ApplicationException("Invalid Symbol passed."); CallbackHandler automatically pushes the exception message back to the client so it's easy to pick up the error message. Regardless of what kind of error occurs: Server side, client side, protocol errors - any error will fire the failure handler with an error object parameter. The error is returned to the client via a JSON response in the error callback. In the previous examples I called onPageError which is a generic routine in ww.jquery that displays a status message on the bottom of the screen. But of course you can also take over the error handling yourself: $("#btnStockQuote").click(function () { ajaxCallMethod("SampleService.ashx", "GetStockQuote", [$("#txtSymbol").val()], function (quote) { $("#divStockDisplay").fadeIn(1000); $("#stockCompany").text(quote.Company + " (" + quote.Symbol + ")"); $("#stockLastPrice").text(quote.LastPrice); $("#stockQuoteTime").text(quote.LastQuoteTime.formatDate("MMM dd, hh:mmt")); }, function (error, xhr) { $("#divErrorDisplay").text(error.message).fadeIn(1000); }); }); The error object has a isCallbackError, message and  stackTrace properties, the latter of which is only populated when running in Debug mode, and this object is returned for all errors: Client side, transport and server side errors. Regardless of which type of error you get the same object passed (as well as the XHR instance optionally) which makes for a consistent error retrieval mechanism. Specifying HttpVerbs You can also specify HTTP Verbs that are allowed using the AllowedHttpVerbs option on the CallbackMethod attribute: [CallbackMethod(AllowedHttpVerbs=HttpVerbs.GET | HttpVerbs.POST)] public string HelloWorld(string name) { … } If you're building REST style API's this might be useful to force certain request semantics onto the client calling. For the above if call with a non-allowed HttpVerb the request returns a 405 error response along with a JSON (or XML) error object result. The default behavior is to allow all verbs access (HttpVerbs.All). Passing in object Parameters Up to now the parameters I passed were very simple. But what if you need to send something more complex like an object or an array? Let's look at another example now that passes an object from the client to the server. Keeping with the Stock theme here lets add a method called BuyOrder that lets us buy some shares for a stock. Consider the following service method that receives an StockBuyOrder object as a parameter: [CallbackMethod] public string BuyStock(StockBuyOrder buyOrder) { var server = new StockServer(); var quote = server.GetStockQuote(buyOrder.Symbol); if (quote == null) throw new ApplicationException("Invalid or missing stock symbol."); return string.Format("You're buying {0} shares of {1} ({2}) stock at {3} for a total of {4} on {5}.", buyOrder.Quantity, quote.Company, quote.Symbol, quote.LastPrice.ToString("c"), (quote.LastPrice * buyOrder.Quantity).ToString("c"), buyOrder.BuyOn.ToString("MMM d")); } public class StockBuyOrder { public string Symbol { get; set; } public int Quantity { get; set; } public DateTime BuyOn { get; set; } public StockBuyOrder() { BuyOn = DateTime.Now; } } This is a contrived do-nothing example that simply echoes back what was passed in, but it demonstrates how you can pass complex data to a callback method. On the client side we now have a very simple form that captures the three values on a form: <fieldset> <legend>Post a Stock Buy Order</legend> Enter a symbol: <input type="text" name="txtBuySymbol" id="txtBuySymbol" value="GLD" />&nbsp;&nbsp; Qty: <input type="text" name="txtBuyQty" id="txtBuyQty" value="10" style="width: 50px" />&nbsp;&nbsp; Buy on: <input type="text" name="txtBuyOn" id="txtBuyOn" value="<%= DateTime.Now.ToString("d") %>" style="width: 70px;" /> <input type="button" id="btnBuyStock" value="Buy Stock" /> <div id="divStockBuyMessage" class="errordisplay" style="display:none"></div> </fieldset> The completed form and demo then looks something like this:   The client side code that picks up the input values and assigns them to object properties and sends the AJAX request looks like this: $("#btnBuyStock").click(function () { // create an object map that matches StockBuyOrder signature var buyOrder = { Symbol: $("#txtBuySymbol").val(), Quantity: $("#txtBuyQty").val() * 1, // number Entered: new Date() } ajaxCallMethod("SampleService.ashx", "BuyStock", [buyOrder], function (result) { $("#divStockBuyMessage").text(result).fadeIn(1000); }, onPageError); }); The code creates an object and attaches the properties that match the server side object passed to the BuyStock method. Each property that you want to update needs to be included and the type must match (ie. string, number, date in this case). Any missing properties will not be set but also not cause any errors. Pass POST data instead of Objects In the last example I collected a bunch of values from form variables and stuffed them into object variables in JavaScript code. While that works, often times this isn't really helping - I end up converting my types on the client and then doing another conversion on the server. If lots of input controls are on a page and you just want to pick up the values on the server via plain POST variables - that can be done too - and it makes sense especially if you're creating and filling the client side object only to push data to the server. Let's add another method to the server that once again lets us buy a stock. But this time let's not accept a parameter but rather send POST data to the server. Here's the server method receiving POST data: [CallbackMethod] public string BuyStockPost() { StockBuyOrder buyOrder = new StockBuyOrder(); buyOrder.Symbol = Request.Form["txtBuySymbol"]; ; int qty; int.TryParse(Request.Form["txtBuyQuantity"], out qty); buyOrder.Quantity = qty; DateTime time; DateTime.TryParse(Request.Form["txtBuyBuyOn"], out time); buyOrder.BuyOn = time; // Or easier way yet //FormVariableBinder.Unbind(buyOrder,null,"txtBuy"); var server = new StockServer(); var quote = server.GetStockQuote(buyOrder.Symbol); if (quote == null) throw new ApplicationException("Invalid or missing stock symbol."); return string.Format("You're buying {0} shares of {1} ({2}) stock at {3} for a total of {4} on {5}.", buyOrder.Quantity, quote.Company, quote.Symbol, quote.LastPrice.ToString("c"), (quote.LastPrice * buyOrder.Quantity).ToString("c"), buyOrder.BuyOn.ToString("MMM d")); } Clearly we've made this server method take more code than it did with the object parameter. We've basically moved the parameter assignment logic from the client to the server. As a result the client code to call this method is now a bit shorter since there's no client side shuffling of values from the controls to an object. $("#btnBuyStockPost").click(function () { ajaxCallMethod("SampleService.ashx", "BuyStockPost", [], // Note: No parameters - function (result) { $("#divStockBuyMessage").text(result).fadeIn(1000); }, onPageError, // Force all page Form Variables to be posted { postbackMode: "Post" }); }); The client simply calls the BuyStockQuote method and pushes all the form variables from the page up to the server which parses them instead. The feature that makes this work is one of the options you can pass to the ajaxCallMethod() function: { postbackMode: "Post" }); which directs the function to include form variable POST data when making the service call. Other options include PostNoViewState (for WebForms to strip out WebForms crap vars), PostParametersOnly (default), None. If you pass parameters those are always posted to the server except when None is set. The above code can be simplified a bit by using the FormVariableBinder helper, which can unbind form variables directly into an object: FormVariableBinder.Unbind(buyOrder,null,"txtBuy"); which replaces the manual Request.Form[] reading code. It receives the object to unbind into, a string of properties to skip, and an optional prefix which is stripped off form variables to match property names. The component is similar to the MVC model binder but it's independent of MVC. Returning non-JSON Data CallbackHandler also supports returning non-JSON/XML data via special return types. You can return raw non-JSON encoded strings like this: [CallbackMethod(ReturnAsRawString=true,ContentType="text/plain")] public string HelloWorldNoJSON(string name) { return "Hello " + name + ". Time is: " + DateTime.Now.ToString(); } Calling this method results in just a plain string - no JSON encoding with quotes around the result. This can be useful if your server handling code needs to return a string or HTML result that doesn't fit well for a page or other UI component. Any string output can be returned. You can also return binary data. Stream, byte[] and Bitmap/Image results are automatically streamed back to the client. Notice that you should set the ContentType of the request either on the CallbackMethod attribute or using Response.ContentType. This ensures the Web Server knows how to display your binary response. Using a stream response makes it possible to return any of data. Streamed data can be pretty handy to return bitmap data from a method. The following is a method that returns a stock history graph for a particular stock over a provided number of years: [CallbackMethod(ContentType="image/png",RouteUrl="stocks/history/graph/{symbol}/{years}")] public Stream GetStockHistoryGraph(string symbol, int years = 2,int width = 500, int height=350) { if (width == 0) width = 500; if (height == 0) height = 350; StockServer server = new StockServer(); return server.GetStockHistoryGraph(symbol,"Stock History for " + symbol,width,height,years); } I can now hook this up into the JavaScript code when I get a stock quote. At the end of the process I can assign the URL to the service that returns the image into the src property and so force the image to display. Here's the changed code: $("#btnStockQuote").click(function () { var symbol = $("#txtSymbol").val(); ajaxCallMethod("SampleService.ashx", "GetStockQuote", [symbol], function (quote) { $("#divStockDisplay").fadeIn(1000); $("#stockCompany").text(quote.Company + " (" + quote.Symbol + ")"); $("#stockLastPrice").text(quote.LastPrice); $("#stockQuoteTime").text(quote.LastQuoteTime.formatDate("MMM dd, hh:mmt")); // display a stock chart $("#imgStockHistory").attr("src", "stocks/history/graph/" + symbol + "/2"); },onPageError); }); The resulting output then looks like this: The charting code uses the new ASP.NET 4.0 Chart components via code to display a bar chart of the 2 year stock data as part of the StockServer class which you can find in the sample download. The ability to return arbitrary data from a service is useful as you can see - in this case the chart is clearly associated with the service and it's nice that the graph generation can happen off a handler rather than through a page. Images are common resources, but output can also be PDF reports, zip files for downloads etc. which is becoming increasingly more common to be returned from REST endpoints and other applications. Why reinvent? Obviously the examples I've shown here are pretty basic in terms of functionality. But I hope they demonstrate the core features of AJAX callbacks that you need to work through in most applications which is simple: return data, send back data and potentially retrieve data in various formats. While there are other solutions when it comes down to making AJAX callbacks and servicing REST like requests, I like the flexibility my home grown solution provides. Simply put it's still the easiest solution that I've found that addresses my common use cases: AJAX JSON RPC style callbacks Url based access XML and JSON Output from single method endpoint XML and JSON POST support, querystring input, routing parameter mapping UrlEncoded POST data support on callbacks Ability to return stream/raw string data Essentially ability to return ANYTHING from Service and pass anything All these features are available in various solutions but not together in one place. I've been using this code base for over 4 years now in a number of projects both for myself and commercial work and it's served me extremely well. Besides the AJAX functionality CallbackHandler provides, it's also an easy way to create any kind of output endpoint I need to create. Need to create a few simple routines that spit back some data, but don't want to create a Page or View or full blown handler for it? Create a CallbackHandler and add a method or multiple methods and you have your generic endpoints.  It's a quick and easy way to add small code pieces that are pretty efficient as they're running through a pretty small handler implementation. I can have this up and running in a couple of minutes literally without any setup and returning just about any kind of data. Resources Download the Sample NuGet: Westwind Web and AJAX Utilities (Westwind.Web) ajaxCallMethod() Documentation Using the AjaxMethodCallback WebForms Control West Wind Web Toolkit Home Page West Wind Web Toolkit Source Code © Rick Strahl, West Wind Technologies, 2005-2011Posted in ASP.NET  jQuery  AJAX   Tweet (function() { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/plusone.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })();

    Read the article

< Previous Page | 467 468 469 470 471 472 473 474 475 476 477 478  | Next Page >