0

this is driving me mad because it seems like such a basic thing, and yet I cannot for the life of me google it out...

I have Two Models in the Portfolio Part of my MVC website

public class PortfolioEntry
{
    public int ID { get; set; }
    [Display(Name="Project Name")]
    public string Name { get; set; }
    [Display(Name="Created for")]
    public string Client { get; set; }
    public string Description { get; set; }
    [Display(Name ="Started at")]
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    public DateTime Start { get; set; }
    [Display(Name ="Ended by")]
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    public DateTime End { get; set; }
    [Display(Name ="Skills used")]
    public string Category { get; set; }
    [Display(Name ="GitHub Link")]
    public string GitHubLink { get; set; }
    [Display(Name ="Solution Screenshots")]
    public virtual ICollection<ScreenShot> ScreenShots { get; set; }
}

And the second one:

    public enum ScreenShotType
    {
        [Display(Name = "Use case Diagram")]
        UseCase,
        [Display(Name = "Behaviour Diagram")]
        Behavior,
        [Display(Name ="Class Diagram")]
        ClassStructure,
        [Display(Name ="Main View")]
        MainPage,
        [Display(Name = "Additional View")]
        SomthingCool
    }
    public class ScreenShot
    {
        public int ID { get; set; }
        public string Description { get; set; }
        [Display(Name="Screenshot Type")]
        public ScreenShotType Type { get; set; }
        public string ImageURL { get; set; }
        public int Sorting { get; set; }
        public int PortfolioEntryID { get; set; }
    }
}

Now what I want to do is create a subform that allows me to on the fly Upload a ScreenShot and create a new record in the database for it (you click browse..., select the photo, fill in the info for it and click "Upload"). Then return the "Main" form so I can either upload another one or just save the whole thing altogether.

How should I go about it? I Tried creating a new action in the controller:

    public async Task<ActionResult> UploadPhoto([Bind(Include = "ID,Name,Client,Description,Start,End,GitHubLink")] PortfolioEntry portfolioEntry, HttpPostedFileBase uploadedFile,  string description, int sorting)
    {

        if (uploadedFile!=null && uploadedFile.ContentLength>0 && uploadedFile.ContentType.Contains("image"))
        {

            string extension = Path.GetExtension(uploadedFile.FileName.ToString().ToLower());
            string fileName = "PorfolioImage" + String.Format("{0:D5}", db.Photos.Count()) + extension;
            var path = Path.Combine(Server.MapPath("~/Pictures/ScreenShots"), fileName);
            uploadedFile.SaveAs(path);
            var screenshotToAdd = new ScreenShot
            {
                Description = description,
                Sorting = sorting,
                PortfolioEntryID = portfolioEntry.ID,
                ImageURL = fileName                    
            };
            await db.SaveChangesAsync();
        }
        return(View(portfolioEntry));
    }

But: 1. It does not see the uploaded file 2. Even if it did see the file it does not seem to register the Entity from the Bind

I've seen one solution by: mkozicki but before I re-write the methods I'd like to know if it is the path I should take.

Adam

EDIT: As per the follow up adding the View:

@model KoscielniakInfo.Models.PortfolioEntry

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>


@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>PortfolioEntry</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Client, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Client, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Client, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Description, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Description, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Description, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Start, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Start, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Start, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.End, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.End, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.End, "", new { @class = "text-danger" })
            </div>
        </div>


        <div class="form-group">
            @Html.LabelFor(model => model.GitHubLink, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.GitHubLink, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.GitHubLink, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">

            <div class="col-md-offset-1 col-md-10">
                <table>
                    <tr>
                        @{
                            int cnt = 0;
                            foreach (var category in ViewBag.Categories)
                            {

                                if (cnt++ % 3 == 0)
                                {
                                    @Html.Raw("</tr><tr>")
                                }
                                @Html.Raw("<td>")
                                <input type="checkbox"
                                       name="selectedCategories"
                                       value="@category.Name"
                                       @(Html.Raw(category.Selected ? "checked=\"checked\"" : "")) />


                                    @category.Name
                                    @Html.Raw("</td>")

                            }

                            @Html.Raw("</tr>")
                        }
                </table>
            </div>
        </div>

        <div class="form-group">
            <div id="newCats" class="col-md-10 col-md-offset-1">
                <div id="newCat">
                    <h5>
                        New Category
                    </h5>
                    <input type="text" name="newCategories" /><br />
                </div>
            </div>
            <div class="col-md-10 col-md-offset-1">
                <input id="clone" type="button" value="More Categories" />
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>

 @*=================================This is the form Group for adding the photo ============================================*@
    <div class="form-group">
        <div class="row">
            <div class="col-md-offset-2 col-md-3">
                Description:
            </div>
            <div class="col-md-7">
                <input type="text" name="description" id="description" />
            </div>
        </div>
        <div class="row">
            <div class="col-md-offset-2 col-md-3">
                screenType:
            </div>
            <div class="col-md-7">
                <input type="text" name="screenType" />
            </div>
        </div>
        <div class="row">
            <div class="col-md-offset-2 col-md-3">
                Sorting:
            </div>
            <div class="col-md-7">
                <input type="number" name="sorting" id="sorting" />
            </div>
        </div>
        <div class="row">
            <div class="col-md-offset-2 col-md-3">
                Image:
            </div>
            <div class="col-md-7">
                <input type="file" name="uploadedFile" />
            </div>
            <input type="button" value="Create" onclick="location.href='@Url.Action("UploadPhoto", "PorfolioEntries")'" />
        </div>
    </div>
//=============================================Ends Here =========================================================================
                            }

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script>

        $('#clone').click(function () {
            $('#newCat').last().clone().appendTo('#newCats')
        })

    </script>
}
Community
  • 1
  • 1
Tackgnol
  • 483
  • 1
  • 9
  • 15
  • 1
    You need to show your view. But since `ScreenShot` has a relationship with `PortfolioEntry` the if your creating a new `PortfolioEntry`, you would not be able to save `ScreenShot` anyway (because its `PortfolioEntry` has not been created in the database yet) –  Feb 12 '17 at 21:35
  • Thanks for taking the interest in my question. I added the View its rather big so I separated the part that's troublesome with : ======= Sections ====== – Tackgnol Feb 12 '17 at 21:47
  • 1
    You only needed to show one or 2 properties of each model :). I suggest you refer [this answer](http://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple-times-data-to-controller/28081308#28081308), and for a more complete example using `BeginCollectionItem`, [this answer](http://stackoverflow.com/questions/40539321/a-partial-view-passing-a-collection-using-the-html-begincollectionitem-helper/40541892#40541892). (and use view models in your view, not data models) –  Feb 12 '17 at 21:52
  • Thanks these will do the trick! I will try to do some reading on my use of data models mistake (to be honest I am learning and my main source of knowledge was the [Microsoft Tutorial](https://learn.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/)) – Tackgnol Feb 12 '17 at 22:05
  • As a side note, your checkboxes are not going to work correctly and suggest you read [this answer](http://stackoverflow.com/questions/29542107/pass-list-of-checkboxes-into-view-and-pull-out-ienumerable/29554416#29554416) –  Feb 12 '17 at 22:13

0 Answers0