working with Actionfilter - asp.net-mvc

I have never worked with actionfilter so i dont really know how to use it, ive done som reseach but i dont completly understand it. But basicly im going to create a new controller, and i want my _Viewstart.cshtml to use this controller. The problem is that i dont know how to use this code to an actionfilter and then call this controller in _viewstart.
The code that i want in my controller is.
var TemplateIDSession = Session["TemplateID"];
if (TemplateIDSession != null)
{
int tempID = (int)TemplateIDSession;
var template = servicetemp.GetEntry(tempID);
var servicetemp = ServiceFactory.Instance.CreateTemplateService();
Response.ContentType = "text/css";
return RazorEngine.Razor.Parse(System.IO.File.ReadAllText(Server.MapPath("Content/Site.css")));

I think you should go about this in a different way, by using a HTML Helper for the CSS, like so:
public static class Helpers
{
public static string OrganizationStyleTemplate(this HtmlHelper html)
{
TagBuilder tagBuilder = new TagBuilder("style");
var templateIDSession = HttpContext.Current.Session["TemplateID"];
if (TemplateIDSession != null)
{
// retrieve your css from the database and insert it into the tag
tagBuilder.InnerHtml = dbObject.CSSYouveStored;
}
return tagBuilder.ToString(TagRenderMode.Normal);
}
}
Then usage would be like so:
#Html.OrganizationStyleTemplate()
P.S. If you need to analyze if the user is authenticated within that method, use:
HttpContext.Current.Request.IsAuthenticated

Related

Redirect page in c# mvc

I have link
http://localhost:3163/PaymentOrder?AgentCode=&InvoiceNo=&AgentName=&FromDate=&fromDate=12%2F11%2F2013&FromDate=12%2F11%2F2013+9%3A08%3A01+SA&toDate=12%2F11%2F2013
after click button "Delete" the page should be redirect to "Index"
return RedirectToAction("Index","PaymentOrder");
But i want keep link same as first, i don't know what method, please help me. thanks
I can fix it, i save session in
public ActionResult Index{
Session["LastPage"] = Request.Url.ToString();
}
after I'm
return Redirect(Session["LastPage"] as String);
You can pass the query strings to the third parameter of RedirecToAction
return RedirectToAction("Index","PaymentOrder", new { fromDate = model.FromDate });
Or pass the entire model as well, that contains the properties similar to your query strings
return RedirectToAction("Index","PaymentOrder", new { paymentModel = model });
As your query string is quite long, it would probably be better to write an extension method and use that instead, to keep your controllers thin. I haven't tested this, but something like this should work:
public static RouteValueDictionary ToRouteDictionary(this NameValueCollection nameValues)
{
if (nameValues == null || nameValues.HasKeys() == false)
return new RouteValueDictionary();
var routeValues = new RouteValueDictionary();
foreach (var key in nameValues.AllKeys)
routeValues.Add(key, nameValues[key]);
return routeValues;
}
Then in your controller:
return RedirectToAction("Index","PaymentOrder", Request.QueryString.ToRouteDictionary());
Just don't redirect but return the view, the URL will remain the same.

how to send custom Actionfilter to view

I have never worked with actionfilter before so i dont really understand how to do it. I have created the controller which i think will work, but now i want to my _ViewStart.cshtml to call this controller and dont know how to do it, i dont really know if my controller is right:
public class CoActionFilter : FilterAttribute, IActionFilter
{
public string CompanyFilter(ResultExecutedContext filterContext, Models.DynCss Cssdata, int id)
{
var service = ServiceFactory.Instance.CreateTemplateService();
var data = service.GetEntry(id);
var OverdriveCss = new Models.DynCss
{
GetAllTempData = data,
BGColor = Cssdata.GetAllTempData.TempBG,
HeadColor = Cssdata.GetAllTempData.TempHeader,
LayColor = Cssdata.GetAllTempData.TempLayout,
TextColor = Cssdata.GetAllTempData.TempText,
FootColor = Cssdata.GetAllTempData.TempFooter
};
string templateContent = File.ReadAllText("Content/Site.css");
return Razor.Parse(templateContent, OverdriveCss);
}
}
ps: The _Viewstart.cshtml doesnt have a controller or a model and this is why i need to use actionfilter. And i want this controller to be called inside: if (Request.IsAuthenticated)

Using ASP.NET MVC Html Helpers in a standard web forms project

So for example in the code behind of a web form aspx page I would like to be able to do things like
string textBoxHtml = Html.TextBox("MyTextBox");
Is this possible?
Is the source code available to fork for webforms?
Possible? Yes.
The entire MVC source is available at:
http://www.microsoft.com/downloads/details.aspx?FamilyID=53289097-73ce-43bf-b6a6-35e00103cb4b&displaylang=en
Good luck!
You'll quickly find that pulling bits of code out of MVC is like only wanting a banana and getting the gorilla holding it. ;)
Here's something that is working for me so far.
public static class PageCommon
{
public static System.Web.Mvc.UrlHelper GetUrlHelper(this System.Web.UI.Control c)
{
var helper = new System.Web.Mvc.UrlHelper(c.Page.Request.RequestContext);
return helper;
}
class ViewDataBag : IViewDataContainer
{
ViewDataDictionary vdd = new ViewDataDictionary();
public ViewDataDictionary ViewData
{
get
{
return vdd;
}
set
{
vdd = value;
}
}
}
public static System.Web.Mvc.HtmlHelper GetHtmlHelper(this System.Web.UI.Control c)
{
IViewDataContainer x;
var v = new System.Web.Mvc.ViewContext();
var helper = new System.Web.Mvc.HtmlHelper(v, new ViewDataBag());
return helper;
}

Using Request.Files.Count with TestControllerBuilder from MvcContrib?

I have a controller action in ASP.NET MVC that handles uploaded files. However, it seems there is no way to call Request.Files.Count while using MvcContrib's TestControllerBuilder.
I know I can work around this by abstracting Request.Files. My questions are:
Is it indeed the case that there is no direct way to call Request.Files.Count when using the TestControllerBuilder? Or am I doing something wrong?
Is there a way to stub the call to Request.Files.Count while using TestControllerBuilder using Rhino Mocks?
Do you think I should submit a request or patch for handling Request.Files.Count to MvcContrib?
Example code:
I want to make sure that there is at least one file in the Request.Files collection so I have the following conditional in my action:
public class MyController : Controller {
public ActionResult Upload() {
if (Request.Files == null || Request.Files.Count == 0)
ViewData.ModelState.AddModelError("File", "Please upload a file");
// do stuff
return View();
}
}
I am using the TestControllerBuilder from MvcContrib to create the test double for my controller tests. However, the call to Request.Files.Count always seems to throw a an exception. For example running the following NUnit test throws a NotImplementedException during the call to controller.Upload() at the call to Request.Files.Count:
[Test]
public void Upload_should_return_default_view_given_one_file() {
MyController controller = new MyController();
TestControllerBuilder controllerBuilder = new TestControllerBuilder();
controllerBuilder.InitializeController(controller);
controllerBuilder.Files["file"] =
MockRepository.GenerateStub<HttpPostedFileBase>();
var result = controller.Upload() as ViewResult;
Assert.That(result.ViewData.ModelState.IsValid, Is.True);
result.AssertViewRendered().ForView(string.Empty);
}
I've also attempted stubbing the call to Request.Files.Count to no avail (I'm using Rhino Mocks). None of the below work (even if I change controller and/or controllerBuilder to a stub):
controllerBuilder.Stub(cb => cb.HttpContext.Request.Files.Count).Return(1);
controller.Stub(c => c.Request.Files.Count).Return(1);
Thanks
I submitted a patch on Github to MvcContrib mantainers, but the changes are very simple to make, the problem is that HttpFileCollectionBase is not implementing Count() and this[int index] methods so they must be overriden by the WriteableHttpFileCollection in MvcContrib.
I paste the code here for completeness, that must be added to WriteableHttpFileCollection class:
public override HttpPostedFileBase this[int index]
{
get { return files[AllKeys[index]]; }
}
public override int Count
{
get { return files.Count; }
}
I've used this approach to solve the problem.
SetUp the test:
string fileName = "Test 1.pdf";
FileStream stream = File.OpenRead("log4net.config");
MockRepository mock = new MockRepository();
builder.Files[fileName] = mock.CreateMock<HttpPostedFileBase>();
using (mock.Record())
{
Expect.Call(builder.Files[fileName].FileName)
.Return(fileName);
Expect.Call(builder.Files[fileName].ContentType)
.Return(contentType);
Expect.Call(builder.Files[fileName].ContentLength)
.Return(Convert.ToInt32(stream.Length.ToString()));
Expect.Call(builder.Files[fileName].InputStream)
.Return(stream);
}
using the mock:
foreach(string key in Request.Files.AllKeys)
{
int lenght = Request.Files[key].ContentLength;
if (lenght > 0)
{
Document document = new Document();
string fileName = Request.Files[key].FileName;
byte[] content= new byte[Convert.ToInt32(lenght)];
Request.Files[key].InputStream.Read(content, 0, content.Length);
document.SetContent(content);
document.MimeType = Request.Files[key].ContentType;
// do whatever you want...
}
}

ASP.NET MVC - HTML Extension method building a URL or link

Consider an extension method whose purpose is to either:
render an <a> tag
on some condition, just return a string without a link
Question: in an extension method, how can you leverage the proper routing logic with Route Values, etc. rather than hardcoding the string. I suspect HtmlHelper.GenerateRouteLink is part of the solution, but please suggest the best way to achieve this.
public static string CreateUserLink(this HtmlHelper html, string userAcctName)
{
if (string.IsNullOrEmpty(userAcctName))
return "--Blank--";
//some lookup to A.D.
DomainUser user = ADLookup.GetUserByAcctName(userAcctName);
if (user == null)
return userAcctName;
//would like to do this correctly!
return string.Format("<a href='/MyAppName/User/View/{0}' title='{2}'>{1}</a>"
, user.Mnemonic, user.DisplayName, user.Location);
//normally returns http://mysite.net/MyAppName/User/View/FOO
}
More info:
using ASP.NET MVC 1.0
I just had to do something similar to this yesterday. There may be a slicker way to do it, but it helps me to see exactly what is going on, so I don't assume anything.
public static string CreateUserLink(this HtmlHelper html, string userAcctName)
{
if (string.IsNullOrEmpty(userAcctName))
return "--Blank--";
//some lookup to A.D.
DomainUser user = ADLookup.GetUserByAcctName(userAcctName);
if (user == null)
return userAcctName;
RouteValueDictionary routeValues = new RouteValueDictionary();
routeValues.Add("controller", "User");
routeValues.Add("action", "View");
routeValues.Add("id", user.Mnemonic);
UrlHelper urlHelper = new UrlHelper(html.ViewContext.RequestContext);
TagBuilder linkTag = new TagBuilder("a");
linkTag.MergeAttribute("href", urlHelper.RouteUrl(routeValues));
linkTag.MergeAttribute("title", user.Location);
linkTag.InnerHtml = user.DisplayName;
return linkTag.ToString(TagRenderMode.Normal);
}
would this work?
public static string CreateUserLink(this HtmlHelper html, string userAcctName)
{
if (string.IsNullOrEmpty(userAcctName))
return "--Blank--";
//some lookup to A.D.
DomainUser user = ADLookup.GetUserByAcctName(userAcctName);
if (user == null)
return userAcctName;
return html.ActionLink(user.DisplayName, "user", "View", new {title=user.Location});
//normally returns http://mysite.net/MyAppName/User/View/FOO
}
My experience with GenerateRouteLink has been an uphill battle. It's been a while since I messed with it but if it's the Method I'm thinking of Microsoft has made it "internal" so you can't access and use it outside the MVC assembly. There are a number of workarounds that I played with and didn't really like.
What I ended up doing to avoid hard coding the url in my helper methods is have it accept a 'string url' parameter and use Url.Action in my view when I call the helper method. It's not the cleanest but it's a workaround that worked well for me.
<%= Html.CreateUserLink("userAcctName", Url.Action("Home", "Controller") %>

Resources