ASP.NET MVC 4, Code First, View to Create/Edit Obj

2019-06-04 02:52发布

问题:

I have the model (code first) & database (SQL Server) setup with many to many relationship & seeding fine:

A Place can have many tags (eg Restaurant, bar, cafe) - and tags can belong to many places.

Place
[ScaffoldColumn(false)]
public virtual int PlaceID { get; set; }

[Required(ErrorMessage = "Place Name is required")]
[StringLength(100)]
public virtual string Name { get; set; }

[Required]
public virtual string Address {get;set;}

public virtual string ImageLogo {get;set;}
public virtual string ImageBackground {get;set;}


Tag
public virtual int TagID { get; set; }

[Required]
public virtual string Name { get; set; }

[Required]
public virtual string NamePlural { get; set; }

public virtual ICollection<Place> Places { get; set; }

EF Migrations has generated a junction table with TagID & PlaceID and I can add Places with multiple tags fine in my Seed method. There are about 50 tags - all seeded.

What I would like to do is have a Create view form - that allows users to select from all the tags - maybe with check boxes (open to alternatives), some async textbox etc? Which are then saved with the model.

This data will be entered by an administrator - speed of entry is most important (doesn't have to be 100% idiot proof).

I also need to be able to edit the place - and have those tags show up appropriately to be removed or others added.

Also the best way to handle deletion of places - delete records in junction table first?

What is best practice in all of the above?

Thanks.

回答1:

I think the best and simplest way for you is that you have a view for creating Place and at the bottom of it put a fieldset to assign tags to it.

For the fieldset, you should mave two partial views: One for create and another for edit. The partial view for creating should be somthing like this:

@model myPrj.Models.PlaceTagInfo

@{ 
    var index = Guid.NewGuid().ToString(); 
    string ln = (string)ViewBag.ListName;
    string hn = ln + ".Index";
}

<tr>
    <td>        
        <input type="hidden" name="@hn" value="@index" />
        @Html.LabelFor(model => model.TagID)
    </td>
    <td>
        @Html.DropDownList(ln + "[" + index + "].TagID", 
            new SelectList(new myPrj.Models.DbContext().Tags, "ID", "TagName"))
    </td>        
    <td>
        <input type="button" onclick="$(this).parent().parent().remove();" 
            value="Remove" />
    </td>
</tr>

By calling this partial view in the create place view ajaxly, you can render some elements for each tag. Each line of elements contains a label, a DropDownList containing tags, and a remove button to simply remove the created elements.

In the create place view, you have a bare table which will contain those elements you create through the partial view:

<fieldset>
     <legend>Place Tags</legend>
     @Html.ValidationMessageFor(model => model.Tags)</label>
     <table id="tblTags"></table>                                        
     <input type="button" id="btnAddTag" value="Add new tag"/>
     <img id="imgSpinnerl" src="~/Images/indicator-blue.gif" style="display:none;" />
</fieldset>

and you have the following script to create a line of elements for each tag:

$(document).ready(function () {
    $("#btnAddTag").click(function () {
        $.ajax({
            url: "/Controller/GetPlaceTagRow/Tags",
            type: 'GET', dataType: 'json',
            success: function (data, textStatus, jqXHR) {
                $("#tblTags").append(jqXHR.responseText);
            },
            error: function (jqXHR, textStatus, errorThrown) {
                $("#tblTags").append(jqXHR.responseText);
            },
            beforeSend: function () { $("#imgSpinnerl").show(); },
            complete: function () { $("#imgSpinnerl").hide(); }
        });
    });
});

The action method GetPlaceTagRow is like the following:

public PartialViewResult GetPlaceTagRow(string id = "")
    {            
        ViewBag.ListName = id;
        return PartialView("_CoursePostPartial");
    }

and your done for the create... The whole solution for your question has many codes for views, partial views, controllers, ajax calls and model binding. I tried to just show you the way because I really can't to post all of them in this answer.

Hope that this answer be useful and lead the way for you.