Showing posts with label MVC. Show all posts
Showing posts with label MVC. Show all posts

Monday, 17 January 2011

Split String To Dictionary

I have created a Survey System, which allows an admin to set the questions.

One question type is a dropdownlist and the information needed (to keep it simple) was stored as a semi-colon separated list (I also extended this to allow colon separated values within that to allow key and value sets).

for example:
spring;summer;autumn;winter
or
0:spring;1:summer;2:autumn;3:winter

Both are valid and the second example will store the values defined as the answer.

I wanted to split a string into a Dictionary and set a return for use on an MVC SelectList,

I refactored out the SplitAndReturnIndex to handle case where the string does not contain a Key, only a value, as can be seen from the code:


public IDictionary QuestionValues()
{
return Question.SurveyItemValues.Split(';')
.Select(x => new { Key = SplitAndReturnIndex(x, 0), Value = SplitAndReturnIndex(x, 1) })
.ToDictionary(x => x.Key, x => x.Value);
}

private string SplitAndReturnIndex(string x, int indexValue)
{
return x.IndexOf(':') == -1 ? x : x.Split(':')[indexValue];
}

Friday, 17 December 2010

MVC 3 Razor Views and Site Areas

Been working quite a lot over the last few years with MVC and since the release of Razor with MVC3 I have been quite giddy.

The fluid transition you can now have between HTML and programmatic code, has made the all cshtml files a thing of beauty.

There are still some bits I am getting to grips with; the "Areas" functionality now provided for example.

In one case I am creating a mobile site, so creating a new area allows me to create a new _layout.cshtml file to reference a new css file and I found that you can reused any controllers from your parent MVC site, by adding the namespace to the namespaces array in the MapRoute object saving me a lot of work.


public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"ms_default",
"ms/{controller}/{action}/{id}",
new {controller="Home", action = "Index", id = UrlParameter.Optional },
// this defines the namespace for the controllers I have already created in the parent site.
new string[] {"TMS.WEB.Controllers"}
);
}

Then I needed to add all the views from the parent site I wanted. I had to drop in the views even though they are the same for now, as it kept going off to use the layout and views defined in the parent site.

It would have been useful to only have to define as few files as necessary, but I guess I can just copy and replace the files as I maintain the site.

Tuesday, 16 February 2010

MVC Mock helper class


public static class MvcMockHelpers
{
public static HttpContextBase FakeHttpContext()
{
var context = new Mock();
var request = new Mock();
var response = new Mock();
var session = new Mock();
var server = new Mock();

context.Setup(ctx => ctx.Request).Returns(request.Object);
context.Setup(ctx => ctx.Response).Returns(response.Object);
context.Setup(ctx => ctx.Session).Returns(session.Object);
context.Setup(ctx => ctx.Server).Returns(server.Object);
context.SetupGet(ctx => ctx.User.Identity.Name).Returns("TestUser");

return context.Object;
}

public static HttpContextBase FakeHttpContext(string address)
{
HttpContextBase context = FakeHttpContext();
context.Request.SetupRequestUrl(address);
return context;
}

public static void SetFakeControllerContext(this ControllerBase controller)
{
var httpContext = FakeHttpContext();
ControllerContext context = new ControllerContext(new RequestContext(httpContext, new RouteData()), controller);
controller.ControllerContext = context;
}

public static void SetHttpMethodResult(this HttpRequestBase request, string httpMethod)
{
Mock.Get(request)
.Setup(req => req.HttpMethod)
.Returns(httpMethod);
}

public static void SetupRequestUrl(this HttpRequestBase request, string address)
{
if (address == null)
{
throw new ArgumentNullException("address");
}

if (!address.StartsWith("~/", StringComparison.OrdinalIgnoreCase))
{
throw new ArgumentException("Sorry, we expect a virtual url starting with \"~/\".");
}

var mock = Mock.Get(request);

mock.Setup(req => req.QueryString)
.Returns(GetQueryStringParameters(address));
mock.Setup(req => req.AppRelativeCurrentExecutionFilePath)
.Returns(GetUrlFileName(address));
mock.Setup(req => req.PathInfo)
.Returns(string.Empty);
}

private static string GetUrlFileName(string url)
{
if (url.Contains("?"))
{
return url.Substring(0, url.IndexOf("?", StringComparison.OrdinalIgnoreCase));
}
else
{
return url;
}
}

private static NameValueCollection GetQueryStringParameters(string url)
{
if (url.Contains("?"))
{
NameValueCollection parameters = new NameValueCollection();

string[] parts = url.Split("?".ToCharArray());
string[] keys = parts[1].Split("&".ToCharArray());

foreach (string key in keys)
{
string[] part = key.Split("=".ToCharArray());
parameters.Add(part[0], part[1]);
}

return parameters;
}
else
{
return null;
}
}
}