MVC5 Azure BLOB-объектов и моделей

Здравствуйте! У меня есть функция для сохранения текста и изображений из форм в базу данных Azure SQL (текст) и в BLOB-объекты Azure для моих изображений. Кроме того, он размещается в облаке в Azure, и его сохранение и загрузка отлично работает. Запуск в обычном стеке C# EF MVC5 Bootstrap Vanilla js, веб-ролик BLOB-объектов Azure и т. Д.

Я застрял в области, которую не могу понять - отобразить мою модель представления (это модель представления с двумя объектами EF, т.е. двумя таблицами базы данных) вместе со списком BLOB-объектов (объект BLOB-объекта Azure). Из-за того, что они не являются технически одинаковыми типами контекста, это проблема, но как мы можем объединить их и вывести так:

Обратный просмотр (jobsVModel + Blobs);

Вот моя текущая работа: Модель:

namespace client.Models
{
    public class JoinUsersandJobsModel : DbContext
    {


        public tradesusers tradesusers { get; set; }
        public jobs jobs { get; set; }
        public uploadedfiles uploadedfiles { get; set; }
        //add a blob service to our model
        //public BlobProfileImageServices _blobServices = new BlobProfileImageServices();


    }

}

У меня есть мой контроллер:

private traderEntities db = new traderEntities();
BlobProfileImageServices _blobServices = new BlobProfileImageServices();
    public ActionResult Index(string usernameCookie)
        {


            var viewModel = from u in db.tradesusers
                            join j in db.jobs on u.id equals j.jobbyuserid
                            join pic in db.uploadedfiles on j.id equals pic.ImageId
                            where u.email.Equals(usernameCookie) 
                            select new JoinUsersandJobsModel { tradesusers = u, jobs = j, uploadedfiles = pic };

            //blob container
            List<ImageVM> images;

            CloudBlobContainer blobContainer = _blobServices.GetCloudBlobContainer();
            List<string> blobs = new List<string>();
            foreach (var blobItem in blobContainer.ListBlobs())
            {
                blobs.Add(blobItem.Uri.ToString());

            }

            images = blobs
               // convert an Azure blob record into an ImageVM:
               .Select(b => new ImageVM()
               {

               })
               .ToList();

            //return View(blobs);


            //return View(imageModel);

            //List<Object> allS = (from x in viewModel select (Object)x).ToList();
            //allS.AddRange((from x in blobs select (Object)x).ToList());

            return View(images);
            //return View(db.tradesusers.ToList());
        }

Как вы можете видеть выше, я хочу вернуть два объекта одновременно, один из которых называется "blob", а второй - "viewModel", но мы можем видеть, что это два разных типа объектов! 'Return View(viewModel.ToList());' один работает, как и "Return View(blob);".

Мой взгляд:

@model IEnumerable<traderclient.Models.JoinUsersandJobsModel>
<--!@model2 List<traderclient.Models.ImageVM>-->

@{
    ViewBag.Title = "Profile";
}

        <!DOCTYPE html>

        <html>
        <head>
            <meta name="viewport" content="width=device-width" />
            <title>system - Client's Profile</title>
        </head>
        <body>

            <br /><br /><br /><br /><br />
            <h1>Profile</h1>


                @foreach (var item in Model)
                {

                    <div>
                        <h5> Profile pic</h5>



                        <hr />


                        <dl class="dl-horizontal">
                            <dt>
                                Pic
                            </dt>

                            <dt>

                            </dt>

                            <dd>

                                <img src="@Url.Content(@item.uploadedfiles.ImagePath+@item.uploadedfiles.ImageName)" width="250" height="250" multiple />


                            </dd>

                        </dl>
                        <p>
                            @Html.ActionLink("Edit", "Edit", new { id = @item }) |
                            @Html.ActionLink("Back to List", "Index")
                        </p>
                    </div>          }



            <table>
                <tr>
                    <td>
                        <table class="table" style="width:200px;">
                            <tr>
                                <td style="width:50%"> Image </td>
                                <td style="width:25%"> Delete </td>
                            </tr>


                            <ul style="list-style-type:none; padding:0;">
                                @foreach (var item in model2)
                                {
                                    <tr>
                                        <td> <img src="@item." alt="image here is" width="100" height="100" /> </td>
                                        <td> <input type="button" id="@item." onclick="deleteImage('@item');" value="Delete" /></td>
                                    </tr>
                                }
                            </ul>
                        </table>
                    </td>
                    <td style="width:100px"></td>
                </tr>

            </table>

Снова выше в представлении, использующем только ОДНУ определение модели, работает так, т.е. IEnumerable для таблиц заданий или торговцев или если я ТОЛЬКО использую объект List для объекта изображения Blob, который тоже работает. Но, как и контроллер, я не могу объединить их. Как я уже упоминал, остальные данные (все данные, кроме большого двоичного объекта) хранятся в базе данных SQL Azure. В Azure Blobs живут только изображения.

Не забудьте мое определение для моих BLOB-объектов, которое также находится в корне этого проекта как отдельный класс:

2 ответа

Решение

Исправлено в конце / предоставлен обходной путь. Таким образом, ваш ответ немного помог, но не достаточно @Dai

Чтобы исправить это сделать: Модель:

// МОДЕЛИ SQL

// Имя файла: JoinUsersandJobsModel.cs

namespace client.Models
{
    public class JoinUsersandJobsModel : DbContext
    {


    public tradesusers tradesusers { get; set; }
    public jobs jobs { get; set; }
    public uploadedfiles uploadedfiles { get; set; }
    //Blob service does not need to be here


}

}

// FileModel - это дополнительная модель для обработки данных BLOB

// Имя файла: FileListModel.cs

namespace client.Models
{
public class FileListModel
{
public FileListModel(IEnumerable<IListBlobItem> list)
{
if (list != null)
{
Files = new List<FileInfo>();
foreach (var item in list)
{
FileInfo info = FileInfo.CreateFromIListBlobItem(item);
if (info != null)
{
Files.Add(info);
}
}
}
}
public List<FileInfo> Files { get; set; }
}
public class FileInfo
{
public string FileName { get; set; }
public string URL { get; set; }
public long Size { get; set; }

public static FileInfo CreateFromIListBlobItem(IListBlobItem item)
{
if (item is CloudBlockBlob)
{
var blob = (CloudBlockBlob)item;
return new FileInfo { FileName = blob.Name,
URL = blob.Uri.ToString(),
Size = blob.Properties.Length };
}
return null;
}
}
}

// Контроллер для Azure SQL

private traderEntities db = new traderEntities();
BlobProfileImageServices _blobServices = new BlobProfileImageServices();
    public ActionResult Index(string usernameCookie)
        {

            var viewModel = from u in db.tradesusers
                            join j in db.jobs on u.id equals j.jobbyuserid
                            where u.email.Equals(usernameCookie) 
                            select new JoinUsersandJobsModel { tradesusers = u, jobs = j, uploadedfiles = pic };

            return View(viewModel);

        }

// Контроллер для BLOB-объектов Azure

// Завершаем отбрасывание частичного и возвратного BLOB-объектов того же типа действия

// и модельных блобов (Blobs)

// Позже мы встраиваем частичное в клиент

 public ActionResult loadMyBlob()
    {
     CloudBlobContainer blobContainer = _blobServices.GetCloudBlobContainer();
                List<string> blobs = new List<string>();
                foreach (var blobItem in blobContainer.ListBlobs())
                {
                    blobs.Add(blobItem.Uri.ToString());

                }

    return PartialView("loadMyBlob", blobs);

    }

// Создаем нашу Частично Сильно Типированную и Проверяем нашу Модель для BLOB-объектов

@model yourApp.Models.FileListModel
@{
ViewBag.Title = "File List";
}
<h2>File List</h2>

<ul>
@foreach (var item in Model.Files)
{
<li>
<a href="@item.URL">@item.FileName</a> (@item.Size bytes)
</li>
}
</ul>
@Html.ActionLink("Upload Another File", "UploadFile")

// Наконец-то внедряем наше Частичное в представление действия - "Индекс" в нашем случае

// Код для встраивания можно разместить в любом месте вашего представления

// Действие будет выполнено по запросу и через блоб

<embed src='@Url.Action("loadMyBlob", "Profile")'>

Если кому-то нужна помощь в подобной настройке, пожалуйста, дайте мне знать.

Ссылка: ТАКЖЕ поддержу и спасибо Джону Килиберти, где я скопировал его идею из его книги для класса FileListModel и как отобразить ее в представлении.

Вы не должны использовать свои внутренние объекты (будь то Microsoft.WindowsAzure.Storage.* объекты) или ваши собственные объекты базы данных) как ViewModels - вы должны создать новые классы ViewModel для каждого компонента логического представления (представление, частичный, повторяющийся элемент и т. д.) и заполнить их внутри ваших действий контроллера данными из ваших внутренних объектов.

Например, если у вас есть представление, которое показывает список изображений, то это будет выглядеть так:

class ImagesController : Controller {

    public ActionResult Index() {

        List<ImageVM> images;
        if( useAzure ) {

            List<CloudStorageBlob> blobs = GetBlobs( ... );
            images = blobs
                // convert an Azure blob record into an ImageVM:
                .Select( b => new ImageVM()
                {
                    Url = b.BlobUrl
                } )
                .ToList();
        }
        else { // use local SQL

            List<MyImageEntity> dbImages = GetImagesFromDB( ... );
            images = dbImages
                // convert a database MyImageEntity into an ImageVM:
                .Select( i => new ImageVM()
                {
                    Url = i.ImageAddress
                } )
                .ToList();
        }

        return this.View( images );
    }
}

ViewModels:

public class ImageVM {
    public String Url { get; set; }
    public String TitleText { get; set; }
    public String Etc { get; set; }
}

Посмотреть:

@model List<ImageVM>

<ul>
@foreach(ImageVM image in this.Model) {
    <li><img src="@image.Url" title="@image.TitleText" /></li>
}
</ul>
Другие вопросы по тегам