1

I am struggling a bit to define whether this is just a design issue and/or how I could address the following scenario from a coding angle:

In my project, I allow a user to add multiple shipping addresses. Obviously, one of these is supposed to be the shipping address. However, I want to offer the possibility to change this at the user's discretion. I have therefore stored shipping addresses with a column called 'IsDefaultShippingAddress' (bool). What I have in mind doing is, when a user selects a shipping address to be the default, the model would pass on 'true' for that column.

Now, in a scenario where a user has an existing shipping address which is selected as default, and would like to add a new default shipping address (or promote an existing shipping address to default), I would naturally end up in a scenario where the same user has two (multiple) records in the same table where 'IsDefaultShippingAddress' is 'true' - but I want it to be only a single address (the latest promoted one) as per nature of the term 'default'.

Therefore my question is, how can I make sure that all records fitting a certain criteria (UserID) are updated to 'IsDefaultShippingAddress' 'false' while the newly promoted shipping address (separate row in same table) is being set to 'IsDefaultShippingAddress' 'true'?

Here's my controller code, which is the one where the problem is unsolved:

// POST: /Manage/EditShippingAddress
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult EditShippingAddress([Bind(Include = "ID,UserID,IsDefaultShippingAddress,ShippingAddressCompanyName,ShippingAddressFirstName,ShippingAddressLastName,ShippingAddressAdditional,ShippingAddressStreet,ShippingAddressNumber,ShippingAddressZIP,ShippingAddressCity,ShippingAddressState,ShippingAddressCountry,ShippingInstructions,UpdatedLatitude,UpdatedLongitude,UpdatedLocation")] ShippingAddresses model)
    {
        // define variables
        var userID = User.Identity.GetUserId();
        DateTime nowUTC = DateTime.Now.ToUniversalTime();
        DateTime nowLocal = DateTime.Now.ToLocalTime();
        // pass first name to viewbag for personalization
        ViewBag.Personalization = UserManager.FindById(userID).FirstName.ToString();
        if (ModelState.IsValid)
        {
            DATADB.Entry(model).State = System.Data.Entity.EntityState.Modified;
            DATADB.SaveChanges();
            return RedirectToAction("ShippingAddresses");
        }
        return View(model);
    }

2 Answers 2

1

Put this code just before your if statement.

I haven't executed the code. There might be some syntax errors but you get the idea.

if (model.IsDefaultShippingAddress)
{
   var addresses = DATADB.ShippingAddresses.Where(address => address.UserId == userId);

   addresses.ForEach(address => address.IsDefaultShippingAddress = false);
}
DATADB.SaveChanges();
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you @Selçuk - this almost works.. except for the scenario where a user actually changes the 'IsDefaultShippingAddress' value. That would end up with the following exception:
Attaching entity of type 'freshNclean.Models.ShippingAddresses' failed because another entity of same type already has same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.
0

Thank you Selçuk - with your help I got on the right path. I few twists and now I have my solution:

public ActionResult EditShippingAddress([Bind(Include = "ID,UserID,IsDefaultShippingAddress,ShippingAddressCompanyName,ShippingAddressFirstName,ShippingAddressLastName,ShippingAddressAdditional,ShippingAddressStreet,ShippingAddressNumber,ShippingAddressZIP,ShippingAddressCity,ShippingAddressState,ShippingAddressCountry,ShippingInstructions,UpdatedLatitude,UpdatedLongitude,UpdatedLocation")] ShippingAddresses model)
    {
        // define variables
        var userID                                                  = User.Identity.GetUserId();
        DateTime nowUTC                                             = DateTime.Now.ToUniversalTime();
        DateTime nowLocal                                           = DateTime.Now.ToLocalTime();
        // pass first name to viewbag for personalization
        ViewBag.Personalization                                     = UserManager.FindById(userID).FirstName.ToString();
        if (ModelState.IsValid)
        {
            if (model.IsDefaultShippingAddress)
            {
                var addresses = DATADB.ShippingAddressList
                    .Where(a => a.UserID                            == userID);
                var address = DATADB.ShippingAddressList
                    .Where(a => a.ID                                == model.ID);
                addresses.ForEach(a => a.IsDefaultShippingAddress   = false);
                address.ForEach(a => a.IsDefaultShippingAddress     = model.IsDefaultShippingAddress);
                address.ForEach(a => a.ShippingAddressCompanyName   = model.ShippingAddressCompanyName);
                address.ForEach(a => a.ShippingAddressFirstName     = model.ShippingAddressFirstName);
                address.ForEach(a => a.ShippingAddressLastName      = model.ShippingAddressLastName);
                address.ForEach(a => a.ShippingAddressAdditional    = model.ShippingAddressAdditional);
                address.ForEach(a => a.ShippingAddressStreet        = model.ShippingAddressStreet);
                address.ForEach(a => a.ShippingAddressNumber        = model.ShippingAddressNumber);
                address.ForEach(a => a.ShippingAddressZIP           = model.ShippingAddressZIP);
                address.ForEach(a => a.ShippingAddressCity          = model.ShippingAddressCity);
                address.ForEach(a => a.ShippingAddressState         = model.ShippingAddressState);
                address.ForEach(a => a.ShippingAddressCountry       = model.ShippingAddressCountry);
                address.ForEach(a => a.ShippingInstructions         = model.ShippingInstructions);
            }
            DATADB.SaveChanges();
            // track user activity: post method includes activity name and timestamp along with location
            var SUCCESS                                             = new UserActivities
            {
                UserID                                              = userID,
                ActivityName                                        = "EditShippingAddress_Success",
                ActivityTimeStampUTC                                = nowUTC,
                ActivityLatitude                                    = model.UpdatedLatitude,
                ActivityLongitude                                   = model.UpdatedLongitude,
                ActivityLocation                                    = model.UpdatedLongitude
            };
            DATADB.UserActivityList.Add(SUCCESS);
            DATADB.SaveChanges();
            return RedirectToAction("ShippingAddresses");
        }
        var FAILURE                                                 = new UserActivities
        {
            UserID                                                  = userID,
            ActivityName                                            = "EditShippingAddress_Failure",
            ActivityTimeStampUTC                                    = nowUTC,
            ActivityLatitude                                        = model.UpdatedLatitude,
            ActivityLongitude                                       = model.UpdatedLongitude,
            ActivityLocation                                        = model.UpdatedLongitude
        };
        DATADB.UserActivityList.Add(FAILURE);
        DATADB.SaveChanges();
        return View(model);
    }

Comments

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.