0

I am building a very simple asp.net MVC file upload form. Currently I have a problem creating the new database object that stores info on said file.

The code for the action method looks as follows:

[Authorize(Roles = "Admin")]
    public ActionResult AddFile(Guid? id)
    {
        var org = organisationRepository.GetOrganisationByID(id.Value);
        Quote newFile = new Quote();
        newFile.Organisation = org;
        newFile.QuotedBy = User.Identity.Name;
        return View("AddFile", newFile);
    }

The problem is that the value of newFile.Organisation is lost when the form is posted back. I suppose EF does not provide a value for OrganisationID at this stage.

[Authorize(Roles = "Admin")]
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult AddFile(Quote quote)
    {
        //save the file to the FS - nice!
        if (ModelState.IsValid)
        {
            try
            {
                foreach (string inputTagName in Request.Files)
                {
                    HttpPostedFileBase file = Request.Files[inputTagName];
                    if (file.ContentLength > 0)
                    {
                        string filePath = Path.Combine(HttpContext.Server.MapPath("~/Content/TempOrgFiles/")
                        , Path.GetFileName(file.FileName));
                        file.SaveAs(filePath);
                        quote.QuoteURL = file.FileName;
                    }
                }
                surveyRepository.AddQuote(quote);
                surveyRepository.Save();
            }
            catch (Exception ex)
            {
                //add model state errors
                ViewData["error"] = ex.Message;
            }
        }

        return View("AddFile");
    }

If this were linq to sql I would simplt set the OrganisationID, but with it being EF that is not possible (at least with my setup)

Any ideas as the best way to handle these situations? (save for doin something crazy like setting a hidden form field to the organisaionid and setting it in the post method)

2 Answers 2

1

You can store OrganisationID in session

[Authorize(Roles = "Admin")]
public ActionResult AddFile(Guid? id)
{
Session["OrganisationID"] = id;
}

and then set EntityKey with something like:

quote.OrganisationReference.EntityKey = new EntityKey("ContainerName.OrganizationSet","ID",Session["OrganisationID"])

If You have organisation ID in URL, You can change post function to:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddFile(Quote quote,Guid? id)

and retrieve it automatically (with adequate routing).

You don't neet to get organisation from repository during get, just store ID.

6
  • grabbing the organisation id in the post seems to work - but has led to a nice new error - An entity object cannot be referenced by multiple instances of IEntityChangeTracker. Commented Oct 9, 2009 at 19:54
  • Is this code everything that You do in post? It happens when You try to connect objects from different contexts. Commented Oct 9, 2009 at 19:58
  • Yep - the related repository methods are as follows: public void AddQuote(Quote q) { db.AddToQuotes(q); } public void Save() { db.SaveChanges(); } I suppose that perhaps when I assign quote.Organisation to org, quote is being attached and tracked through that object context? Then, when I try to add to to the db through another context, things getting confused and an exception is thrown.... Commented Oct 9, 2009 at 20:05
  • How do You set organisation during post? Setting organisation during get is not important, because during post it is not restored. Quote object is built of post data. Commented Oct 9, 2009 at 20:17
  • during get I leave it as null. I have found that I can alter my AddQuote repository method to accept a quote and an organisation id. I can then get the organisation entity in the repository and set it there. not sure if that is good practise - doesnt feel like it. Thanks for your help btw! Commented Oct 9, 2009 at 20:27
0

The data is lost because it is stateless. Your quote object in the GET is not the same quote object as passed in the POST. It's only partially hydrated due to the native binding in MVC (by property names). You'll either need to setup a CustomModelBinder or requery for your Quote object in the controller.

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.