C# MVC NerdDinner authorization helper method problem - c#

I'm currently going through the ASP.NET MVC NerdDinner tutorial and am having a problem with a particular helper method related to user authorization. The idea is that only users who "own" a particular dinner should be able to edit or delete it (based on the Dinner object's HostedBy property).
I have the following method in my Dinner object:
public partial class Dinner {
public bool IsHostedBy(string userName) {
return HostedBy.Equals(userName, StringComparison.InvariantCultureIgnoreCase);
}
// other stuff removed for brevity
}
and in my View I'm trying to show/hide links based on whether the logged in user is the dinner's host:
<% if (Model.IsHostedBy(Context.User.Identity.Name)) { %>
<%= Html.ActionLink("Edit Dinner", "Edit", new { id = Model.DinnerID })%>
|
<%= Html.ActionLink("Delete Dinner", "Delete", new { id = Model.DinnerID })%>
<% } %>
The problem is that IsHostedBy() never returns true. I've written User.Identity.Name and Dinner.HostedBy to the screen to verify they're the same, but the method still returns false. I'm uncertain how to track down the problem.
I'm new to both C# and ASP.NET MVC, so it's very likely I'm missing something easy. Any help is appreciated and I'd be happy to post more information if it's needed.

While I'm at it I may as well write the Answer.
Check for errent spaces in the two strings.

I'm guessing that HostedBy and userName aren't actually the same string!
Some debugging ideas:
1st) Try forcing it to always return true:
public bool IsHostedBy(string userName) {
return true;
}
If this lets you return true back into the view, at least you can know that the code you're writing in the IsHostedBy method is being executed.
2nd) Add a console-out to see for yourself if the two strings are indeed equal:
public bool IsHostedBy(string userName) {
Console.WriteLine("userName: {0} / HostedBy: {1}", userName, HostedBy);
return true;
}
This will help you inspect the values of these items. Or you could just set a breakpoint at the return statement and see what they are as well.

Related

Set page count on dynamic pages & maintain page visit count in database

I just want to know the logic of this. I am not posting any code because I don't know what is the logic behind this so please pardon. I have a page call dynamicPage. This page is connected with database & everytime details of particular things gets fetched according to users selected. Now I want to track How many time particular thing is visited.
e.g.
Hospital1
Hospital2
Hospital3
If user clicks on Hospital2 then it's count get increased by one & so on..
I made this site http://www.brandstik.in/Music here many products are listed. Now I want to see how many times particular products is viewed.
You need something between clicking on the product link and loading the detail page. There are lots of ways to do that. One of the easiest ones is to have a method between you clicked on the link and loading the detail page. So the simplest solution that I can suggest is to have an action (if it is MVC) or a simple method on detail page, increase the count and then redirect to the original one. So lets say your code is in MVC and you have a method like this on dynamic page:
#Html.ActionLink("#item.productName", "Index", "Products", new {id = "#item.id"}))
and you have this code in your products controller:
public class ProductsController:Controller
{
Public ActionResult Index(int Id)
{
...some code to load and return the productDetails
}
}
Then you need to add a method to add to the count and then redirects to the original method. so your controller will be like this:
public class ProductsController:Controller
{
Public ActionResult Index(int Id)
{
//some code to load and return the productDetails
}
public ActionResult IncreaseProductCount(int Id)
{
//increase the count
return RedirectToAction("Index",new{Id=Id});
}
}
And then on the dynamic page view change your code to call the new method instead:
#Html.ActionLink("#item.productName", "IncreaseProductCount", "Products", new {id = "#item.id"}))

Get Search Queries from UrlReferer

I'm developing a website in ASP.Net 4. One of the requirements is to log search queries that people use to find our website. So, assuming that a URL parameter named "q" is present in Referrer, I've written the following code in my MasterPage's Page_Load:
if (!CookieHelper.HasCookie("mywebsite")) CookieHelper.CreateSearchCookie();
And my CookieHelper class is like this:
public class CookieHelper
{
public static void CreateSearchCookie()
{
if (HttpContext.Current.Request.UrlReferrer != null)
{
if (HttpContext.Current.Request.UrlReferrer.Query != null)
{
string q = HttpUtility.ParseQueryString(HttpContext.Current.Request.UrlReferrer.Query).Get("q");
if (!string.IsNullOrEmpty(q))
{
HttpCookie adcookie = new HttpCookie("mywebsite");
adcookie.Value = q;
adcookie.Expires = DateTime.Now.AddYears(1);
HttpContext.Current.Response.Cookies.Add(adcookie);
}
}
}
}
public static bool HasCookie(string cookiename)
{
return (HttpContext.Current.Request.Cookies[cookiename] != null);
}
}
It seems ok at the first glance. I created a page to mimic a link from Google and worked like a charm. But it doesn't work on the host server. The reason is that when you search blah blah you see something like www.google.com/?q=blah+blah in your browser address bar. You expect clicking on your link in the results, will redirect to your site and you can grab the "q" parameter. But ,unfortunately, it is not true! Google, first redirects you to an address like:
http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CCgQFjAA&url=http%3A%2F%2Fwww.mywebsite.com%2F&ei=cks5Uof4G-aX0QXKhIGoCA&usg=AFQjCNEdmmYFpeRRRBiT_MGH5a1x9wUUlg&bvm=bv.52288139,d.d2k&cad=rja
and this will redirect to your website. As you can see the "q" parameter is empty this time! And my code gets an empty string and actually doesn't create the cookie (or whatever).
I need to know if there is a way to solve this problem and get the real "q" value. The real search term user typed to find my website. Does anybody know how to solve this?
Google stopped passing the search keyword:
http://www.searchenginepeople.com/blog/what-googles-keyword-data-grab-means-and-five-ways-around-it.html

what is a good way of creating a back button to different 'coming from' pages

I have two different pages, from which a user can click on a 'details' link and go to the details page.
On the details page, I have a 'back' button, which leads the user to the originating page, being one of the two original pages of course.
There is also one extra issue: in one of the return links, I must specify an extra anonymous object.
my view code right now is:
#{
MvcHtmlString backLink = null;
if (Model.ReturnPage == MatchResultReturnPage.Search)
{
backLink = Html.ActionLink("GoBack", "Search", new {search = true});
}
else
{
backLink = Html.ActionLink("GoBack", "Dashboard");
}
}
In the controller I now look in the url.referrer if it contains 'dashboard', then I set the Model.ReturnPage to 'Dashboard'.
Is there a cleaner way of doing this?
Put the ReturnLink as a property on your model and set it inside the controller, which will alleviate the need for you to put that logic in the view.
There are certainly cleaner ways, but as your code is currently, it is very easy to understand what you are trying to do.
I would say keep it as is and simply put a #region wrapper around it and hide it when you don't need to work with it:
#region get referrer page
MvcHtmlString backLink = null;
if (Model.ReturnPage == MatchResultReturnPage.Search)
{
backLink = Html.ActionLink("GoBack", "Search", new {search = true});
}
else
{
backLink = Html.ActionLink("GoBack", "Dashboard");
}
#region
The only thing I would suggest is to have this check in the Controller, rather than the view and simply putting the result of your check either in model property, or in the ViewBag.
To gain access to Helpers in your controller, do the following:
var URL = new UrlHelper(this.Request.RequestContext).Action("MyAction", "MyController", new { id = 123 });
you should probably implement the Back button entirely in JavaScript.
using the history object
<a href=”javascript:history.back()”> [Back]</a>

MVC reCapcha Only Returns False

I am using:
http://mvcrecaptcha.codeplex.com/
My problem is very simple!
bool captchaValid
always returns false, no matter what I do.
Here is my code:
[CaptchaValidator]
[HttpPost]
public ActionResult ViewWidget(int id, TagwallViewModel model, bool captchaValid)
{
model.TagwallCollection = new TagWallCollection() { Id = id };
if (!captchaValid)
{
ModelState.AddModelError("_FORM", "You did not type the verification word correctly. Please try again.");
}
else
It shows no errors..
Things i have done differently, but i think have no influence:
The cs files downloaded from codeplex is not in the same folders.
I registered on https://www.google.com/recaptcha/admin/create to get my two keys with a online domain, but i'm testing it on localhost.
That was my problem, sorry for troubleing you! Having a bad code day.
I am using Razor.

In MVC Edit Action {HTTP POST} Using UpdateModel vs Request.Form Collection

I am working through sample MVC Nerdinner tutorial and using it on the AdventureWorks database. I have created an Edit action in the CategoryController to edit Product Category in AdventureWorks. The only updateable field in this table is the Name (the other fields - ID, RowGUID and UpdateDate are autogenerated). So my edit form View has only 1 field for the Name (of Product Category). My "Save" action for the edit is below: -
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection collection){
ProductCategory p = awRepository.GetProductCategory(id);
try
{
//UpdateModel(p);
p.Name = Request.Form["Name"];
awRepository.Save();
return RedirectToAction("Details", new { id = p.ProductCategoryID });
}
catch
{
foreach (var err in p.GetRuleViolations())
{
ModelState.AddModelError(err.PropertyName, err.ErrorMessage);
}
return View(p);
}
}
If I use the code as above, everything works as long as the Name I enter is valid (thus there is no exception). If I introduce an error (which is raised by GetRuleViolations if the Name is blank or for testing purposes is a particular "Test" string) I get a NullReferenceException (Object reference not set to an instance of an object) on this line in the View (Category/Edit.aspx) when the Edit View is redrawn (to show the user the error and allow him to correct)
<%= Html.TextBox("Name") %>
If I update my ProductCategory using UpdateModel(p) instead of using the Request.Form variable, everything works fine; Valid data is saved and invalid data redraws the view showing the error message.
My question is: what is the difference between UpdateModel and manual updating my variable by reading the values from Request.Form collection? The Nerdinner tutorial seems to suggest that both are equivalent. So I am surprised that one works smoothly and the other raises an exception.
Sounds like this:
http://forums.asp.net/p/1396019/3006051.aspx
So, for every error you add with
ModelState.AddModelError() and call
the View again, MVC Framework will try
to find an AttemptedValue for every
error it finds. Because you didn't add
them, MVC will throw an exception.
Normally you don't need to add these
values: AttemptedValues are
automaticaly populated when you use
DefaultBinding (by calling
UpdateModel() or by passing the object
to bind as an Action Method paramter:
public ActionResult
Create(FormCollection Form,
YourObjectType yourObject).
Looks like the following is done automatically by UpdateModel, but not done manually by yourself?
if (Form["Name"].Trim().Length == 0)
{
ModelState.AddModelError("Name", "Name is required");
//You missed off SetModelValue?
ModelState.SetModelValue("Name", Form.ToValueProvider()["Name"]);
}

Categories

Resources