|
I was working with a WCF service client application that failed. First, I had to modify the try-catch and using blocks. Then, I was able to see the real problem. The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element.
This came as no surprise to me since it needed to send and receive large amounts of data. I updated my configuration file with a new binding to use 1MB instead of 64KB. (I was using a TCP binding.)
<bindings> <netTcpBinding> <binding name="myTcpBinding" maxReceivedMessageSize="1048576" /> </netTcpBinding> </bindings>
I also updated the endpoint element in the service element by adding the bindingConfiguration attribute with the binding's name as its value. I performed both changes on the client and the server.
However, I still received exactly the same message because changing maxReceivedMessageSize wasn't enough. I also needed to update the maxBufferSize attribute of the same binding element.
<bindings> <netTcpBinding> <binding name="myTcpBinding" maxBufferSize="1048576" maxReceivedMessageSize="1048576" /> </netTcpBinding> </bindings>
|
|
My WCF service client kept giving me the generic fault message. The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
I enabled fault text in the configuration file.
<serviceDebug includeExceptionDetailInFaults="true" />
However, it still gave me the generic fault message. Here's how my client-side code looked.
try { using(var client = new ControlServiceClient()) { client.DoSomething(); client.DoSomethingElse(); } } catch(Exception ex) { Debug.WriteLine(ex); }
The problem is the placement of the using block. If one of the methods in it throws an exception, program flow moves to the catch block. However, leaving a using block invokes the Dispose method of the IDisposable interface. In this case, the service client's implementation of Dispose will invoke Close which throws another exception, hiding the first one. To fix it, I moved the using statement outstide of the try-catch block and introduced a call to Abort.
using(var client = new ControlServiceClient()) { try { client.DoSomething(); client.DoSomethingElse(); } catch(Exception ex) { client.Abort(); Debug.WriteLine(ex); } }
Invoking Abort does not throw an exception and prevents the Dispose implementation from invoking Close. |
|
While investigating MVVM in Silverlight 2, I came across a problem putting a UserControl in a DataTemplate used by an ItemsControl. I started with the following XAML for the DataTemplate used by my ItemsControl in the page.
<UserControl.Resources> <DataTemplate x:Key="ListDataTemplate"> <a:DetailControl DataContext="{Binding}" /> </DataTemplate> </UserControl.Resources>
I don't know why but the data didn't bind correctly in my DetailControl so for every row in the data bound to the list control I ended up with user controls in my list that had no data. Wrapping the user control in a Grid in the DataTemplate corrected the problem.
<UserControl.Resources> <DataTemplate x:Key="ListDataTemplate"> <Grid> <!-- Data-binding fails if I don't wrap it in a panel. --> <a:DetailControl DataContext="{Binding}" /> </Grid> </DataTemplate> </UserControl.Resources> |
|
The MSDN documentation is incorrect. In the current released version of Silverlight 2, 2.0.31005.0, you cannot use attribute syntax for the Figures property of a PathGeometry in XAML. For instance, the following will fail, throwing a XamlParseException.
<Path Fill="Black">
<Path.Data>
<PathGeometry Figures="M0,0L9,0 9,9 0,9Z" /> </Path.Data> </Path>
This is true for path geometries used in clipping regions as well. The following will fail in the same way.
<Rectangle Width="23" Height="23" Fill="Black">
<Rectangle.Clip>
<PathGeometry Figures="M0,0L9,0 9,9 0,9Z" /> </Rectangle.Clip> </Rectangle>
Instead, you must use the more verbose element syntax.
<Rectangle Width="23" Height="23" Fill="Black"> <Rectangle.Clip> <PathGeometry> <PathGeometry.Figures> <PathFigure StartPoint="0,0" IsClosed="True"> <LineSegment Point="9,0" /> <LineSegment Point="9,9" /> <LineSegment Point="0,9" /> </PathFigure> </PathGeometry.Figures> </PathGeometry> </Rectangle.Clip> </Rectangle>
This is not true for the Data property of a Path. The following will work as expected.
<Path Fill="Black" Data="M0,0L9,0 9,9 0,9Z" /> |
|
I suggest following the directions found here but if you need a different solution try the following instead.
Add this method to your Silverlight in a convenient place, such as your application class.
public static void OpenBrowser(string url) { if(HtmlPage.BrowserInformation.UserAgent.Contains("Safari")) { HtmlElement anchor= HtmlPage.Document.GetElementById("externalAnchor"); anchor.SetProperty("href", url); HtmlElement button= HtmlPage.Document.GetElementById("externalButton"); button.Invoke("click", null); } else HtmlPage.Window.Navigate(new Uri(url, UriKind.RelativeOrAbsolute), "_blank"); }
Then, add this code anywhere in the HTML.
<a id="externalAnchor" style="display:none;"></a> <input id="externalButton" type="button" onclick="window.open(document.getElementById('externalAnchor').href)" style="display:none;" /> |
|
Recently, there was an article on avoiding inheritance on the Visual Studio start page news channel. In general, I like the content of the article. I don't think there is any misinformation, but I do think there is some misrepresentation. I believe this article is overly critical of inheritance. I hope the author isn't simply being fashionable by deriding inheritance in favor of generics and lambdas. One realization I have come to when talking with many other developers is that there is a good number of developers that don't realize that inheritance introduces dependencies directly into your classes.
This is a problem of education, not abstraction. This doesn't mean inheritance is flawed; it means the developers' knowledge is incomplete. Your derived class is now dependant [sic] upon the interface and behavior of your base class. Worded another way, your derived class is now strongly coupled to your base class.
Correct: that is by design. That is a known and welcome aspect of inheritance. If Foo inherits Bar, a Foo is a Bar and I expect it to behave as such. For instance, if I need to add another abstract method I didn't originally think of, every single class that derives from that base class now must change in order to implement that behavior.
If you're adding an abstract method, it means you want derived classes to implement it. Otherwise, either add a virtual method or derive a new class that contains the new abstract method. Or, if I change the behavior of one of the methods in my base class, I can find myself in a situation where one of my derived classes will break because they were relying on that base class behavior to act a given way….
This problem isn't restricted to class hierarchies; this will happen with any code. Any time you change code anywhere, you need to re-test your application. If you're writing a class library for consumption by others, you're only alternative to potentially breaking a client is to add a new method with the new behavior or create an entirely new class (e.g. the ConfigurationManager class instead of the ConfigurationSettings class). The .NET framework even has an attribute (the ObsoleteAttribute class) specifically for dealing with legacy. There are plenty of instances of this in the System.Runtime.InteropServices namespace.
Everything else about the article is pretty good. His use of the Command pattern is a fine example of when to use generics instead of inheritance. I have a couple of additions to his discussion.
- And because of leveraging a common base class, we can use polymorphism to reuse this code even more (like having a list of commands that we can execute in a script or elsewhere).
I think this is still useful but he didn't come back to it in his re-implementation using generics. Here, he can still benefit from an interface. Having his GenericCommand<TReceiver> implement, say, ICommand (having the same definition as his Command abstract class) enables generic containers and iteration.
- First of all, for every home device that we wish to turn on and off, we would be introducing two new classes into our code.
In his example where he addresses this with generics, .NET will introduce new classes (e.g. GenericCommand`1[Garage]), but they're created at run-time. You won't find them if you use, say, Reflector to look at the assembly. This doesn't invalidate the way he addresses this concern since those generated classes aren't introduced into our code.
- If we change our Execute() method in our base class from abstract to virtual in order to introduce common behavior, how do you guarantee that the base method is called when it should be? In a derived class, should you call the base method before your own execution code, or after? What if I want common code in my base class that will be executed both before and after the behavior in my derived classes?
The answer to all of these is "use the Template Method pattern." In fact, using lambdas to defer the actual implementation of the command behavior to a separate entity as he does is in essence a use of the Strategy pattern, a relative of the Template Method pattern. (BTW, Wikipedia's Python example of the Strategy pattern can be re-implemented in C# without loss of generality by using the same techniques found in this article.) |
|
I've seen several master-detail examples using a GridView that controls a DetailsView but no parent-child examples that reverse their roles (i.e., an example using a DetailsView that contains and controls a GridView). I alluded to such a scenario in a previous post. Here, I'll walk through the steps to create such a display.
- Create the database and tables. If you already have one with a parent-child (i.e., one-to-many) relationship, you can skip this step. Also, if you're using SQL Server 2005 instead of its Express edition, skip to sub-step c.
- From the Project menu, select "Add New Item…".
- Select the Data category, and then select the SQL Server Database template and click "Add". If it then prompts you to place it in the App_Data folder, click "Yes".

- Create a two tables, one of which has a foreign key into the other. Here is the example I'll use.

- Add some data to the tables. I'll add two companies with two divisions each.
- Create a new Web form or use one you already have. I'll use Default.aspx. Open it and switch to the Design view.
- Add a DetailsView to the design surface. You can find it in the Data section of the Toolbox.

- From the "Choose Data Source" drop-down list, select "<New data source…>". I'll select the Database data source for this walk-through.

- Select the connection to your database from the drop-down list. If it's not there, click "New Connection…" to create a new one.
- Click "Next" to save the connection string in Web.config.
- In the "Configure the Select Statement" step, select the "Companies" table (or whichever table is the parent in your schema) and select "*" to see all columns in the DetailsView. Click "Next".

- Test the query if you like. Click "Finish".
- Click the Smart Tag symbol on the DetailsView control to open it and select "Add New Field…".

- Select "TemplateField" from the "Choose a field type" drop-down list and enter some header text. I'll enter "Divisions" since that's the name of my child table. Click "OK".

- Select "Edit Templates" from Smart Tag. The control enters "Edit Template Mode" and displays an empty item template for the Divisions field. Drag a GridView from the Data section of the Toolbox into the item template.

- Create a new data source as above (steps 4 through 8) for the GridView but select all columns from the Companies table (or whichever table is the parent in your schema) instead. There is one issue to beware. VS will name the new data source for the GridView the same as that for the DetailsView. (I previously used the default, SqlDataSource1.) This will cause a designer error. Be sure to use a different name for the new data source. I'll use what is supposed to be the default, SqlDataSource2.
- If you run it now, you'll see one company but all divisions, not just those for that company.
- In the "Configure the Select Statement" page of the "Configure Data Source" wizard (the page where you select "*"), click the "WHERE…" button.
- In the "Add WHERE Clause" dialog, select "CompanyId" from the "Column" drop-down list and select "Control" from the "Source" drop-down list.
- In the Parameter properties section, select DetailsView1 from the Control ID drop-down list. Click "Add" and then click "OK".

- Verify the SELECT statement. Mine is "SELECT * FROM [Divisions] WHERE ([CompanyId] = @CompanyId)". Click "Next".
- Test the query if you like. Click "Finish".
- Press F5. Here's what it looks like in my browser.

I ran through the instructions of my previous post and had no problems with that combination of GridView, ObjectDataSource, DataSet, and stored procedures using Visual Studio 2008. It appears Microsoft fixed it since Orcas. |
|
I am still a die-hard C++ programmer. I don't call myself an expert (journeyman, perhaps); it's a huge and complex language. Put another way, it gives you enough rope to shoot yourself in the foot. Nowadays, I program primarily in C#. For the longest time, I still did significant recreational programming in C++ because I liked the power of the language and the C++ standard library, most notably the STL, which the .NET framework had not yet matched.
With .NET 2.0 and 3.x, that's changed. While I'm sure there are tasks more well suited for C and C++ (e.g. operating systems), I find myself doing much less of my recreational programming in C++. What really did it for me was the introduction of generics, introduced in .NET 2.0. Not so much that generic programming became possible, but rather the implementations of many of the same concepts found in the STL: containers, iterators, algorithms, and functors.
Iterators and functors previously existed in .NET in the forms of IEnumerable and delegates, respectively. They're more powerful now with IEnumerable<T> and anonymous methods. Those are interesting but the most interesting to me are the containers. Here is a list of the STL containers and the .NET equivalents. I also listed the STL insert complexity.
1 These are more difficult to construct since they allow duplicate keys. Perhaps use a Dictionary of Lists.
There are other containers but they're either more for special purposes (e.g. bitset and valarray) or not yet part of the standard (e.g. hash_set and unordered_map).
.NET 3.x, with LINQ and extension methods, gives us not only many of the functors but also something even more valuable: expressiveness and elegance. For instance, which is more readable? (These are adapted from Scott Meyers' Effective STL, Item 47.)
C++
vector<int> v;
// ... other statements here
// remove elements < 100 except those preceding the last element >= 2500 v.erase( remove_if(find_if(v.rbegin(), v.rend(), bind2nd(greater_equal<int>(), 2500)).base(), v.end(), bind2nd(less<int>(), 100)), v.end());
C#
List<int> v= new List<int>();
// ... other statements here
// remove elements < 100 except those preceding the last element >= 2500 v = v.SkipWhile((i, n) => n < 100 && i >= v.Last(m => m >= 2500)).ToList();
I still like C++ and I understand the above statement and have written many like it (although I wasn't sure how to indent it since I prefer to break it up as he suggests in his book). I'm ignoring efficiency1 and aliasing2 here, but for readability, I side with C#.
1 The C++ code is likely to be more efficient, at least for primitive types such as int used here. For more complex classes with expensive copy constructors, the C# code is perhaps better since it deals with references, not values. C++ can certainly handle references (as pointers) but, in an unmanaged world, one must then contend with memory management. 2 The C++ code modifies the vector while the C# example creates a new list. That matters if other code has a reference to the original list. It's possible to construct a more complex C# expression or set of C# statements involving RemoveAll or RemoveRange. |
|
If you have code that you want to run only while debugging in Visual Studio, you can detect it if you are running in its hosting process, which is enabled by default.
#if DEBUG if(AppDomain.CurrentDomain.FriendlyName.EndsWith("vshost.exe")) { // Perform whatever tasks depend on running inside the Visual // Studio debugger. } #endif
While it does provide several features not otherwise available, you might have a reason to disable it (such as a corrupted vshost.exe file). To do so, uncheck the last box (shown checked here) on the Debug tab in the Project Properties window. |
|
If in a class you have a value type property that is optional, it's common to specify it as nullable. However, if you serialize a nullable value type property to XML, you'll get something like this if it's null.
<Value xsi:nil="true" />
Or, if you turned off declaration of the XML schema instance namespace, it will be even more verbose.
<Value p2:nil="true" xmlns:p2="http://www.w3.org/2001/XMLSchema-instance" />
This might look strange but it will properly deserialize. Nonetheless, you might have a reason to have a nullable value type property serialize the way a class property does, which is to not appear in the XML output at all if it's null. Setting the IsNullable property of the XmlElement attribute for such a property will have no effect. (Well, setting it to false will result in a run-time error.)
The XmlElementAttribute.IsNullable Property page at MSDN has this to say.
You cannot apply the IsNullable property to a member typed as a value type because a value type cannot contain null. Additionally, you cannot set this property to false for nullable value types. When such types are null, they will be serialized by setting xsi:nil to true.
One work-around is to declare another property that is a class type, such as string, and parse it in the nullable value property.
[XmlElement("Value")] public string ValueString { get; set; }
[XmlIgnore] public int? Value { get { return int.Parse(ValueString); } set { ValueString= value.ToString(); } }
Of course, you can go in the opposite direction as well.
[XmlElement("Value")] public string ValueString { get { return Value.HasValue ? Value.Value.ToString() : null; } set { if(value != null) Value= int.Parse(value); else Value= null; } }
[XmlIgnore] public int? Value { get; set; }
|
View in Web Browser /personal/chris/Blog/_layouts/VisioWebAccess/VisioWebAccess.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 0x0 0x1 FileType vdw 255 Compliance Details javascript:commonShowModalDialog('{SiteUrl}/_layouts/itemexpiration.aspx?ID={ItemId}&List={ListId}', 'center:1;dialogHeight:500px;dialogWidth:500px;resizable:yes;status:no;location:no;menubar:no;help:no', function GotoPageAfterClose(pageid){if(pageid == 'hold') {STSNavigate(unescape(decodeURI('{SiteUrl}'))+'/_layouts/hold.aspx?ID={ItemId}&List={ListId}'); return false;} if(pageid == 'audit') {STSNavigate(unescape(decodeURI('{SiteUrl}'))+'/_layouts/Reporting.aspx?Category=Auditing&backtype=item&ID={ItemId}&List={ListId}'); return false;} if(pageid == 'config') {STSNavigate(unescape(decodeURI('{SiteUrl}'))+'/_layouts/expirationconfig.aspx?ID={ItemId}&List={ListId}'); return false;}}, null); return false; 0x0 0x1 ContentType 0x01 898 Edit in Browser /_layouts/images/icxddoc.gif /personal/chris/Blog/_layouts/formserver.aspx?XsnLocation={ItemUrl}&OpenIn=Browser&Source={Source} 0x0 0x1 FileType xsn 255 Edit in Browser /_layouts/images/icxddoc.gif /personal/chris/Blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser&Source={Source} 0x0 0x1 ProgId InfoPath.Document 255 Edit in Browser /_layouts/images/icxddoc.gif /personal/chris/Blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser&Source={Source} 0x0 0x1 ProgId InfoPath.Document.2 255 Edit in Browser /_layouts/images/icxddoc.gif /personal/chris/Blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser&Source={Source} 0x0 0x1 ProgId InfoPath.Document.3 255 Edit in Browser /_layouts/images/icxddoc.gif /personal/chris/Blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser&Source={Source} 0x0 0x1 ProgId InfoPath.Document.4 255 View in Browser /personal/chris/Blog/_layouts/xlviewer.aspx?id={ItemUrl}&DefaultItemOpen=1 0x0 0x1 FileType xlsx 255 View in Browser /personal/chris/Blog/_layouts/xlviewer.aspx?id={ItemUrl}&DefaultItemOpen=1 0x0 0x1 FileType xlsm 255 View in Browser /personal/chris/Blog/_layouts/xlviewer.aspx?id={ItemUrl}&DefaultItemOpen=1 0x0 0x1 FileType xlsb 255 View in Browser /personal/chris/Blog/_layouts/xlviewer.aspx?id={ItemUrl}&DefaultItemOpen=1 0x0 0x1 FileType ods 255 Document Set Version History javascript:SP.UI.ModalDialog.ShowPopupDialog('{SiteUrl}/_layouts/DocSetVersions.aspx?List={ListId}&ID={ItemId}') 0x0 0x0 ContentType 0x0120D520 330 Send To other location javascript:GoToPage('{SiteUrl}/_layouts/docsetsend.aspx?List={ListId}&ID={ItemId}') 0x0 0x0 ContentType 0x0120D520 350 |
|
|
|
|