This is more of an exploratory entry than a solution to a problem. Today I wrote this code to handle updating a C# object from a Dictionary
At his point I remembered about UpdateModel(). If you are using .NET MVC, you don't need to use this. There is already the handy UpdateModel() function that will do this work for you. So if you have this problem in MVC, use UpdateModel().
At the end of the day, I came back to this problem because I knew that there was a solution, since UpdateModel() does the same function, and I wanted to know how it was done. So I attempted a number of solutions to how to convert a string to a nullable value. At some point I found the solution below in Stack Overflow:
using System.ComponentModel; public partial class Memo { public void Update(Dictionary<string,string> collection) { var properties = TypeDescriptor.GetProperties(this); foreach (PropertyDescriptor property in properties) { if (collection.Contains(property.Name)) { var value = collection[property.Name]; property.SetValue(this, property.Converter.ConvertFromInvariantString(value)); } } } } }
The solution was the PropertyDescriptor and its converter. This worked. I should learn more about this object in the future.
Source:
On using PropertyDescriptorCollection
http://stackoverflow.com/questions/446522/how-to-set-nullable-type-via-r...
To serialize:
public void Serialize(MyLittleObject mylittleObject)
{
var stream = File.Open(path, FileMode.Create);
var binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(stream, myLittleObject);
stream.Close();
}
To deserialize
public MyLittleObject Deserialize()
{
var stream = File.Open(filePath, System.IO.FileMode.Open);
var binaryFormatter = new BinaryFormatter();
var result = (MyLittleObject)binaryFormatter.Deserialize(stream);
return result;
}
This is a cheat sheet on how to make events in .Net. This is not a tutorial. There are already good tutorials out there about how to create events in .Net. Read one of those if you need to learn about how to write events. Read this one, which is the basis of this cheat sheet: http://www.knowdotnet.com/articles/creatingevents.html
This short document is for those people who already now how to work with events, don't get to write events too often, but need a quick glance at the syntax and steps needed to do it. That was one long sentence to say that this is a recipe.
The scenario: you are writing an object that needs to expose an event, such
as clicking on an image within a control.
I. Simple event, which uses the framework EventHandler
1. We declare an event
public event EventHandler ImageClicked;
2. Implement the On method:
protected virtual void OnImageClicked(EventArgs args)
{
if(this.ImageClicked != null){
this.ImageClicked(this, args);
}
}
Done.
II. An event with a custom event handler
1. Create a class that derives from EventArgs as you custom event arguments
public class ImageClickedEventArgs : EventArgs
{
public string ImageUrl;
public ImageClickedEventArgs(string imageUrl)
{
this.ImageUrl = imageUrl;
}
}
2. Create a delegate to act as the event handler that uses your custom event arguments class
public delegate void ImageClickedEventHandler(object sender, ImageClickedEventArgs args);
3. Create the event, using the custom event handler delegate type
public event ImageClickedEventHandler ImageClicked;
4. Implement the On method, following the instructions above.
III. To hook up the event programmatically, in another object:
public class bogus
{
....
var imageControl = new ImageControl();
imageControl += new EventHandler(event_handler_method_name);
private void event_handler_method_name(object sender, EventArgs e)
{
...;
}
}
There are a lot of entries on how to upload files in silverlight, so I won't repeat that code. I will show you how simple it is to turn those examples, which upload immediately after selecting a file, into a two-step process, where you first select a file and then click submit.
It is amazingly simple.
This is what most examples look like:
private void Browse_Click(object sender, RoutedEventArgs e)
{
bool? result = dialog.ShowDialog();
if (result == true)
{
UploadFile(); //Where the painful details are
}
}The first step is to take out UploadFiles() method and put code that will show in a textbox the name of the file:
private void Browse_Click(object sender, RoutedEventArgs e)
{
bool? result = dialog.ShowDialog();
if (result == true)
{
textSelectedFile.Text = dialog.File.Name;
}
}The second and last step is to populate the event for the upload button with the UploadFile() method. Notice that the method must check that the dialog.File object is not set to null.
private void Upload_Click(object sender, RoutedEventArgs e)
{
if (dialog.File != null)
{
UploadFile(); //Painful details moved here!
}
}And that is all. Easy, isn't it?
I have been working on a silverlight project recently, so I got a lot of little nibbles of wisdom on this technology. Unfortunately I am very busy for the next few weeks, so I won't get to share them with readership, which mainly consists of myself (and as a reader, I just love the good quantities of great tips and information this blog provides to me.).
In any case, the weird silverlight issue of the moment:
I am working on a custom control, and then, after I did something to it, the design mode breaks. The behavior of the control is fine while I am running it; it just messes design mode big time. And it gives me an error about how the instance couldn't be created. Searching for the error message is fruitless since it seems that many things can happen to make xaml choke.
Then the message told me about how I should search at some Key Value stuff. I look towards the end of the main error, and this is what I get:
HtmlPage_NotEnabled
Which happens when you are calling on the Browser object, such as when you need to get the root url of the site.
The solution is to use the following check:
using System.ComponentModel;
if (!DesignerProperties.GetIsInDesignMode(this))
PopulateTree();For the full explanation, go to the site below. Thanks, Andy :)
http://www.andybeaulieu.com/Home/tabid/67/BlogDate/2009-06-30/Default.aspx
Yesterday I walked into an interesting problem. After I finished cleaning up an SVN debug folder, my MVC app stop working, specifically calls to JSON. That were working previously.
I thought it must have something to do with silverlight since it was there where I found the exception. I did a series of searches looking for an answer, but I didn't find one since I looking at the wrong thing.
The actual problem had to do with MVC. I was getting the following response:
This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.
I did a search on this error. Behold! The issue was a change in how JSON is handled in .NET MVC. Adding a simple line took care of the issue.
return Json(result, JsonRequestBehavior.AllowGet);
So I want to use the .Net DataContractJsonSerializer object. I check on msdn for what are the references that are needed:
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.jso...
But it didn't work. I wasted about 20 minutes trying to troubleshoot what it was. I did a search on it, and I got the following answer:
using System.Runtime.Serialization;
using System.ServiceModel;
System.Runtime.Serialization.dll
System.ServiceModel.dll
System.ServiceModel.Web.dll
http://forums.silverlight.net/forums/p/14304/367154.aspx
Grrr. What is wrong with that .Net documentation? So I go back, and scroll to the comments:
Regarding the problem mentioned earlier, i want to say this article is right: this class resides in System.Runtime.Serialization dll for the .NET Framework 4. The problem lies in the assembly version: although the class is contained in the version 4.0.0.0 assembly, you won't find it in earlier versions. This class was migrated from System.ServiceModel.Web to System.Runtime.Serialization in .NET 4.
Thus, if you are using .NET 3.5 SP1 or earlier, you should look for this class in System.ServiceModel.Web dll.
Ah! So that was the problem! Maybe this is a false memory, but wasn't there an easy way to toggle between the different versions of a page on the msdn site? That was useful.
Learning testing from dynamic languages such as javascript and php, my experience with testing uploads or file creation was via actually creating a file during test, verifying its existence, and then erasing this file. When I tried this in C# using Moq, the tests wouldn't fail, but the file wasn't created.
I was missing something, so I found this excellent link on testing file uploads in asp.net http://www.hanselman.com/blog/ABackToBasicsCaseStudyImplementingHTTPFile...
After reading it over, I realized that:
1. The problem was that I was calling SaveAs() from HttpPostedFileBase class, not HttpPostedFile. As an abstract class, this method is not implemented. Moq must implement this method for one. Nice, nice Moq.
2. There is a nice couple of method called Verifiable() and Verify(), and they belong to the Mock object. My using it in the following manner
file1.Setup(f => f.SaveAs(It.IsAny())).Verifiable();
We can later called
file1.Verify();
And this will verify that the method got called. So there is no need for me to implement SaveAs() to test that it is being called.
Bonus aside:
Thinking back, it seems that I have learned many new concepts via scripting languages. I believe it is because the simpler language interface allows one to exercise the features more seemly by not having to think of elaborate setups.
Today I spent many hours troubleshooting the unable to cast Object type X to X . As I said in the previous blog entry, I am starting an asp.net mvc project because I want to TDD this project. So I finished translating the existing project from web forms to asp.net mvc, and now the only thing I have to confirm is that the unit test that I adapted for testing file uploads pass. (By the way, the wonderful page is found here: http://csainty.blogspot.com/2009/01/aspnet-mvc-unit-test-file-upload-wit...)
And it won't work.
I repeated the steps on how to create the mocks and how to test the entry, and it doesn't work. It give me this weird error
unable to cast Object type System.Web.Mvc.Content to System.Web.Mvc.Content
I rubbed my eyes a few times. It looks to me that it is the same. So I try it again. Same result. I recreated, step by step, the test. Same result. I researched a possible bug in NUnit. Nothing. Just in case, I repeated the test using Microsoft's test framework. Same error.
I research the specific bug connecting it to mvc. Nothing relevant. I try just the bug. This time I got a page that said that this error could be triggered by having some repeated URI references. This is potentially possible, so I decide to repeat the experiment in a new project. This time, it works using visual studio's framework. I try it again using Nunit, and it fails. I start to suspect that it is Nunit or that there is something in visual studio's framework that can make it pass. I try a third project, and this time visual studio's frameworks fails too.
So I research this error again. This time, I got this excellent link:
http://www.hanselman.com/blog/FusionLoaderContextsUnableToCastObjectOfTy...
Where Scott Hanselman explains how this error can happen from using two different DLLs. Let me quote(quote()) here:
Suzanne Cook puts it best, emphasis mine:
For example, path matters when determining whether a type is castable to another type. Even if the assemblies containing the types are identical, if they're loaded from different paths, they're considered different assemblies and therefore their types are different. This is one reason why using contexts other than the Load context is risky. You can get into situations where the same assembly is loaded multiple times in the same appdomain (once in the Load context, once in the LoadFrom context, and even several times in neither context), and their corresponding types won't be castable.
So I checked in my project, and yes, this was the problem. Those test passed right away.
I just started working on a new project. As you know, I got agile religion earlier this month, and I am a born-again coder, who wants to test his code as he goes. Also, after doing a few TDD projects, not doing it seems wrong, and it is just not as fun.
So I got a new .Net project, and this time I actually can do it right. I am going to do it right. I set up Moq and NUnit, and off I go to test land. Now All what I have to figure out is how to mock HttpRequest to test an upload method. I research the question. And in most cases, most of the solutions involved Asp.net mvc. I kept trying to find something specific to just plain asp.net, but the information that I got was either very old, or was a tangential mention that in an mvc page about how the solution could also work with regular asp.net pages.
So the pragmatic solution was to move the back end of the project to mvc. Fortunately for me the project only has a couple of pages of code, and translating the behavior from asp.net to mvc was quick. In fact, it seems that it takes a lot less work code to do the same work.
I am not saying that it is not possible to TDD regular asp.net. I am sure it is. But most of the information and resources exist for asp.net mvc, so, if it is possible, it makes a lot more sense to adopt it if one wants to TDD a asp.net project.