So this is a pretty straightforward concern, but I wanted to add validation notation to a FieldTemplate's Label, and not necessarily its control. In ASP.NET's dynamic data, this isn't straightforward. What I found is that using Entity Templates is better than editing individual Field Templates.
Go into your dynamic data directory and open Default_Edit.ascx and Default_Insert.ascx files. Add a Label to each, like so. This label represents our required field token.
<asp:Label OnInit="Required_Init" runat="server" Text=" *" Visible="false" />
Now, you'll notice this control has an OnInit Handler. Basically, these controls IDs are not available in the codebehind based on the draw order, from what I can tell. So you can set their values when they are drawn, not on a global control-wide event, but on the individual control's events.
protected void Required_Init(object sender, EventArgs e)
{
if (currentColumn.TypeCode != TypeCode.Boolean)
((Label)sender).Visible = currentColumn.IsRequired;
}
Basically, you create a simple event listener that will hide or show the control you just added based on the required-ness of the field. Note that I do not set the label to visible if the column is bound to a Boolean; this is because Booleans render as checkboxes and the idea of 'requiredness' sort of doesn't fit... if you don't check the checkbox, you are still submitting the field with a value of 'false', so required does not apply.
As part of a kiosk application written in WPF, the client wanted 'Swipe'-like functionality similar to many touch-enabled smartphones. It's actually not that hard in .NET 4 and WPF.
First, add a property to your page/control that keeps track of the Touch that the user has initiated to start the swipe event:
protected TouchPoint TouchStart;
In the codebehind of the Page or Control you're building, add the following handlers:
public BasePage()
{
this.TouchDown += new EventHandler<TouchEventArgs>(BasePage_TouchDown);
this.TouchMove += new EventHandler<TouchEventArgs>(BasePage_TouchMove);
}
These handlers help detect when a user has pressed down and moved his/her finger over your page or control.
Next, handle the initial Touch event that triggers the swipe:
void BasePage_TouchDown(object sender, TouchEventArgs e)
{ TouchStart = e.GetTouchPoint(this); }
Finally, handle the movement aspect of the touch. If the movement exceeds some threshhold; then we consider it a swipe and execute whatever code we want to do (Navigation, animation, etc)
Here, 'AlreadySwiped' is just a flag property so we don't execute the same task multiple times if the swipe exceeds our threshhold more than once. You are responsible for resetting it after you do your on-swiped code. Also, I used 200 pixels as the swipe threshhold, but you may want a bigger/smaller value. You may also want to consider percentages of X here instead of actual pixels.
void BasePage_TouchMove(object sender, TouchEventArgs e)
{
if (!AlreadySwiped)
{
var Touch = e.GetTouchPoint(this);
//right now a swipe is 200 pixels
//Swipe Left
if (TouchStart != null && Touch.Position.X > (TouchStart.Position.X + 200))
{
RunMyCustomCode();
AlreadySwiped = true;
}
//Swipe Right
if (TouchStart != null && Touch.Position.X < (TouchStart.Position.X - 200))
{
RunMyCustomCodeSwipeRight();
AlreadySwiped = true;
}
}
e.Handled = true;
}
This should be straightforward but send me a message if you have any questions.
By default, the Entity Data Model version of Dynamic Data allows you to use a Many-To-Many fieldtemplate user control, which on display shows you a nice list of links for each related entity. However, in some instances you might not want to show links. Perhaps you want to show plain text, or maybe a custom control?
Diving into the code for the Many-To-Many field template, its not clear exactly how the binding is happening. Here is the ASPX file for the Many To Many control, before editing:
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate><asp:DynamicHyperLink runat="server"></asp:DynamicHyperLink></ItemTemplate></asp:Repeater>
Not very helpful, right? The normal controls have FieldValueString or some other property from the control available to them to bind. Here, we are in a repeater so one property won't do, we need to peer into the collection or item from the collection at binding time.
The other problem is we can't just expect to know the property name. The property name(s) may be different depending on which Many-To-Many relationship we are dealing with. So we need to know a little about how Dynamic Data works to pull this off.
The first thing we can do is replace our Dynamic Hyperlink (which seems to be smart enough at bind-time to pick up the proper fields) with a Literal or some other control, like so:
<asp:Literal runat="server" Text="<%# GetDisplayString(Container.DataItem) %>" />
cool? Now we have a literal instead of a hyperlink, and we are making a call to a function that we need to define. That function will take the individual item we've bound, and figure out what value to display. Now lets look at the function we need to make in the code behind: protected string GetDisplayString(object value){ MetaTable actualTable = MetaTable.GetTable(value.GetType()); return actualTable.GetDisplayString(value); }
This function is doing two things: It is getting the MetaTable of the object we have by inferring it from the Type of object we are binding to. Then, once it knows the MetaTable it can figure out what the Display Name should be for that field. The Display Name is taken either from the 'TableName' Data Annotation , or if one does not exist, it grabs the first string it can find from the table.
Voila! No Links anymore. That's all you need, and now you might know a little about how Dynamic Data works under the hood.
While working on a project with a LinqToSQL Classes object (.dbml), sometimes your dbml file will get hosed when you remove/add/modify some part of the data model. At first, my error was "The custom tool 'MSLinqToSQLGenerator' failed." , indicating that the LinqToSQL custom tool was failing. Oddly, what would happen is the code would end up deleting the .designer.cs file ... I googled around and found some other people who had the same issue, which for me was resolved taking the following steps:
- On your .dbml file, drill into the file and, if you are not using a partial class declaration, delete the <modelname>.cs file that's generated.
- Right-click the .dbml file and choose 'Run Custom Tool'.
This restores the <modelname>.designer.cs file, but that's only half the battle. For me, when generating the .designer.cs file, the Custom Tool no longer flagged that file as 'compile' in the build process, so while the 'custom tool' error was gone, my other 'missing data context' errors were still present. You then have to right-click on the <modelname>.designer.cs file, go to Properties, and choose 'compile' as the build action. Otherwise, you will continue to have missing <modename>DataContext errors .
Hope this helps someone! I was stumped.
So I admit it, I have gone against Microsoft's best practices and used Microsoft Excel on a server and had my web-based code call the Interop COM Library in order to generate Excel files. Sorry, but it works, and the code is managed and free. I won't lie, I love using Microsoft.Office.Interop.Excel. So suck it.
But in migrating one of our servers to a new environment, we found we could no longer generate excel files. Our code was generating the following error messages under our new environment.
Working config: Microsoft Excel Enterprise 2007 + Windows Server 2008 x64 edition + .NET 4.0 web application
Server Error in '/excel' Application.
Retrieving the COM class factory for component with CLSID {00024500-0000-0000-C000-000000000046} failed due to the following error: 80070005.
This error is basically saying that the IIS / ASP.NET framework does not have permission under its current user to run/access COM Objects.
Following the instructions here http://www.computerperformance.co.uk/Logon/code/code_80070005.htm Led me to a solution. Using DCOMCNFG you can set COM permissions. However, instead of just setting COM permissions on the 'Microsoft Excel Application', I needed to set permissions for the entire computer. The linked article has you setting permissions for 'Everyone' but that's not necessary. You only need to set permissions for NETWORK SERVICE user.
Originally, I had followed the steps located here: http://blog.crowe.co.nz/archive/2006/03/02/589.aspx ... those steps have you set permissions to NETWORK SERVICE but only on the Excel Application. For some reason, that wasn't enough on my environment, I needed to set it on the entire 'My Computer' and not the individual app.
OK, so I set up permissions, but then I was getting a totally different error, one that didn't jive at all:
“Microsoft
Office Excel cannot open or save any more documents because there is not
enough available memory or disk space.
• To make
more memory available, close workbooks or programs you no longer need.
• To free
disk space, delete files you no longer need from the disk you are saving
to.”
This is of course false. My machine had plenty of space. So what gives?
This is the hardest part to grok, IMHO. This error will NOT occur in Windows Server 2008 32 bit edition (x86). Why not? Because the Folder Structure is different for a user in x64 edition. Excel, when opened, actually tries to create some temporary files or other data when it loads. If it does not have the ability to write to the disk (either because the disk is actually full, or in our case, because that folder is not something we can write to due to security setup), then the disk error is the default message shuttled back to the user. Here are the write locations
C:\Windows\SysWOW64\config\systemprofile\Desktop (x64, does not exist by default)
C:\Windows\System32\config\systemprofile\Desktop (x86, exists by default and is writeable)
http://social.msdn.microsoft.com/Forums/en-US/innovateonoffice/thread/b81a3c4e-62db-488b-af06-44421818ef91 has more on this issue. Basically, to get this to work, take two steps: Create C:\Windows\SysWOW64\config\systemprofile\Desktop and give C:\Windows\SysWOW64\config\systemprofile folder write access to 'Everyone'. This will allow excel to proceed past this error and hopefully start automating files for you.
Finally, I was getting one last error after doing this step:
Service cannot be started.
System.Runtime.InteropServices.COMException (0x800A03EC): Microsoft
Office Excel cannot access the file 'c:\temp\test.xls'. There are
several possible reasons:
• The file name or path does not exist.
• The file is being used
by another program.
• The workbook you are trying to save has the
same name as a currently open workbook.
This is because the folder I was trying to write to was not allowed full-control rights by NETWORK SERVICE. If you app writes excel files to a directory, that directory must be full-control permissioned to NETWORK SERVICE.
ONE OTHER THING: If you are running an OFFICE TRIAL VERSION and you have not entered a license key, your app might hang and never load anything. This is because the COM Object actually spawns a modal dialog for a license key and your code will wait there for a user who will never come to add a license key. So, be sure if you're automating excel that you ONLY using a registered version and not a 30 day trial or unlicensed version.
So I took a new job which has me writing C# code again, which is great! A lot of new developments have happened in ASP.NET land since I've been gone, such as MVC framework, ASP.NET 3.5, etc. However, I've been working to keep up with them and I'm excited about what the future holds.
The last few days I've been working on a Flex + Sharepoint project for my employer. Sharepoint has a robust set of web services, but accessing them can be a bit confusing. For the method 'GetListItems', accessing all items from a list can be pretty easy... the http://sharepointserver/_vti_bin/Lists.asmx service endpoint provides you with the ability to getListItems by listName ...however, if you want to do more than just grab one list item, you might be in for a hurting. Getting a specific subset of lists means you have to pass in a complex parameter, like viewFields ... The viewFields parameter of GetListItems is not a simple type like a string or number. Instead, its an XML subtype and you're required to pass in a specific format of XML within this node. If you pass XML that sharepoint does not expect, you'll see something like ' ViewFields is missing or invalid' ... Normally people consume web services with generated code from ASP.NET... When I found myself in Flex, however, the generated tools fell a little short.
Problem 1 is that Flex WebServices libraries by default append a namespace to each node that they send in their Soap Bodies. Usually the namespace is "tns:" ... that's fine, but it was unclear to me if the complex XML children parameters of the webservice needed this namespace too... turns out, they do not.
<soap-env:envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap-env:body>
<tns:getlistitems xmlns:tns="http://schemas.microsoft.com/sharepoint/soap/">
<tns:listname>Regions</tns:listname>
<tns:viewfields>
<viewfields>
<fieldref name="LinkTitle">
</fieldref>
</viewfields>
<tns:rowlimit>2</tns:rowlimit>
<tns:queryoptions>
<queryoptions>
<includemandatorycolumns>FALSE</includemandatorycolumns>
<dateinutc>TRUE</dateinutc>
</queryoptions>
</tns:queryoptions>
</tns:viewfields>
</tns:getlistitems>
</soap-env:body></soap-env:envelope>
(note the lack of 'tns:' in the 'queryoptions' and 'viewfields' parameters)
Problem 2 is lack of examples of actual web requests of Sharepoint services. Which normally you wouldn't need if you're consuming generated code from Visual Studio. But if you're writing custom webservice wrappers, or doing anything nonstandard, then you need to have your hands dirty and understand what's going on at the transport level. For a while I didn't realize that the viewFields parameter needed , as its root child element, a viewFields element... the examples page was unclear; and every other code example had me writing ASP,NET go-between layers. That's not what I want, I want my Flex movie talking right to sharepoint. Anyways, what made this whole process way easier was Flash Builder 4, which generates code for you based on a WSDL; a lot like ASP.NET does. So you end up with something like this:
var viewFields:XML = <ViewFields><FieldRef Name="LinkTitle" /></ViewFields>;
var queryOptions:XML =
<QueryOptions>
<IncludeMandatoryColumns>FALSE
</IncludeMandatoryColumns>
<DateInUtc>TRUE</DateInUtc>
</QueryOptions>;
var myLists:Lists = new Lists();
myLists.addEventListener(FaultEvent.FAULT, handleFaults);
myLists.addEventListener(ResultEvent.RESULT, RegionsResult);
myLists.GetListItems("Regions",null, null, viewFields, "2", queryOptions, null);
Makes sense now, but if you're coming in green, Sharepoint connectivity can be a pain without raw XML examples!
Word to the wise, unless you want to spend hours tracking down idiotic Stack Overflows, check your Sitemap files in ASP.NET. Each sitemap node can contain a 'Provider' attribute. This is designed so that you can set up several sitemaps, and have a master sitemap file pull submenuitems from seperate sitemap files (or databases, depending on your sitemap provider configuration, and whether you rolled your own. However, if you mistakenly point a sitemap provider node to the same provider that references the sitemap file you're in, you'll get a stack overflow error. This was tricky because its actually the webserver that blows the stack, so you can't debug or trace your way out of it. What a fool I've been :)
So I am back into making .NET websites... and I love the web.sitemap feature of .NET 2.0+ However, I like my web folder structure to be semantic. This means that instead of clunky files with extensions, I like to have a directory for every portion of the site. Example:
http://www.website.com/products/, http://www.website.com/aboutus/
And then every folder has a Default.aspx ... but the problem with this is that the sitemap, when connected to an ASP.NET Menu control, is that the selected page is only recognized if the page name is included... so my sitemap has to be /products/Default.aspx , instead of just /products/... that's a bummer, because then I lose my semantic 'feel'.
Anyone have any ideas on how to modify this? I'd prefer not to override the Menu control if I don't have to.
Update: So I dug a little deeper and found a solution. First, in your web.sitemap file, keep all the URLs to be exact, including the Default.aspx file. Then, in your menu control, add an onDataBound event handler as such:
protected void SubMenu_DataBound(object sender, EventArgs e)
{
foreach (MenuItem Mi in ((Menu)sender).Items)
{
//Trim default.aspx from Menu Item URL; this is for SEO
Mi.NavigateUrl = Mi.NavigateUrl.Replace("Default.aspx", "");
}
}
So I've been re-tooling my demo-game in XNA to take advantage of XNA 2.0 enhancements. So one thing I noticed is that my very simple code that I lifted from NetRumble project wasn't working in my project. It was a simple sign-in invocation:
if (!Guide.IsVisible)
{
Guide.ShowSignIn(1, false);
}
It was displaying, but not responding to input. (although my underlying components were responding to input.)
I had included the addition of the proper component in the Game's constructor:
Components.Add(
new GamerServicesComponent(this));
but still no luck. Finally, even though it wasn't in the NetRumble game, I found in the MSDN documentation that "However, in some cases a program might not use the XNA Framework application model or component infrastructure." Whatever. I thought I was doing everything right. But turns out I needed to manually 'prime the pump', so to speak.
http://msdn2.microsoft.com/en-us/library/bb975692.aspx
Adding the following line in the Game's Update method:
GamerServicesDispatcher
.Update();
Solved my problem. Unsure what I did to hose this component though. Or automatically adding components. Probably somewhere deep in my code I have the Game Components object do a .Clear or something
Sometimes we have objects which have timespans in our database, such as valid dates for coupons, or say active dates of a sale, or trigger, or some other event. in searching through these, we may want to give a user the ability to see all of these objects which were 'active', or whose timespan intersects a user's search criteria. So the user gives a set of dates, and we want to see if any date inside the user's date at all also exists inside the date that the object in our DB was active. The following pseudo-code should hash out how I solved this problem.
AND(
(userselected_start_date <= dbobject_end_date AND userselected_end_date >= dbobject_start_date )
OR
(userselected_start_date <= dbobject_start_date AND userselected_end_date >= dbobject_end_date)
OR
((userselected_start_date <= dbobject_end_date AND userselected_start_date >= dbobject_start_date) OR
(userselected_end_date >= dbobject_start_date AND userselected_end_date <= dbobject_end_date))
)
These three OR statements essentially fill the three criteria about the user's timespan and how it relates to the timespan in the database. There are four possibilities for the set theory relationship between the date ranges.
- The date ranges share no common dates. This means the sets are disjoint, and in the above where clause, the rows would not be returned
- The date range the user selects is a superset of the database range
- The date range the user selects is a subset of the database range
- The date range the user selects has some members, but not all members, which are also found in the date range in our database
This is a bit obscure, but in writing web reports this has come up a few times. Hope it helps someone.
Update:
Ruud Campsteijn points out that it is much easier to check if dates don't intersect, and invert the results.
AND NOT (daterange1_startdate > daterange2_end_date OR daterange1_endate < daterange2_startdate)
So I'm working on a small SQL Server 2005 Analysis Services Project in Visual Studio 2005. Anyone who's ever used this tool knows that its less than forgiving if you have foreign key issues. Namely, if you have a table with a foreign key , and the associated key ID doesn't exist in the other table, you'll get an error. So I have not only a data pull into a warehouse, but a second set of scripts which normalize any rouge data / orphaned IDs.
However, after I thought I fixed all the 'gotchas', I was still getting errors that said that the DB was unable to find the associated key. After much soul searching, I saw the key it was referring to was in the same table? how can a Primary key be looked at as a foreign key? Later I found that the answer was, re-process the entire solution, not just the specific cube. Turns out, if you make dimension changes and just try to process the cube, the cube won't process some of the time, depending on the change. So now, even though its more time consuming, no matter what, I reprocess my entire solution to make sure I don't run into these little inconsistencies.
I am writing a Business Intelligence Project and I found I needed to be able to warehouse data from a MySQL Server. Rather than spend tons of money for a DB conversion software kit, I decided to use a linked server to communicate between the two. Luckily, a generous blogger at Windows Live Spaces provided me with all the steps, pretty much. Thanks Dinesh!
Also, please note, he is wrong on a few items. You don't need to use OPENQUERY, at least not for SQL Server 2005. You just need to use the triple-dot notation, AKA
SELECT * FROM LINKEDSERVER...tblname
And I wasn't able to get the generic DSN method working. I created a local SYSTEM DSN first, then just put the system DSN name in the appropriate linked server slot.
So I recently updated my XNA project to 2.0 to take advantage of the cool networking libraries and such. However, now I've noticed that game components I add to the component list no longer automatically begin calling their draw methods once they're added. Perhaps previously I was implementing DrawableGameComponents wrong, but I was under the assumption that once you add them to the components list, they automagically draw themselves. They did in 1.0, and now in 2.0 I have to manually call their .Draw method. Maybe the XNA community can help out with this?
UPDATE: This article by a member of the XNA team may shed light on my problem. there's a property of a DrawableGameComponent called 'Visible'... it may have been set default true in 1.0 and 2.0 its no longer default enabled.
http://blogs.msdn.com/etayrien/archive/2007/02/02/first-person-shooter-cameras.aspx
So I just took a new job at a new company, and of course, it wouldn't be the same if I were still doing the same type of technology. Unfourunately I've taken a position developing in Coldfusion, so I'll be doing less .NET work and that means less blog posts. I still have personal .NET projects I need to get done (including a MySQL -> SQL Server integration / reporting server deployment I want to get up and running), so expect sporadic updates. I'll respond to any questions via email, though. Keep rocking C#!
So I was optimizing a query that displays a timetable of television programming. I'm working to try to optimize it because its currently taking 3-10 seconds per execution, which is less than optimal, considering that the query needs to be made 48 times per pageload, to load 48 timetables.
The query looks something like this:
SELECT * FROM TimeSlotsInADay CROSS JOIN (
SELECT DISTINCT
dayofweek FROM Dashboard_TEST.dbo.broadcastDates
)
INNER JOIN ProgrammingData
Now normally you'd think that wouldn't be too bad. Basically we have a list of timeslots, and we make an entry for every timeslot, every day. But it turns out, the bottleneck according to the Execution Planner was actually the cross join. So I ran the subquery and found out that the subquery was returning days in reverse order, while all my Indexes on those day fields were set to ASC order. So basically when the JOIN happened on programming data, because the list was reversed, the index scanning ended up being equivalent to a table scan.
So I modified the list to ORDER BY on the subquery (which requires a TOP statement), so the Subquery now looks like:
SELECT
DISTINCT TOP 7 dayofweek FROM Dashboard_TEST.dbo.broadcastDates ORDER BY 1And now the entire parent query executes in under a second. Hope this helps someone
More Posts
Next page »