0

I'm currently trying to create an XML based website which has access to a feed URL. The XML feed is queried by adding url parameters to the current URL, and so I am using a form with GET method to add parameters to the URL.

I currently have a property search form which will search for properties within the feed by adding xml parameters to the url like so:

/Sales/?minprice=300000&maxprice=500000

This works perfectly and the correct results are shown to the user. However, if I was to use a filter form which filtered these properties by highest price for example, the feed parameters would be removed when the filter form is submitted. The new URL after the filter would be for example:

/Sales/?priceSort=descending

As you can see, the minprice and maxprice fields have been removed completely, leaving me with unwanted properties.

Currently, to combat this I am using sessions to store the URLs for each page and then combining them to make 1 url. I understand that using sessions within MVC based applications isn't exactly recommended.

So, I'm really just wondering if there is a better way to store the url's rather than using sessions?

Any help would be much appreciated.

Thanks in advance.

SOME CODE SNIPPETS OF THE SITE:

Model and ViewModel

    public class ResultsViewModel 
{
    public PropertyResult[] Property { get; set; } 
}

public class PropertyResult
{
    public int Count { get; set; }
    public int Pid { get; set; }
    public int RentalPeriod { get; set; }
    public string Price { get; set; }

    public string Address { get; set; }
    public string NameNumber { get; set; }
    public string SA1 { get; set; }
    public string SA2 { get; set; }
    public string Town { get; set; }
    public string City { get; set; }
    public string County { get; set; }
    public string Postcode { get; set; }

    public string LocationCode { get; set; }

    public string PriceText { get; set; }
    public string Primary1 { get; set; }
    public string Secondary1 { get; set; }
    public string Secondary2 { get; set; }
    public string Description { get; set; }

    public string Period { get; set; }

    public int Bedrooms { get; set; }
    public int Receptions { get; set; }
    public int Bathrooms { get; set; }
    public int Garages { get; set; }
    public int Gardens { get; set; }

    public bool Featured { get; set; }
    public int Views { get; set; }
}

Controller

try
        {
            var xml = XElement.Load(resultsFeed);

            var query = (from props in xml.Descendants("property")
                         select new PropertyResult
                         {
                             // property id
                             Pid = Convert.ToInt32(props.Attribute("id").Value),

                             // Rooms Count
                             Bedrooms = Convert.ToInt32(props.Attribute("bedrooms").Value),
                             Receptions = Convert.ToInt32(props.Attribute("receptions").Value),
                             Bathrooms = Convert.ToInt32(props.Attribute("bathrooms").Value),
                             Gardens = Convert.ToInt32(props.Attribute("gardens").Value),
                             Garages = Convert.ToInt32(props.Attribute("garages").Value),

                             // 1 = sales prop, 4 = lettings prop
                             RentalPeriod = Convert.ToInt32(props.Attribute("rentalperiod").Value),

                             Period = props.Attribute("period").Value,

                             // address 
                             Address = props.Element("useAddress").Value,
                             NameNumber = props.Element("num").Value,
                             SA1 = props.Element("sa1").Value,
                             SA2 = props.Element("sa2").Value,
                             Town = props.Element("town").Value,
                             City = props.Element("city").Value,
                             County = props.Element("county").Value,
                             Postcode = props.Element("postcode").Value,

                             // location code
                             LocationCode = props.Element("locationcodes").Value,
                             Featured = Convert.ToBoolean(props.Attribute("featured").Value),

                             // description
                             Description = props.Element("summaryDescription").Value,

                             // price
                             Price = props.Attribute("price").Value,
                             PriceText = props.Element("pricetext").Value,



                             // images
                             Primary1 = "http://lb.dezrez.com/Imaging/PictureResizer.ASP?Position=1&AgentId=" + eaid + "&BranchId="+ bid + "&width=1000&Category=Primary&PropertyId=",
                             Secondary1 = "http://www.dezrez.com/estate-agent-software/ImageResizeHandler.do?&photoID=2&AgentID=1239&BranchID=1976&Width=1000&PropertyId=",
                             Secondary2 = "http://www.dezrez.com/estate-agent-software/ImageResizeHandler.do?&photoID=3&AgentID=1239&BranchID=1976&Width=1000&PropertyId=",
                         }).ToArray();

View

I'm currently accessing each node like so:

@Model.Property[i].Gardens

2 Answers 2

1

In MVC you need to pass all the needed parameters (or rely in some store as Session, Cache, Db).

So, when sorting, you are just sending the column and order... in this case, you need to post also the filter values.

The correct way to do this, is having a ViewModel with all the filters and sorting parameters... and when you return from filtering or sorting, you can render the current filters.

So, besides filling the filter inputs with the current filters, you should craft the links to take into account all the parameters. For instance: when ordering, you pass also current filters... or if you change the filters you should maintain sortorder passing it on post.

Some code:

Your ViewModel:

public class SalesFilter{
   public int? MinPrice {get; set;}
   public int? MaxPrice {get; set;}
   public int? IdTypeOfSale {get; set;}
   ...
   ...
   ...
   public IEnumerable<Sale> FilteredValues {get; set;}

   //SelectLists if you need that your filters being DropDownLists
   public SelectList TypesOfSales {get; set;}
}

Your Controller:

public ActionResult Sales(){
   var model = new SalesFilter();
   model.FilteredValues = db.YourSales.Where(/*your init conditions*/);
   //set other initial values in your ViewModel

   return View(model);
}

[HttpPost]
public ActionResult Sales(SalesFilter filters){
   model.FilteredValues = db.YourSales.Where(/*use the conditions of your filter */);

model.TypesOfSales = new SelectList(db.TypesOfSales, "idType", "Name", filter.IdTypeOfSale);

   return View(model);
}
Sign up to request clarification or add additional context in comments.

7 Comments

Indeed, MVC stores no parameters, everything needs to be submitted every time or stored internally. Big distinction from ASP.NET Webforms.
Thanks for both of your comments, much appreciated. So maybe the best option would to be have another ViewModel which has all filtering and search parameters as properties. I could then assign values to these properties through the querystring class? Am I right or am I getting confused. I'm quite amateurish at the moment so any help would be great. Thanks
Nope, your controller should have your ViewModel as parameter. The the framework will handle the conversion/mapping from query string values to ViewModel properties. Is you use MVC in the way it was designed, you start to have benefits :)
Thanks a lot for your code samples. I'm not actually using a database at all though and I think this may be an overkill. I may not have explained my question clearly enough so I'll take the blame for that. I will update this with a code sample asap. Thanks again.
So... what are your Sales coming from? If it is not a database, it will be some sort of list (files, Xml). Replace the "db.Dataset" for your list and it will be the same. If you don't need the dropdownlists from the server, you can hardcode it directly in your view.
|
0

Consider using a Domain Model (all your business data, etc.) and separate View Models and extension methods that will transform your domain model to a specific view model and vice versa. Decoupling your business model from your view model using the transform indirection gives you the opportunity to use simple, easy to use view models that fit your view.

2 Comments

Hi, thanks for your reply. I'm struggling to understand the need for a Domain Model when I'm not really interacting with a database as such. I'm simply accessing an XML feed. I'm currently only using a ViewModel along with a Controller to access XML feed nodes. Are you saying there's a better way to do this?
If your XML feed is the same as both of your view models, perhaps not, but if there are differences and if you want to be able to present data differently in one view from another, then using a domain model that contains the XML data deserialized to nice objects and two different view models would allow you to have greater control and the ability to extend and make changes in one view that do not affect the other.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.