loads of useful information, examples and tutorials pertaining to web development utilizing asp.net, c#, vb, css, xhtml, javascript, sql, xml, ajax and everything else...

 



Advertise Here
C-Sharpener.com - Programming is Easy!  Learn Asp.Net & C# in just days, Guaranteed!

Adding Custom Exception Handling Attributes to Your Asp.Net MVC Actions

by naspinski 3/7/2011 12:00:00 PM

Attributes are a simple way to run common handling across many actions without repeating yourself

I ran into a position where I was handling exceptions and pushing them to xml ContentResults the same way on multiple actions across many controller repeating a lot of code. I was working on a REST interface that always was to return xml. All Exception were to be returned in xml as well. I found myself writing a lot of actions like this:
public ContentResult Fidget()
{
    try
    {
        //do a bunch of stuff
        //throw exceptions if I need to
    }
    catch(Exception ex) //now catch them and display xml
    {
        // turn the exception into xml
        return this.Content(myXmlException, "text/xml");
    }
    
    // if it made it here, return success xml
    return this.Content(successXml, "text/xml");
}

This worked great, but after a bunch of actions, the code was very redundant. I want to handle exception the same on a lot of actions, but not all, so I decided to go to an Attribute, specifically ActionFilterAttribute and the IExceptionFilter. If I override the OnException, I can automatically handle the Exceptions in the painted actions, so this is what I came up with:
[HttpGet]
public class XmlExceptionAttribute : 
    ActionFilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext 
        filterContext)
    {
        if (filterContext.Exception == null) return;
        filterContext.ExceptionHandled = true;
        var response = filterContext.Controller
            .ControllerContext.HttpContext.Response;
        response.ContentType = "text/xml";
        response.Write((new Status(
            filterContext.Exception)).ToXmlString());
    }
}

*Note that the Status object is a just an object I made to be serializeable and .ToXmlString() is an extension method I came up with a while back to convert objects into xml strings on the fly.

Now, if the attribute is applied, all I have to do for the above behavior in an action is simply this:
[HttpGet]
[XmlException]
public ContentResult Fidget()
{
    //do a bunch of stuff, throw exceptions if I need to
    
    // if it made it here, return success xml
    return this.Content(successXml, "text/xml");
}

The behavior is now the EXACT same!

Tags: , , , ,

c# | mvc | xml

Serializing and DeSerializing XML Objects in .Net

by naspinski 3/1/2011 12:50:00 AM

these two simple extension methods with have you switching between XML and objects in no time

First off, it is pretty well known that if you have any Object and want to convert it into an XML strong, you can use the XmlSerializer to do so. I encapsulated the process is a simple extension method that run from any object - this will work as long as the object has a constructor with no inputs (ie: new SomeObject()) as that is the constraint passed up from XmlSerializer. Here is the method for converting from an object to an xml string:
public static string ToXmlString(this Object o)
{
    StringWriter xml = new 
        StringWriter(new StringBuilder());
    XmlSerializer xS = new XmlSerializer(o.GetType());
    xS.Serialize(xml, o);
    return xml.ToString();
}

With this, now all you need to do is:
MyObject obj = new MyObject();
// a bunch of stuff here...
// now I want the xml representation of this:
string xml = obj.ToXmlString();

Now to go backwards, you can use the similar Deserialize along with the XmlSerializer with this method:
public static T XmlToObject<T>(this string s)
{
    var xR = XmlReader.Create(new 
        StringReader(s));
    XmlSerializer xS = new XmlSerializer(typeof(T)); 
    T obj = (T)xS.Deserialize(xR);
    return obj;
}

It is important to notice that this is taking in a raw xml string, which would not be web safe. If you were taking in data from a web source, you would want to employ HttpUtility.UrlDecode(s) instead of just s above. Now if you want to turn your above string 'xml' into an object again, simply call it like this:
MyObject obj2 = xml.XmlToObject<SomeObject>();

ServerInfo - Easily scan a Machine/Server Farm for Information

by naspinski 7/31/2010 12:23:00 PM

new open-source project in Asp.Net MVC 2

More than once I have been asked what databases are on what server, if server X is running application Y or what websites server ABC is running. These are are relatively simple things to accomplish, and there are tools available to get this information, but this is an extremely simple and portable solution - all the data is kept in xml, so there is no need to install a backend.

All that it is required to get all this information is to enter ip addresses and the user has the rights to scan the machines requested.

In addition, this can keep track of all of the owners of the machines and has a GUI for running WMI Queries, which is extremely powerful if you know how to use it.

This is written with Asp.Net MVC 2, C# and xml; it requires .Net 4.0 framework. I will be updating this to MVC 3/Razor in the near future.

Tags: , , ,

c# | mvc | my projects | xml

Keeping all your settings in an XML file in a centralized location

by naspinski 2/22/2009 8:16:00 AM

Often times you want to centralize some key data, and avoid a DB call

Most of my applications use a settings.xml file where keep all of my settings. I then use a Settings.cs class to view/update those values. It is great for centralizing data while avoiding unnecessary trips to the DB; change once, it's changed everywhere.

One of the most common things I use in my settings class is for my email settings, just in case I want to change the account or smtp that I am using, here is a sample of what one would look like:
<?xml version="1.0" encoding="utf-8" ?>
<settings>
  <smtp>smtp.gmail.com</smtp>
  <ssl>True</ssl>
  <mail_account>demo@naspinski.net</mail_account>
  <mail_password>Iparty</mail_password>
</settings>

Pretty basic stuff there, now here is the Settings.cs class I use to access it using a little Linq-to-XML:
using System.Linq;
using System.Web;
using System.Xml.Linq;

public static class Settings
{
  public static string Get(string setting)
  { // gets the specified setting
    XElement x = XElement.Load(HttpContext.Current.Server.MapPath("~") + "\\App_Data\\settings.xml");
    return (from p in x.Descendants(setting) select p).First().Value;
  }

  public static void Update(string setting, string value)
  { // changes the specified setting
    string file_location = HttpContext.Current.Server.MapPath("~") + "\\App_Data\\settings.xml";
    XElement x = XElement.Load(file_location);
    XElement xe = (from p in x.Descendants(setting) select p).First();
    xe.Value = value;
    x.Save(file_location);
  }
}

As you can see, I keep my settings in the App_Data folder. Here you can see how I use it in some apps, for example, this is how I use it with my Email.cs class:
public Email(string to, string from, string subject, string body) : base(Settings.Get("smtp"), 587)
{
  this.Credentials = new System.Net.NetworkCredential(Settings.Get("mail_account"), Settings.Get("mail_password"));
  ...

I think you can figure out Settings.Update() as it is basically the same. You can use whatever method to encrypt your data whereever you keep it.


Tags: ,

c# | steal some code | xml

GUI css writer: change your page style and rewrite your css on the fly

by naspinski 9/28/2008 11:45:00 AM

I have seen a lot of theme pickers out there, but not one that gives you 100% control like this

While working on a recent project, I had a complaint about the colors... I hate colors and I am no good at picking them, and when I do find some colors that I think are nice, apparently everyone else thinks they are crap.  This is why I truly respect web designers, as that is a true skill.  But to my chagrin I do not have a web designer, so I did the next best thing: get the blame off my back.  That's right, if you think you are so good with colors, why don't you pick them Mr. User?

 

So I went ahead and used the Farbtastic jQuery color picker Plug-in that I recently fell in love with, along with some nice Linq, XML, some good old .Net IO and a dash of clever css writing, and I was able to put together a (almost) fool-proof theme-designer with a friendly GUI.

 

First thing first, I needed both jQuery and the Farbtastic jQuery color picker Plug-in I just mentioned to be downloaded and called in my <head>.  Once I ran the Farbtastic demo to make sure everything was working fine, I set out on my adventure.

 

Next, I had to seperate my css into two distinct sheets, one: main_style.css would be jsut that, the main style; this never changes and is static.  Then, I made another stylesheet: theme.css that will hold my changing data and be re-written.  By using some clever techniques like not relying on any css border properties, I will be able to minimize the amount of code i have to re-write and be able to produce what looks like borders without actually using borders.  So instead of

/*theme.css*/
div.border { border: solid 5px Black; }

<!--html-->
<div class="border">some stuff with a border</div>

 

I will instead use something like this:

/*main_style.css*/
.border { padding:5px; }

/*theme.css*/
.border_color { background-color:Black; }
.content_color { background:White; }

<!--html-->
<div class="border border_color">
  <div class="inner_color">some stuff with a border</div>
</div>

 

These both produce what looks to be the exact same, the difference being that the second one does not actually have a border, it just looks like it with the padding and background color.  Now I know that the second one is more code, but that is the price you pay to have less code in your css and have your website be maintainable.  Once you write teh css writer one time, you will never have to touch the code again.  You can easily incorporate borders into the re-written css if you would like, that is just not the path I am going.

 

Now that that is understood, I can put in the color picker and the related TextBox controls to correspond to what colors I will be changing.  To do that, simply put this isnot your page where you want the picker: <div id="picker"></div> and then add your TextBox controls where you need them; each TextBox is the class 'colorwell' that allows them to be accessed easier by jQuery.  Once that is done, add a Button to submit everything.  So far, mine looks like the picture at the top of the post.  You will have to bind everything with jQuery now:

 <script type="text/javascript" charset="utf-8">
     $(document).ready(function() {
         var f = $.farbtastic('#picker');
         var p = $('#picker').css('opacity', 0.25);
         var selected;
         $('.colorwell')
      .each(function() { f.linkTo(this); $(this).css('opacity', 0.75); })
      .focus(function() {
          if (selected) {
              $(selected).css('opacity', 0.75).removeClass('colorwell-selected');
          }
          f.linkTo(this);
          p.css('opacity', 1);
          $(selected = this).css('opacity', 1).addClass('colorwell-selected');
      });
     });
 </script>

 

Now comes the code-behind.  First thing I decided is that I am going to hold the data in an xml file; you could easily do this in a SQL database as well.  I named the file theme.xml and it looks like this:

<?xml version="1.0" encoding="utf-8"?>
<theme>
  <text>#444444</text>
  <borders>#4a4a4a</borders>
  <body>#ffffff</body>
  <links>#ff7700</links>
  <link_hover>#ffa500</link_hover>
  <button_text>#ffffff</button_text>
  <headers>#ffffff</headers>
  <background>#a53c3c</background>
</theme>

 

I populated it with my default color values of what will be changing.  Next, I made a class that will help me interact with the xml using Linq, I named this file xmlHelper.cs and placed it in my App_Code folder:

public static XElement getElement(XElement x, string element)
{ return (from e in x.Descendants(element) select e).First(); }

public static void writeElement(XElement x, string element, string value)
{
    XElement xe = getElement(x, element);
    xe.Value = value;
}

 

Now in my Page_Load I made a Dictionary<string, TextBox> and populated it with all of my TextBox controls and their corresponding xml Element name.  Now each time the page loads fresh, I simply load my values into the TextBox controls like this:

if (!IsPostBack)
{
    foreach (var v in colors)
        v.Value.Text = xmlHelper.getElement(x, v.Key).Value;
}

 

Now every time the page loads, it pulls the values out of the xml file and populates the TextBox controls.  Now that I have that, I need a way to write to the css file and the xml file.  A iadd that to my btnSubmit_Click event.  Once again, I can look through the Dictionary I had set up to this time use my xmlHelper class and write to the xml file.  That is done like this:

protected void btnSubmit_Click(object sender, EventArgs e)
{
    foreach (var v in colors) xmlHelper.writeElement(x, v.Key, v.Value.Text);
    x.Save(themePath);
    //writeCss(); //this will be used in a moment
}

 

Now the xml is written, we need to write the css.  For this I just use the old IO and StringBuilder to write my css and overwrite the old file:

protected void writeCss()
{
    string cssThemeFile = Server.MapPath("~") + "\\css\\theme.css";
    StringBuilder sb = new StringBuilder();
    sb.Append("html{background-color:" + txtBg.Text + ";}");
    sb.Append(".border_color{ background-color:" + txtBorders.Text + ";}");
    sb.Append(".content_color{ background-color:" + txtBody.Text + ";}");
    sb.Append(".header_text{color:" + txtHeader.Text + ";}");
    sb.Append("a{color:" + txtLink.Text + ";}");
    sb.Append("a:hover{color:" + txtLinkHover.Text + ";}");
    sb.Append(".button:hover{background-color:" + txtLinkHover.Text + ";}");
    sb.Append(".button{background:" + txtLink.Text + ";color:" + txtButtonText.Text + ";}");
    File.Delete(cssThemeFile);
    TextWriter tw = new StreamWriter(cssThemeFile);
    tw.WriteLine(sb.ToString());
    tw.Close();
}

 

That will write my theme.css file, and that is that.  Now on every click, the values will be written to the xml file (this is unneccessary, but it loads the previous settings up for your user).  After that, the css file is re-written and immediately used by your page.  This does require that you have write permissions to whatever directory/directories you house your theme.css and theme.xml files in.  This also is easy to implement with each user profile having their own saved style (easier with SQL).  I hope this comes in handy for someone, I love it and have used it on a few projects now.

 

...And now they see it's not soo easy picking colors that actually look good :)