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...

 






Cascading DropDowns with SQL

by naspinski 6/28/2008 2:16:00 AM

an improved cascade class that includes methods using both xml and sql

I posted an entry of how to make cascading ddls with xml in the past, now I extended the class to include sql.  In this case, one of the few times I may say so I decided not to use LINQ as in this case it actually seemed to make more work.  The idea is basically the samejust usingan SQL database.  This is what the info in my DB looks like:

 

dropDowns

idcategoryitem
1 ford mustang
2 ford f-150
3 ford focus
4 chevy impala
5 chevy corvette
6 chevy blazer

 

Now I just have to make my ddls, notice the second one is empty:

 

<asp:DropDownList ID="ddlMake" runat="server" AutoPostBack="true"   onselectedindexchanged="ddlMake_SelectedIndexChanged"
    cascadeTo="ddlModel"  cascadeBlank="- select make -" >
    <asp:ListItem>- select make -</asp:ListItem>
    <asp:ListItem>ford</asp:ListItem>
    <asp:ListItem>chevy</asp:ListItem>
</asp:DropDownList>
<asp:DropDownList ID="ddlModel" Enabled="false" runat="server">
    <asp:ListItem>- select make -</asp:ListItem>
</asp:DropDownList>

 

Also notice that the attributes cascadeTo and cascadeBlank are set.   cascadeTo is the ddl you are going to cascade to, and cascadeBlank is what the empty value of the  cascaded-to ddl will be if the original is returned to index 0 (that is much easier to demonstrate than explain).

 

Now just call it in the code-behind (don't forget to put the class in your App_Code folder):

 

protected void ddlMake_SelectedIndexChanged(object sender, EventArgs e)
{
    DropDownList dll = (DropDownList)sender;
    string connString = ConfigurationManager.ConnectionStrings[ "mytestDB" ].ConnectionString;
    cascade2.fromThisDropDownSql(this.Page, (DropDownList)sender, connString, "item", "category", "dropDowns" );
}

 

This takes more inputs than the xml one, but is quite simple if you compare it to the database above.  The first two variables will always be the same, and the next 4 are simply the connection string, the table column you wish to populate the cascaded ddl with, the table column that you are filtering with, and the table name.  Doesn't really matter how your tables are layed out or where everything is located, you just change your inputs accordingly.  Really that is all that it takes.

 

 

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

asp.net | c# | steal some code

Simple Gantt Chart with Asp.net

by naspinski 6/27/2008 3:33:00 AM

It's very easy to make a Gantt Chart in Asp.Net, just takes a little math

Recently I was asked how to make a Gantt chart in Asp.Net.  Now I am too cheap to actually go and buy some software to do this for me, so I decided to figure it out on my own; can't be that hard right?  I will just use some strategically crafted div's to look like legitimate graphs.  Turns out it really wasn't that tough... wasn't even a lot of code!

 

First thing I did was make some sample data.  Whenever I have used a Gantt Chart in the past, it has been used to plot projects over time.  So my basic elements were:

  • Title
  • Start Date 
  • End Date

 

Now you can have endless extra crap on there, but that is the basics.  Also, instead of dates, you could easily substitute numbers, but I am going to go with dates.  I just produced a DataTable with those as my 3 DataColumns and some dummy data:

 

titlestartend
Super Important Project 6/8/2008 7/3/2008
A Project 6/3/2008 6/30/2008
Crappy Project 6/25/2008 7/3/2008
Party Project 6/13/2008 6/23/2008
Being stupid 6/28/2008 7/8/2008
Getting Hammered 6/18/2008 7/1/2008
Recovering 7/2/2008 7/5/2008

 

Now that we have the data, it is just down to the math of how we are going to get this to work.  First of all, let me explain my approach to CSS graphing: using divs and the css 'width' property can easily make you a horizontal bar graph, just stack a couple divs on top of eachother that are different widths, different backgrounds and there you go, you have some nifty graphs.  The only challenge here is that we can't just use a simple percentage.  The left side of the graph isn't necessarily on the far left side, and with width is going to be relative to where it starts... hmmm.

 

I actually drew this out on some scratch paper on my desk to make it easier to see, using a nice even number: 10.


Now with this information, we can figure out how to render each div (graph line).  Since I am working with DateTime variables, I can easily convert this into TimeSpans and then Days which is an int... then it's easy math.  Notice I added in the *100 up above, that is so I am working with full percentages instead of decimals, like css uses.  Here is the code I cam up with for defining where to start a div and how wide for it to be.  Here is my function that takes in title String, start DateTime and end DataTime  and returns a nicely formatted div.  I am also using the global variables dtMin, and dtMax which are DateTime variables that are the maximum and minimum dates in the data (I use LINQ to find that easily, you can see in the code).  dateSpan is another global variable, an int that is simply (dtMax - dtMin).Days.

 

public string doGantt(object t, object s, object e)
{
    string title = (string)t;
    DateTime start = (DateTime)s;
    DateTime end = (DateTime)e;

    int numberOfDays = (end - start).Days;
    int startDivAt = (start - dtMin).Days > 0 ? (start - dtMin).Days * 100 / dateSpan : 0;
    int howWide = end != dtMax ? ((end - start).Days + 1) * 100 / dateSpan : (end - start).Days * 100 / dateSpan;
    count++;
    return "<div class=\"gantt\" style=\"background:" + colors[count%colors.Count()] + ";width:" + howWide + "%;margin-left:" + startDivAt + "%;\">&nbsp;&nbsp;"+title+"</div>";
}

 

Notice in there I call an array I had declared called colors[] which simply has the colors {"navy","maroon","orange"} in it - this simply rotates the colors of the graph.  The code is pretty straight forward I think; had to do a little magic to prevent it from falling off the edge of the page.  Then to implement it, you just need to add in a repeater in your aspx:

 

<fieldset>
    <legend>Gantt Chart</legend>
    <asp:Repeater ID="rpt" runat="server">
        <HeaderTemplate>
            <div style="font-weight:bold;font-size:1.2em"><%= dateHeader %><br /></div>
        </HeaderTemplate>
        <ItemTemplate>
            <%# doGantt(Eval("title"), Eval("start"), Eval("end")) %></td>
        </ItemTemplate>
    </asp:Repeater>
</fieldset>

 

And then you set your DataSource and DataBind and you have a Gantt Chart...

 

rpt.DataSource = dt;
rpt.DataBind();

 

It even resizes liquidly to the size of the container. It is very vanilla, but definitely a good start to a simple, no images Gantt chart that could be expanded/spruced up very easily!

 


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

asp.net | c# | steal some code | tutorials

Adding Multiple Persistent Controls is Asp.Net

by naspinski 6/16/2008 5:21:00 PM

It's easy to add one control in asp.net during runtime, but it's not so straight-forward to add a bunch dynamically

You would think to add more and more controls, you could simply do something like this on a button click event (I will be using LiteralControls for ease of explanation, but this works the same for all controls, even custom ones):

 

somePanel.Controls.Add(new LiteralControl("<div>I AM A NEW CONTROL</div>"));

 

Which does work perfectly, and does exactly what you think it would do.  But, if you click it again, guess what?  It just re-makes the same control, replacing the old one.  Doing this over and over.  This is because what is produced is not kept in any sort of persistent state.  You need to 'tell' your program what you want it to keep.  For this,  I like to use Session variables... and if you don't like that, then too bad!

 

With that said, we will need some sort of way to keep all the controls in an easily accessable structure.  My choice here is a Generic List as they are so easy to work with and offer so much that you can do do/with them.  To start with, I will be working with a basic List<LiteralControl> but I will get on later to a list with multiple controls contained within it as it is likely that you will want to add multiple controls at each click.

 

Now we just need to show how this is going to be persistant.  First, we need to declare a list in the class.  Then, each time a control is added, it must be pushed into the list as well as the page as to keep a 'copy' of it.  But that still will not survice a postback.  We also need to put the List into a Session variable.  And now that we have that list of controls in the session, we need to check every Page_Load to see if there is any controls we have stowed away, and if so, push them to the page.  Here is the most basic way to show this with functioning code:

 

aspx 

<asp:Button ID="btn" runat="server" Text="Add Control" onclick="btn_Click" />
<asp:Panel ID="pnl" runat="server" />

 

code-behind (c#)

List<LiteralControl> persistControls = new List<LiteralControl>();
protected void Page_Load(object sender, EventArgs e)
{
    // if you already have some controls populated
    if (Session["persistControls"] != null)
    {
        // pull them out of the session
        persistControls = (List<LiteralControl>)Session["persistControls"];
        foreach (LiteralControl lc in persistControls)
            pnl.Controls.Add(lc); // and push them back into the page
    }
}
protected void btn_Click(object sender, EventArgs e)
{
    // basic control for demo
    LiteralControl lc = new LiteralControl("<div style=\"border:solid 2px navy;padding:3px;margin:3px\">NEW CONTROL</div>");
    pnl.Controls.Add(lc);// add it to your page
    persistControls.Add(lc);// add it to the list
    Session["persistControls"] = persistControls; // put it in the session
}

 

Now that is just a basic example to get the point across that this is actually a pretty easy concept.  Now on to a bit more functionality.  There are two basic things I would think an average use of this would require:

 

  • Ability to delete each 'set' of controls
  • Ability to add a bunch of controls each time and persist all of them

 

Turns out both of these are also quite easy given the structure we are using. 

 

Looking at the first one: Ability to delete each 'set' of controls should be no problem as we are using a generic List. What does a List have that makes this so simple?  List.Remove(List Item)  In fact, using a List makes this ridiculously easy.  Simply add a btnDelete_Click method to our code-behind, Now every time a control is added, a Button must also be added with a corresponding CommandArgument that relates to it's position in the List and add a Button.Click += new EventHandler(btnDelete_Click) so the new delete method will be called.  Since the List itself will automatically adjust it's size and move it's items dynamically we can simply use an integer to count up from 0 each time we push a control to the page.  And when a new Control is added, all that is needed is to add the List.Count to the CommandArgument.

 

Now on to: Ability to add a bunch of controls each time and persist all of them which will be even easier.  Instead of passing just one Control like above, we can pass a collection of Controls inside another control.  For this I chose Panels for the easy to work with <div> that they produce.  So now, every time you add a Control, you simply add all your Controls to a Panel, then push that Panel to the List (which is now a List<Panel> by the way).  And really that is all you need to do.  

 

With those two additions, the example code now looks like this:

 

aspx 

<asp:Button ID="btn" runat="server" Text="Add Control" onclick="btn_Click" />
<asp:Button ID="btnClear" runat="server" Text="Reset" onclick="btnClear_Click" />
<br /><br />
<asp:PlaceHolder ID="ph" runat="server" />

 

code-behind (c#) 

List<Panel> persistControls = new List<Panel>();
Random rand = new Random(); // for display so we can get a simple difference in controls
protected void Page_Load(object sender, EventArgs e)
{
    // if you already have some controls populated
    if (Session["persistControls"] != null)
    {
        persistControls = (List<Panel>)Session["persistControls"]; // pull them out of the session
        int count = 0;
        foreach (Panel lc in persistControls)
        {
            lc.CssClass = "smallPanel";
            Button btn = new Button();
            btn.Click += new EventHandler(btnDelete_Click);
            btn.Text = "Delete";
            btn.CommandArgument = count.ToString();
            ph.Controls.Add(lc); // and push them back into the page
            ph.Controls.Add(btn);
            ph.Controls.Add(new LiteralControl("<br /><br />")); // for formatting
            count++;
        }
    }
}
protected void btn_Click(object sender, EventArgs e)
{
    LiteralControl lc1 = new LiteralControl("<span style=\"border:solid 2px navy;margin:3px\"> NEW CONTROL [ "+ rand.Next(1000,9999).ToString() + "] </span>");
    LiteralControl lc2 = new LiteralControl("<span style=\"border:solid 2px navy;margin:3px\"> NEW CONTROL [ " + rand.Next(1000, 9999).ToString() + "] </span>");
    Panel pnl = new Panel();

    pnl.Controls.Add(lc1);
    pnl.Controls.Add(lc2);
    Button btn = new Button();
    btn.Click += new EventHandler(btnDelete_Click);
    btn.Text = "Delete";
    btn.CommandArgument = persistControls.Count.ToString();
    ph.Controls.Add(pnl); // and push them back into the page
    persistControls.Add(pnl);// add it to the list
    ph.Controls.Add(btn);
    ph.Controls.Add(new LiteralControl("<br /><br />")); // for formatting
    Session["persistControls"] = persistControls; // put it in the session
}
protected void btnClear_Click(object sender, EventArgs e)
{
    Session["persistControls"] = null;
    Response.Redirect(Request.Url.ToString());
}
protected void btnDelete_Click(object sender, EventArgs e)
{
    int deleteThisOne = int.Parse(((Button)sender).CommandArgument);
    persistControls.Remove(persistControls[deleteThisOne]);
    Session["persistControls"] = persistControls; // put it in the session
    Response.Redirect(Request.Url.ToString());
}

 

And that is all you need to do.  This could be cleaned up a bit and redundant code could be consolidated, but you get the idea.  This will work with any group of controls be it TextBoxes, DropDownLists or even custom Controls that you make.  I throw mine inside an UpdatePanel to make it function smoother.  Remember though, since this is using Session, high traffic or large control collection can make this a bit of a memory hog, so be careful. 

 

Here is an example and the code:

 



code:


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

asp.net | c# | steal some code | tutorials

WSS 3.0/MOSS 2007 Web Part Tutorial

by naspinski 6/13/2008 4:54:00 AM

So you want to build your own web part eh?

First thing is first, I am going to cut through the crap so you know whether or not you should keep reading right now: for this tutorial to make any sort of sense, you are going to need to have WSS 3.0 and VS/VWD 2008 installed on your Server 2003+ machine; if you do not have one available, make a virtual server (Actually, this is the ideal setup anyway).  You will then need to install WSS 3.0 Extensions for Visual Studio 2008 on your machine (I know I previously posted how to install WSS 3.0 Extensions on your desktop, but that will not work for a full build).  Yes it's a pain, and a lot of requirements, but SharePoint can be a bastard child sometimes.  This really is the hardest part about building new web parts.

Once all of that is out of the way, simply start a new project in VS and choose SharePoint->Web Part.  Give it a name and a location and hit OK.

 

Your solution explorer should now be populated with a bunch of files and references like this:



Now really there are only a few files you need to concern yourself with.  The most important one being the <WebPartName>/<WebPartName>.cs file, in my case it is Test/Test.cs; I will refer to this file as the main file from now on.  I say it is the most important as that is the one that does everything from presentation to code-behind.  The others are the <WebPartName>.webpart file and possibly the AssemblyInfo.cs file, but we will focus on the first right now.


Open up the main file and you will see something like this:



Where you see “TODO: …” is where you are going to put your rendering code.  They even provide you with the always-friendly “Hello World” program if you just un-comment it.  The Guid is automatically populated when you make your project, so don’t mess with it.  The big thing here is that 100% of your styling and layout has to be taken care of back here.  There is no aspx page to your aspx.cs like a normal .net web page.  Once you have a handle on that, it can be treated just like any other asp.net website you have ever made.  There are some other great interactive tools and features you can include, but that is for another day.  Right now, just use the “Hello World” code, use my supplied code or fill it up with your own.

 

NOTE: Often times it is easier to get your programming logic done in a regular Visual Studio Project as there is no way to easily test in a SharePoint Web Part Project.

 

Now that you have your code finished, we can change a few other things.  Open the <WebPartName>.webpart file and you can see some properties you can change.  Customize the Title and Description if you like.



That will change the default settings for this web part.  That is all I would mess with for right now.  So in theory, you now have a 100% working web part.  Now is the easy part.  Just right click on your project and click ‘Deploy’.

 


Assuming everything worked, you know have published your web part to your portal.  If it didn’t work, go fix your bugs and come back :PGo to your Portal->Site Actions->Site Settings->Modify All Site Settings and click on Web Parts under Galleries and you should see your Web Part with a happy little ‘!NEW’ by it.



Now just go to a Web Part Page and put it in there somewhere then exit edit mode.  You should now see your web part in action:


 

Here is my example web part you can take a look at.  It shows a couple different methods of how you can make a web part interact with itself.  As I mentioned above, there is a lot you can do with web parts beyond this, and I will hopefully be able to post some more in the near future.


Source Code:



Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

sharepoint | steal some code | tutorials

MS releases WSS 3.0 Tools: Visual Studio 2008 Extensions

by naspinski 6/12/2008 10:34:00 PM

Making web parts for WSS 3.0 and MOSS 2007 just got a lot easier... that is, once you figure out how to install it

Long ago (in computer time) Microsoft offered Visual Studio Extensions for WSS 3.0 web parts and they were wonderful. Problem was for us fools who upgraded to the latest and greatest (Visual Studio 2008) were stuck with a new fancy IDE that did not support this tool that is oh-so-handy. So, in my stubbornness/laziness, I just decided to study up on web parts themselves and hold off on the SharePoint implementation of them until it became compatible, instead relying on the lazy mans way of Jan Tielens' ReturnOfSmartPart (great tool).

But now (actually 8 days ago... we had a big project ok?!) MS has released the new VS 2008 Compatible Extensions and SharePoint devs all over the world rejoice!

But wait!? It won't install on my Windows XP?

It says compatible with Windows XP? But what is this? It also says that a requirement is to have WSS 3.0 installed. Ok, I'll install WSS 3.0, but...

WSS 3.0 will not install on Windows XP. I am no genius here, but let's think about this. If I need WSS 3.0 to be installed in order to install the extensions and WSS 3.0 is not compatible with Windows XP, then by some mathematical property wouldn't it be safe to say that the extensions are not compatible with Windows XP?

Luckily some google searching brought me to Janne Mattila's blog and a way to trick my OS into thinking that WSS is installed. You just need to add/change a registry key:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\12.0] "Sharepoint"="Installed"

Now everything should work fine.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

sharepoint

XML to DataTable with LINQ

by naspinski 6/11/2008 8:47:00 PM

Easy way to get your XML into a DataTable

Now I might just be blind, or incredibly incapable at searching google or reading my LINQ books (very possible) but I hadn't found a simple way to get a 2-level XML document into a DataTable for use in a GridView or just simple DataTable manipulation utilizing LINQ (I assume this is because DTs are 2 dimensional, and XML files can be all sorts of mash-ups of information). Since LINQ is so powerful, I assumed it wouldn't be all that difficult, turns out I was right, it's pretty easy. Here is the code:

public DataTable XElementToDataTable(XElement x)
{
  DataTable dt = new DataTable();

  XElement setup = (from p in x.Descendants() select p).First();
  foreach (XElement xe in setup.Descendants()) // build your DataTable
    dt.Columns.Add(new DataColumn(xe.Name.ToString(), typeof(string))); // add columns to your dt

  var all = from p in x.Descendants(setup.Name.ToString()) select p;
  foreach (XElement xe in all)
  {
    DataRow dr = dt.NewRow();
    foreach (XElement xe2 in xe.Descendants())
      dr[xe2.Name.ToString()] = xe2.Value; //add in the values
    dt.Rows.Add(dr);
  }
  return dt;
}

This is completely dynamic, so it doesn't matter what or how many elements you have. It does rely on the first element to set the DataTable columns, so make sure that one is complete. Though the XML does have to be limited to 2-dimensional elements; in fact, I am not even sure what happens if you feed the function bad data? The XML should resemble this structure:

<?xml version="1.0" encoding="utf-8"?>
<root>
      <person>
            <age>26</age> 
            <name>stan</name> 
            <hobbies>partying</hobbies> 
      </person>
      <person>
            <age>26</age> 
            <name>matt</name> 
            <hobbies>taking dumps</hobbies> 
      </person>
</root>

In that structure, each person will be a row, and age, name and hobbies will the the columns in the datatable:
agenamehobbies
26stanpartying
26matttaking dumps
Call it like this:

// load your xml file (this one is named people and it is in my App_Data folder)
XElement x = XElement.Load(Server.MapPath(".") + "\\App_Data\\people.xml");//get your file
// declare a new DataTable and pass your XElement to it
DataTable dt = XElementToDataTable(x);

And that's it, you have your DataTable.


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

c# | linq | xml

The Site is 100% Functional Again!

by naspinski 6/11/2008 8:28:00 PM

Thanks to VIUX.com and their superb service, my site is back up and running again

I am now completely off M6 and their worthless service and once again back at Viux. I just can't say enough good things about their service over the past 4 years (I need to stop trying other hosts).

As for the site, I believe everything is uploaded again and all downloads should be working. I also added a new examples section so you can see the code in action. I will be adding more and more to this as I get the chance.

Apparently I actually have visitors since I got some contacts while my site was down, I hope I got the files to everyone that asked for them. If not, sorry... but they are all back up now.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Using DefaultIfEmpty() to check if an element exists with LINQ

by naspinski 6/11/2008 8:12:00 PM

This is a very handy way to test if an element exists using LINQ

Often you want to run something only if an element exists. There is always the try/catch method, but that doesn't seem very elegant to me, and this gave me an excuse to figure some more out about LINQ, which I am finding I like more and more.

This is actually very simple once you understand how DefaultIfEmpty() works. It may seem a bit obvious, but it returns a default value if something is not there. The easiest way to do this is to give it something explicitly so you know what it is returning for the default; I just use a dummy instance. For this example, I am using LINQ with XML and XElements

//make your dummy element
XElement dummy = new XElement("dummy");
//assign it an easy to recognize null value
dummy.Value = "Does Not Exist";
//now run a query with it
foreach (XElement p in xmlFromFile.Elements("anElement").Descendants("someElement").DefaultIfEmpty(dummy))
{
  if(process.Value.Equals("Does Not Exist")
    //it does not exist
}

It's just that easy. Works the exact same with SQL or any other data source as well.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

c# | linq

Facelift to AuctionConstructor.com

by naspinski 6/11/2008 6:57:00 AM

I did a whole facelift to one of my sites, let me know what you think

I got bored of how my site AuctionConstructor.com was looking, so I revamped it completely.  Now I am no designer by a long shot, but I think it looks pretty good, also a little easier to navigate if I do say so myself!  Please check it out and let me know if you have any input.  Thank you! 



Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

my projects

M6.net is the worst host of all time

by naspinski 6/9/2008 8:39:00 PM

I have never experienced such a lack of service and overall ability in a 'professional' company in all of my life

Dealing with M6.net has been an utter nightmare. And I want to share, half to stop other people from using them and save them the grief, half because they piss me off so much that I want to vent, and half because I hope that their company fails as they have no business charging people for what they provide (3 halves... I know).

Where to begin? So... my site was working fine for a little while, everything was all fine and dandy. Until one day I noticed that none of my downloads were working, just sending me to another blank page. I also noticed that I could no longer make posts, edit posts, comment, rate, etc. Basically my site became an internet vegetable.

So, I contacted M6 to tell them about my predicament. Apparently they installed some anti-virus software and that was breaking many sites. Apparently locking down the App_Data folder which most asp.net projects use. So let me get this straight: They decided to put untested software onto a production server which people pay for, and admit to breaking many sites. And here is the amazing explanation I get:
We are still not having any ETA from macafee but it will get resolved soon.
Wow... thanks. Keep in mind this is about a week after I put in the initial trouble ticket (which still isn't resolved, its been over 2 weeks).

But wait! There's more! I was finally able to browse via FTP to my directory (oh, did I forget to say that FTP wasn't working either?). I noticed that all of the .zip files I had stored were now mysteriously missing. I sent in another trouble ticket explaining what happened, and this is the astoundingly thorough and useful response I get in email:
I am sorry to let you know that that files are not available on the server.
That's it, that is the whole response. We lost your files... woops :P

So this is when I decided I am done with M6, this is just getting stupid. Since I had already paid for a year of service, and I still had over 6 months left in that year, I figured it was ok to ask for my un-supplied hosting fees back. Not because I was leaving the service, but because the service I paid for was not being provided to me.
My site has basically been crippled over the past 2 weeks due to your deployment of (apparently untested) software on the server which hosts my site and I have gotten nearly zero support from M6. I have a ticket open: #KNT-488469 which is no longer being responded to.

Basically I have lost traffic and money because your service has been unacceptable. I would like my money refunded from the end of this paid month (though I feel I shouldn't have to pay for this month either) until the end of my contract with some time so I can migrate to a different host. I feel this is reasonable as you are not providing the service I payed for. Is this possible? I am trying to be reasonable, but this situation is very agitating.

Thank you
They then told me they can't because of their refund policy, then I I asked for an explanation in my case why they couldn't:
If we gave refunds in this way then there would be no reason for our clients to sign up for monthly billing as they could just cancel and receive their remaining credit anyway. As our monthly packages are at a higher per month price point than our yearly and two yearly packages this would render our pricing system useless. We apologize for the personal inconvenience this may cause.
and I replied:
But you also agreed to provide me with a service that you are not providing. That is a breach of contract is it not? I am not just a user that is trying to get my money back, I have a legitimate problem and you are not remedying it. I have been cordial and this is just poor business.
After they denied me again, I immediately filed this with the Better Business Bureau. I can at least hope to make it more of a hassle to sh#t on me that some annoying emails.

Overall, this host was horrendous. I have never experience such lack of courtesy, ability and professionalism in a 'company' (it's probably just some kid in his mom's basement). I hope this review stops at least one person from signing up for their 'service'.

M6 can rot in internet hell :)

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

other