Giorgos Nikolaidhs
Giorgos Nikolaidhs

Reputation: 71

Passing Model to all views mvc

I m trying to write a web page with mvc for practice reasons mainly.
When the page loads reads an xml file and creates a Model of Stores which contains some settings.

<Store>
    <StoreId>459</StoreId>
       <StoreSettings>
          <path1>c:\\mobile\\</path1>
          <path2>c:\\mobile2\\</path2>
     </StoreSettings>
  </Store>
  <Store>
    <StoreId>150</StoreId>
       <StoreSettings>
          <path1>c:\\mobile\\</path1>
          <path2>c:\\mobile2\\</path2>
     </StoreSettings>
  </Store>
</ArrayOfStore>

The user choose from a dropdown list the Store he wants(so he chooses the settings for the actions will take place) the form posts back,i take the selected value fom the list and creating the specific Model.

I m looking a good way to transfer the specific Model to all other Views.
I mean after select something if click to an other link or button redirecting to an other view,
ll have to choose again from the list.
I want after he choose something from the dropdownlist keep it(to other views too) until he ll choose something else.(the dropdownlist exist at all views)
Something like global variable which takes the value from what is selected in the dropdown.

What i was thinking to do is to serialise/deserialise the model and send the model from hidden form but i ll ve to do that for every button and link?

Edit
Myform

@model Control2.ViewModels.VMStoreList 
 @using (Html.BeginForm())
            {
            <dt>Select Store</dt>

            <dd>@Html.DropDownListFor(p => Model.SelectedValue, Model.ItemsInDropDown, "select store", new { onchange = "this.form.submit()" }) </dd>

My model

public class VMStoreList
    {

        public Store Store { get; set; }
        public string SelectedValue { get; set; }
        public IEnumerable<SelectListItem> ItemsInDropDown { get; set; }

        //constructor that initialise the dropdown items
        public VMStoreList()
        {
             XDocument doc = new XDocument();
            doc = XDocument.Load("C:\\Users\\gnikolaidis\\Desktop\\Projects\\Control2\\Control\\Settings\\Stores.xml");

            List<Control2.Models.Store> Stores = Control2.Models.HelpFuncs.DeserializeParams<Control2.Models.Store>(doc);
            List<SelectListItem> ItemsInDropDown = new List<SelectListItem>();
            foreach (var Store in Stores)
            {
                SelectListItem i = new SelectListItem();
                i.Text = Store.StoreId;
                i.Value = Store.StoreId;
                ItemsInDropDown.Add(i);
                this.ItemsInDropDown = ItemsInDropDown;
             }
        }

        //This method has the selected value and initialise Store property
        public void Post()
        {
             XDocument doc = new XDocument();
            doc = XDocument.Load("C:\\Users\\gnikolaidis\\Desktop\\Projects\\Control2\\Control\\Settings\\Stores.xml");

            List<Store> Stores = Control2.Models.HelpFuncs.DeserializeParams<Store>(doc);
            var g = from s in Stores
                    where (s.StoreId == SelectedValue)
                                       select s;
            this.Store = g.FirstOrDefault();
            this.SelectedValue = SelectedValue;
            int a=6+7;



        }
    }

and my action in controller

 public ActionResult Index()
        {


            return View();
        }

        [HttpPost]
        public ActionResult Index(VMStoreList Vmobject)
        {
            if (ModelState.IsValid)
            {
                Vmobject.Post();
            }
            return View(Vmobject);
        }

Upvotes: 1

Views: 1020

Answers (2)

su8898
su8898

Reputation: 1713

There are 2 options. For both options you will have to save the user's selection either in the client side (local storage/cookie) or in the server side for it to be rendered back for subsequent requests.

  • You can create a _Layout page for all views that needs to have the selected data displayed by the user and inherit this _Layout. You can also consider adding this to the default _Layout page given that you need this information in all views.

  • You can create a PartialView and use RenderPartial to show the selected store in the Views that needs to show it.

    In this method, you will have to use RenderPartial in all views that you like to show the selected stores information. This means that all ViewModels passed to the normal views must have the items for the DropDownList and the Selected Store. This method is useful only when you want to show this information in a handful of views. Because otherwise, you will have to include the extra model info for the stores in all ViewModels.

For example, if you have a CartViewModel it will look like below

Public Class CartViewModel
{
    Public List<CartItems> Items {get;set;}

    Public SelectedStore SelStore{get;set;}
}
Public Class SelectedStore
{
    Public string SelectedStore {get;set;} 
    Public List<StoreInfo> Stores {get;set;}
}

And in your CartControllers Index view you would call

RenderPartial("_UserSelStore", Model.SelStore);

Hope you got the idea.

Upvotes: 1

Gregoire
Gregoire

Reputation: 24872

You can store the selected store in a url and use route params to handle it.

Eg: Your view without selected store:

http://yourapp/default/controller/action

Your view with selected store

http://yourapp/selectedstore/controller/action

What you have to do is a custom route (in routeconfig):

 routes.MapRoute(
               name: "MyStore",
               url: "{store}/{controller}/{action}/{id}",
               defaults: new { controller = "Home", action = "Index", store = "default", id = UrlParameter.Optional }
           );

So after you can ask for the selected store in your action Eg:

public async Task<ActionResult> MyStore(string store){
...
}

When the user changes the store in the dropdownlist all you have to do is refresh the page with the good store name in the url

Upvotes: 0

Related Questions