选择正确的实体代表

时间:2014-12-02 18:40:32

标签: c# asp.net-mvc

我有相册模型:

public class Album
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Artist { get; set; }
    public int? Year { get; set; }
    public string Image { get; set; }
    public virtual ICollection<Track> Tracklist { get; set; }
    public string Description { get; set; }
}

我想实现以下一种方式将新专辑添加到数据库中的功能:

  1. 在第一个视图中,用户应该看到带有字段的表单&#34;艺术家&#34;和&#34;专辑名称&#34;。
  2. 然后他将此字段发布到操作中,该字段应将album.getInfo请求发送到Lastfm API(http://www.lastfm.ru/api/show/album.getInfo)。
  3. 新专辑应该从响应构建并传递给用户。如有必要,他应该能够检查收到的信息的正确性并编辑任何字段。
  4. 然后他将整个专辑发布到动作,并将其保存到db。
  5. 您将如何实施此方案?特别是,最好将一个模型(Album)传递给每个动作,或者为每个动作创建模型(在这种情况下为两个)?关于操作和视图的相同问题:在一个操作和视图中执行有关创建和编辑相册的所有用户交互,或以某种方式将它们分开,会更好吗?

    我有几个解决方法,但他们看起来并不是很优雅,而且我觉得应该有更好的解决方案。

1 个答案:

答案 0 :(得分:1)

我会用AJAX处理这个场景。它不仅对用户更好(不需要往返),而且还使它只是标准的旧表单提交服务器端(换句话说,非常简单)。基本上,您只需要进行标准的GET和POST操作:

public ActionResult Create()
{
    var model = new Album();
    return View(model);
}

[HttpPost]
public ActionResult Create(Album model)
{
    if (ModelState.IsValid)
    {
        db.Albums.Add(model);
        db.SaveChanges()
        return RedirectToAction("Index");
    }

    return View(model);
}

然后,在您看来:

@model Namespace.To.Album


@using (Html.BeginForm())
{
    @Html.LabelFor(m => m.Artist)
    @Html.EditorFor(m => m.Artist)

    @Html.LabelFor(m => m.Name)
    @Html.EditorFor(m => m.Name)

    <div class="js-visible">
        <button type="button" id="LookupAlbum">Lookup</button>
    </div>

    <div id="AlbumFields" class="js-hidden">
        <!-- rest of the fields here -->
    </div>

    <button type="submit">Create</button>
}

js-visiblejs-hidden是我喜欢使用的便捷类。它们的实现非常简单,如果你使用像Modernizr这样的东西,它会更简单,因为如果支持和启用JavaScript,它会为js元素添加html类。

使用Modernizr

CSS

.js-visible {
    display:none;
}
.js js-visible {
    display:block;
}

.js .js-hidden {
    display:none;
}

没有Modernizr

CSS

.js-visible {
    display:none;
}

JS(实际上jQuery不是代码示例)

$('.js-visible').show();
$('.js-hidden').hide();

无论如何,这里的想法是,如果没有JavaScript功能或它已被禁用,则查找按钮不会显示,而是用户只会看到所有字段。但是,如果您可以使用JavaScript(并因此执行AJAX查找),则最初将隐藏剩余的专辑字段,并且在前两个字段之后将显示查找按钮。

然后,您只需要一些JavaScript来处理您的查找:

 $('#LookupAlbum').on('click', function () {
     var artist = $('#Artist').val();
     var album = $('#Name').val();

     $.get('/some/url', { artist: artist, album: album }, function (result) {
         // fill in the remaining fields with retrieved information
         $('#LookupAlbum').hide();
         $('#AlbumFields').show();
     });
 });

我故意试图将此代码保持为基本,因为AJAX调用所发生的很多事情取决于您正在做什么。如果他们的API支持JSONP,URL将直接连接到LastFM(在这种情况下,您的AJAX调用的主体将是不同的,并且您需要实现将由JSONP调用的回调函数,该函数将填充您的如果LastFM没有提供JSONP,或者您只是不想这样做,那么该URL将转到您创建的将调用LastFM API并返回它的操作。响应(基本上只是创建一个代理来绕过同源限制)。

长短,您可以异步从API获取信息并通过JavaScript填写字段。然后,隐藏查找按钮并显示剩余的相册字段。用户现在可以填写任何剩余内容或修改LastFM返回的内容并提交一次。