Follow me on Twitter at Twitter.com/wbm
FYI, I'm blogging most of my stuff over at More Wally now.
You might want to add my rss feed to your reader at:http://morewally.com/cs/blogs/wallym/rss.aspx
Wallace B. McClure

Wallace B. McClure

All About Wally McClure - The musings of Wallym on .NET, Sql, ASP.NET, and other crazy shenanigans

News

Personal Blog

Work Blog

.NET

Book Authors

Business

Family

Friends

Georgia Tech Bloggers

Personal

Today's my birthday

Rock!

Posted: Jun 24 2009, 09:21 AM by Wallym | with no comments |
Filed under:
Visual Studio 2010 Beta 1 and .NET 4.0 Beta 1 on msdn downloads
Since no one else has said it, I will.  Visual Studio 2010 Beta 1 and .NET 4.0 Beta 1 are on msdn for subscribers.  Just stay off until my download is complete. ;-)
ASP.NET Podcast Show #140 - ASP.NET 4.0 Ajax Databinding

Original Url: http://aspnetpodcast.com/CS11/blogs/asp.net_podcast/archive/2009/04/28/asp-net-podcast-show-140-asp-net-4-0-ajax-databinding.aspx

Subscribe to Everything.

Subscribe to WMV.

Subscribe to M4V.

Subscribe to MP3.

Download WMV.

Download M4V.

Download MP3.

Show Notes:

PS. I started getting sick about 5-10 minutes into the show, so if I sound somewhat confusing after that, I apologize.

Source Code:

<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.Master" AutoEventWireup="true" CodeBehind="Content.aspx.cs" Inherits="TwitterApp.Content" %>

<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">

</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">

<asp:ScriptManager ID="sm" runat="server">

<Scripts>

<asp:ScriptReference ScriptMode="Inherit" Name="MicrosoftAjax.js" Path="~/js/MicrosoftAjax.js" />

<asp:ScriptReference ScriptMode="Inherit" Path="~/js/MicrosoftAjaxAdoNet.js" />

<asp:ScriptReference ScriptMode="Inherit" Path="~/js/MicrosoftAjaxTemplates.js" />

</Scripts>

<Services>

<asp:ServiceReference Path="~/TwitterService.svc" />

</Services>

</asp:ScriptManager>

<asp:TextBox ID="Status" runat="server"

TextMode="MultiLine" Rows="2" Columns="70" /><br />

<input type="button" ID="btnSubmit"

onclick="SubmitStatus()" value="Submit Status" />

<hr width="98%" />

<script language="javascript" type="text/javascript">

var userName = "More_Wally";

 

function SubmitStatus() {

var Status = $get('<%=Status.ClientID %>');

var userStatus = Status.value;

Status.value = "";

TwitterService.SubmitUserStatus(userName, userStatus,

TwitterPostCallBack);

}

function TwitterPostCallBack(result) {

TwitterService.GetUserTimeLine(userName,

TwitterServiceCallBack, TwitterServiceFailure);

}

var dv;

function pageLoad() {

var tblS = $get("tblStatus");

var uiElement = $get("twitterFriendsTimeLineListView");

dv = new Sys.UI.DataView(uiElement);

dv.add_itemCreated(fillExtra);

dv.initialize();

TwitterService.GetFriends(userName, StoreFriendsCallBack);

TwitterService.GetUserTimeLine(userName, TwitterServiceCallBack, TwitterServiceFailure);

}

var dd;

function StoreFriendsCallBack(result) {

dd = result;

}

function TwitterServiceCallBack(result) {

dv.set_data(result);

//dv.updated();

//tblStatus.style.visibility = "visible";

}

function FriendsCallBack(result, userCtx) {

dd = result;

DisplaySelect(dd, userCtx);

}

function DisplaySelect(data, userCtx) {

var i;

var opt;

var sel = $get("to" + userCtx.index);

sel.options.add(new Option("", ""));

for (i = 0; i < data.length; i++) {

opt = new Option(data[i].name, data[i].screen_name);

sel.options.add(opt);

}

}

var i = 0;

 

function fillExtra(sender, Args) {

var ctx = Args.get_templateContext();

var dt = Args.get_dataItem();

var strOut = "";

var strReturn = "<br />";

var Out = $get("Output");

var userCtx =

{

index: ctx.index

}

 

if (i == 0) {

strOut = "ctx<br />";

for (m in ctx) {

strOut += m + strReturn;

}

strOut += "<br/>ctx.nodes[0]<br />";

for (m in ctx.nodes[0]) {

strOut += m + strReturn;

}

strOut += "<br/>Data Item:<br />";

for (m in dt) {

strOut += m + strReturn;

}

Out.innerHTML = strOut;

}

i++;

if (dd == null) {

TwitterService.GetFriends("More_Wally", FriendsCallBack, null, userCtx);

}

else {

DisplaySelect(dd, userCtx);

}

}

function TwitterServiceFailure(result) {

alert("An error occurred");

}

function IterateDV() {

var count = dv.get_items().length;

var rw = "";

var controlId;

var ctx = dv.get_templateContext()

for (i = 0; i < count; i++) {

if (i == 0) {

//rw = dv.get_items()[i].elements[0].childNodes[2].childNodes[0].innerHTML;

rw = $get("Number" + i).innerHTML;

}

else {

rw += "," + $get("Number" + i).innerHTML;

}

}

alert(rw);

}

function SendMessage(i) {

var userName = "More_Wally";

var sendTo = $get("to" + i).value;

var userStatus = $get("message" + i).value;

TwitterService.DMSend(userName, sendTo, userStatus,

TwitterPostCallBack, TwitterServiceFailure);

}

String.prototype.parseURL = function() {

var URL = /[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+/;

var matches = this.match(URL);

var stringToReplace = this;

while (matches != null ) {

var m = matches[0];

var url = "<a href='" + m + "'>" + m + "</a>";

stringToReplace = stringToReplace.replace(m, url);

matches = stringToReplace.substring(stringToReplace.indexOf(url) +

url.length).match(URL);

}

return (stringToReplace);

};

String.prototype.parseUsername = function() {

var userName = /[@]+[A-Za-z0-9-_]+/;

var matches = this.match(userName);

var stringToReplace = this;

while ( matches != null ) {

var m = matches[0];

var finalMatch = m.replace("@", "");

var url = "<a href='http://twitter.com/" + finalMatch + "' target='_new'>" + m + "</a>";

stringToReplace = stringToReplace.replace(m, url);

matches = stringToReplace.substring(stringToReplace.indexOf(url) + url.length).match(userName);

};

return (stringToReplace);

};

String.prototype.parseHashtag = function() {

var hashTag = /[#]+[A-Za-z0-9-_]+/;

var matches = this.match(hashTag);

var stringToReplace = this;

while (matches != null) {

var m = matches[0];

var finalMatch = m.replace("#", "%23");

var url = "<a href='http://search.twitter.com/search?q=" + finalMatch +

"' target='_new'>" + m + "</a>";

stringToReplace = stringToReplace.replace(m, url);

matches = stringToReplace.substring(stringToReplace.indexOf(url) +

url.length).match(hashTag);

};

return (stringToReplace);

 

 

};

</script>

<input type="button" id="btnIterate"

value="Iterate" onclick="IterateDV()" />

<table>

<tr valign="top" align="left">

<td>

<table id="tblStatus" >

<thead>

<tr>

<th>

User Name

</th>

<th>

Status

</th>

<th>

Number

</th>

</tr>

</thead>

<tbody id="twitterFriendsTimeLineListView"

class="sys-template" >

<tr>

<td valign="top" align="left">

{{UserName}}<br />

<img sys:src="{{ ProfileImage }}" /><br />

<span style="font-size:smaller">

{{ StatusDate }}

</span>

</td>

<td valign="top" align="left">

<span code:after="$element.innerHTML=Status.parseURL().parseUsername().parseHashtag()" />

<!--{{Status.parseURL().parseUsername().parseHashtag()}}--></td>

<td>

<div sys:id="{{ 'Number' + $index }}">{{ $index }}</div>

<div code:if="($index % 2) == 0">even</div>

<div code:if="($index % 2) == 1">odd</div>

</td>

</tr>

<tr>

<td>

<select sys:id="{{ 'to' + $index }}" ></select>

<input type="text" sys:id="{{ 'message' + $index }}" size="50" />

</td>

<td>

<input type="button" sys:id="{{ 'btn' + $index }}"

value="Send a direct message" onclick="{{ 'SendMessage(' + $index + ')' }}" />

</td>

</tr>

<tr>

<td colspan="2">

2 way data binding<br />

{ binding Status }<br />

<input type="text" value="{ binding Status }" />

</td>

</tr>

<tr>

<td colspan="2">

<div code:before="if (i != 19) {" code:after="}">break</div>

<hr width="98%" code:if="$index != 19" />

</td>

</tr>

</tbody>

</table>

</td>

<td>

<div id="Output">

</div>

</td>

</tr>

</table>

</asp:Content>

 

Images:

ASP.NET Podcast Show #139 - David Penton and Pat Helland on Cloud Computing - audio

Subscribe to everything.

Subscribe to MP3 audio.

Download.

Original Url: http://aspnetpodcast.com/CS11/blogs/asp.net_podcast/archive/2009/04/01/asp-net-podcast-show-139-david-penton-and-pat-helland-audio.aspx

Show Notes:


Codestock Session Submissions
If you are not familiar with it, CodeStock is June 26-27 in Knoxville, TN.  If you have not submitted your talk, do so now.  Run, don't walk over to http://www.codestock.org/Speakers.aspx and submit your session.  Session submissions are due by the end of today (March 31).
Posted: Mar 31 2009, 10:38 AM by Wallym | with no comments
Filed under:
More things that I have learned with Azure

I've been working on this application to run on Windows Azure.  I wanted to share a few things that I have learned.  I'm not sure if I have missed these being covered else where, but I want to bring them up here for my own knowledge.  I find that I remember things much better if I blog them than if I put them on twitter.

  • Resource not found for the segment 'ObjectTableName." Steve Smith has a good blog post on this at http://stevesmithblog.com/blog/azure-table-storage-gotcha/.  I got this message, followed Steve's instructions and bang, still go the message.  WTF is that about!  Anyway, I found that I had to reset the table storage through the azure development storage applet and then recreate the tables from the objects in Visual Studio.  Once I did that, things seemed to work better.  Yippee!
    Another note, that you can get this error when you operate on a LINQ query that returns no objects.
  • I was running queries that were not returning any data.  WTF is that about! Then it hit me, LINQ doesn't return data until you actually ask for that data.  I need to force LINQ to send me some data in some situations.  How can I force this to occur?  I saw that some of my queries were returning data and some were not.  I started playing around and found that if I called .ToList<T>() after my query that the data always came back to me.  I figure that was a step in the right direction.
  • Azure Development Tools use Sql Server Express on the local development machine to store data during development.  I decided to look and see what is happening.  Guess what, you can connect up and see your data just like you thought you could in any application.  Also, you can use Sql Server tools to see WTF is going on.  I used that to figure out the issue above.
    Sql Express in Azure
  • DateTime.Now vs. DateTime.UtcNow.  Have you used DateTime.Now in an Azure query?  It works just fine when you are running in the local development fabric.  Deployed to the azure hosted fabric and I got an error.  You can't quite connect VS.NET to the hosted fabric to see what is going on.  After lots of testing, I changed the query I was doing to use DateTime.UtcNow andlow and behold my app started posting messages to twitter from the hosted fabric.

Original Url: http://morewally.com/cs/blogs/wallym/archive/2009/03/25/more-things-that-i-have-learned-with-azure.aspx

More reminders / gotchas from the trenches with Azure

I've been working on setting up my VPC for Azure's March CTP.  This is a fresh install.  I had everything installed.  Here are a couple of gotchas that you have to remember:

  • SqlExpress needs to be running.  I had the .\SqlExpress service turned off in my archived vpc.  With the service off, the dev tools can't see the database service so they fail.
  • Create TablesA database can be setup by right clicking on your cloud service and selecting "Create Test Storage Tables."
  • With a new installation, windows communication foundation (WCF) is most likely not setup.  You may need to setup calls to WCF.  To setup WCF, you may need to login as an Administrator and run "ServiceModelReg -i"
Original Url: http://morewally.com/cs/blogs/wallym/archive/2009/03/24/more-gotchas-from-the-trenches-with-azure.aspx
ASP.NET 4.0 AJAX - Caching Data on the client

 

One of the interesting new objects in ASP.NET 4.0 AJAX is the DataView.  its a client side object which is associated with a display tag of some type.  In my examples, I've been using a table.  I assume it could be anything.  One of the features of the DataView is the ability to call an event each time a record is bound to the DataView.  This is similar in concept to the server side asp.net grids which have the OnRowDataBound events (or similarly named).  One of the common scenarios that I see is to have a drop down list box inside of a record.  This could represent typically anything.  As I was working through the DataView, I thought about some type of efficient way to cache the data.  In my scenario, the data is constant across the rows, so caching it is fairly easy.  Anyway, here goes:

  1. I call the method to get my data first before doing anything else in my page load client side event:
            TwitterService.GetFriends(userName, StoreFriendsCallBack);
            TwitterService.GetUserTimeLine(userName, TwitterServiceCallBack, TwitterServiceFailure);
  2. In side of my StoreFriendsCallBack method, all I do is store my data to a global js variable I call dd.
        function StoreFriendsCallBack(result) {
            dd = result;
        }
  3. Finally, I test to see if my dd (dropdown) object has any data or not.  If it has data, I use it, if not, then I go ahead and call back to the server to get my data.
            if (dd == null) {
                TwitterService.GetFriends("More_Wally", FriendsCallBack, null, userCtx);
            }
            else {
                DisplaySelect(dd, userCtx);
            }
Twitter API - Submit a post in C#

I used C# and WCF, but I could have just as easily used an ASMX web service.  This code is fairly simple.  No I didn't write it initially.  I found it online (Hey, we all have to start somewhere).  I massaged it a little to fit my needs and boom, here it is.  I have decided to leave the comments for the original code sample in the post.  Note: This code will not run as listed.  You have to have a password.  This code has that as a shared variable, but I'm not showing that to you, seriously.  I hope that this is of some help to you.

        [OperationContract]
        public void SubmitUserStatus(string username, string tweet)
        {
            // encode the username/password
            string user = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(username + ":" + password));
            // determine what we want to upload as a status
            byte[] bytes = System.Text.Encoding.ASCII.GetBytes("status=" + tweet);
            // connect with the update page
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://twitter.com/statuses/update.xml");
            // set the method to POST
            request.Method = "POST";
            // thanks to argodev for this recent change!
            request.ServicePoint.Expect100Continue = false;
            // set the authorisation levels
            request.Headers.Add("Authorization", "Basic " + user);
            request.ContentType = "application/x-www-form-urlencoded";
            // set the length of the content
            request.ContentLength = bytes.Length;
            // set up the stream
            Stream reqStream = request.GetRequestStream();
            // write to the stream
            reqStream.Write(bytes, 0, bytes.Length);
            // close the stream
            reqStream.Close();
        }

Original Url: http://morewally.com/cs/blogs/wallym/archive/2009/03/20/twitter-api-submit-a-post-in-c.aspx

Why am I writing against the Twitter API directly?

Yeah, so some of my friends asked me why I am not using a twitter library instead of calling the api directly.  Yeah, I'm wondering that to.  Seriously, the reason why I am doing that is that .net libraries to call out to twitter that I tried under VS 2008, did not work with Windows Azure. These libraries seemed to generate a security exception.  Given azure's security requirements being a little more than regular asp.net, I decided to just drop the search for a library and make my calls on my own.  Not sure if its a good decision or not, but its what I did.

Original Url: http://morewally.com/cs/blogs/wallym/archive/2009/03/18/why-am-i-writing-against-the-twitter-api-directly.aspx

PS. I hear that Full Trust and Native Code support are coming to Azure.

Posted: Mar 24 2009, 07:00 PM by Wallym | with 2 comment(s)
Filed under: ,
More Posts Next page »