contentService.SaveAndPublish 在Umbraco 8中无法通过编程方式创建新内容。

huangapple go评论58阅读模式
英文:

contentService.SaveAndPublish not creating new content programmatically - Umbraco 8

问题

希望有人能帮助我解决这个问题。

我正在将我们当前的 Umbraco 7 项目迁移到 Umbraco 8

我们有一个自定义的后台部分,用于上传 CSV 文件并根据 CSV 行创建新内容。代码似乎正常运行并创建/保存内容。但是当我检查时,它在后台或数据库中没有出现。

具有以下方法的控制器继承自 UmbracoAuthorizedApiController

public async Task<HttpResponseMessage> UploadFileToServer()
{
    if (!Request.Content.IsMimeMultipartContent())
    {
        throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
    }

    // 父级的 Id
    var vehicleList = Umbraco.Content(2873);

    var provider = new MultipartMemoryStreamProvider();
    await Request.Content.ReadAsMultipartAsync(provider);
    var file = provider.Contents.First();
    var filename = file.Headers.ContentDisposition.FileName.Trim('\"');
    _logger.Debug(this.GetType(), $"uploading file {filename}");

    var buffer = await file.ReadAsByteArrayAsync();
    var stream = new MemoryStream(buffer);
    string payload;
    using (var s = new StreamReader(stream))
    {
        var DataReader = new DataReader();
        var validateResult = DataReader.Validate(filename, s);

        if (validateResult.ImportedOK)
        {
            _logger.Debug(this.GetType(), $"file {filename} has no duplicates");
            IDataTypeService dts = Services.DataTypeService;
            var stocklistStatus = dts.GetAll().First(z => z.Name == "StocklistStatus");

            var dataType = dts.GetDataType(stocklistStatus.Id);
            ValueListConfiguration prevalues = 
                (ValueListConfiguration)dataType.Configuration;
            int pendingstatus = prevalues
                .Items
                .Where(x => x.Value == "Pending")
                .Select(i => i.Id)
                .FirstOrDefault();

            var service = Services.ContentService;

            using (var scope = _scopeProvider.CreateScope())
            {
                var db = scope.Database;

                foreach (var item in validateResult.ImportRows)
                {
                    var cleanedreg = Utility.CleanReg(item.Reg);
                    var cleanedConverterUsername = item.Converter.TrimStart('0');
                    var guid = new Guid("e597cb94-727d-44d2-987c-2d6d8e3b73c2");

                    var vehicle = service
                        .Create(cleanedreg, guid, "Vehicle", Security.GetUserId()
                        .Result);

                    var alreadyExists = ArchiveVehicleDataProvider
                        .CheckIfVehicleSoldExpiredBefore(db, cleanedreg, _logger);
                    vehicle
                        .SetValue(Vehicle
                        .GetModelPropertyType(x => x.Colour)
                        .Alias, item.Colour);
                    vehicle
                        .SetValue(Vehicle
                        .GetModelPropertyType(x => x.Converter)
                        .Alias, cleanedConverterUsername);
                    vehicle
                        .SetValue(Vehicle
                        .GetModelPropertyType(x => x.Doors)
                        .Alias, item.Doors);
                    vehicle
                        .SetValue(Vehicle
                        .GetModelPropertyType(x => x.ElectricBelt)
                        .Alias, item.ElectricBelt);
                    vehicle
                        .SetValue(Vehicle
                        .GetModelPropertyType(x => x.Fuel)
                        .Alias, item.Fuel);
                    vehicle
                        .SetValue(Vehicle
                        .GetModelPropertyType(x => x.Make)
                        .Alias, item.Make);
                    vehicle
                        .SetValue(Vehicle
                        .GetModelPropertyType(x => x.Mileage)
                        .Alias, item.Mileage);
                    vehicle
                        .SetValue(Vehicle.GetModelPropertyType(x => x.Model)
                        .Alias, item.Model);
                    vehicle.SetValue(Vehicle
                        .GetModelPropertyType(x => x.AdditionalInformation)
                        .Alias, item.Additional);
                    vehicle
                        .SetValue(Vehicle
                        .GetModelPropertyType(x => x.Price)
                        .Alias, item.Price);
                    vehicle
                        .SetValue(Vehicle
                        .GetModelPropertyType(x => x.Seats)
                        .Alias, item.Seats);
                    vehicle
                        .SetValue(Vehicle
                        .GetModelPropertyType(x => x.PublishedDate)
                        .Alias, DateTime.Now);

                    var result = service.SaveAndPublish(vehicle);
                }
            }
        }
        _logger.Debug(this.GetType(), $"file {filename} loaded into database");
        payload = JsonConvert.SerializeObject(validateResult);

    }
    HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);
    response.Content = new StringContent(payload);
    return response;
}

当我检查 App_Data 下的日志时,似乎表明这些项目已经发布。

没有错误,当我逐步执行代码时也没有明显的问题。有人有什么建议吗?

我刚刚注意到另一个奇怪的行为:

var result = service.SaveAndPublish(vehicle);

会为内容分配一个 ID。我让代码运行并“创建”内容,第一个结果的 ID48863。尽管我无法在数据库或 Umbraco 中看到它。

然后,我关闭并重新启动项目,并使用相同的 CSV 运行相同的代码。这次我获得了 ID48873。递增了上次上传的记录长度。因此,似乎某处保留了 ID 记录,尽管我找不到它。(这可能是关于原始问题的一个误导信息)

导入和整个项目是在与原始 v7 解决方案不相关的项目中构建的,因此不应该引用旧的 v7 数据库。

英文:

hoping some one here can help me out with this one.

I am migrating our current Umbraco 7 project to Umbraco 8.

We have a custom back office section that uploads a CSV and creates new content from the CSV rows. The code seems to run fine and creates/saves the content. However it does not appear in the back office or in the database when I check.

The controller which has the method below is inheriting from UmbracoAuthorizedApiController

public async Task&lt;HttpResponseMessage&gt; UploadFileToServer()
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
//Id for the parent
var vehicleList = Umbraco.Content(2873);
var provider = new MultipartMemoryStreamProvider();
await Request.Content.ReadAsMultipartAsync(provider);
var file = provider.Contents.First();
var filename = file.Headers.ContentDisposition.FileName.Trim(&#39;\&quot;&#39;);
_logger.Debug(this.GetType(), $&quot;uploading file {filename}&quot;);
var buffer = await file.ReadAsByteArrayAsync();
var stream = new MemoryStream(buffer);
string payload;
using (var s = new StreamReader(stream))
{
var DataReader = new DataReader();
var validateResult = DataReader.Validate(filename, s);
if (validateResult.ImportedOK)
{
_logger.Debug(this.GetType(), $&quot;file {filename} has no duplicates&quot;);
IDataTypeService dts = Services.DataTypeService;
var stocklistStatus = dts.GetAll().First(z =&gt; z.Name == &quot;StocklistStatus&quot;);
var dataType = dts.GetDataType(stocklistStatus.Id);
ValueListConfiguration prevalues = 
(ValueListConfiguration)dataType.Configuration;
int pendingstatus = prevalues
.Items
.Where(x =&gt; x.Value == &quot;Pending&quot;)
.Select(i =&gt; i.Id)
.FirstOrDefault();
var service = Services.ContentService;
using (var scope = _scopeProvider.CreateScope())
{
var db = scope.Database;
foreach (var item in validateResult.ImportRows)
{
var cleanedreg = Utility.CleanReg(item.Reg);
var cleanedConverterUsername = item.Converter.TrimStart(&#39;0&#39;);
var guid = new Guid(&quot;e597cb94-727d-44d2-987c-2d6d8e3b73c2&quot;);
var vehicle = service
.Create(cleanedreg, guid, &quot;Vehicle&quot;, Security.GetUserId()
.Result);
var alreadyExists = ArchiveVehicleDataProvider
.CheckIfVehicleSoldExpiredBefore(db, cleanedreg, _logger);
vehicle
.SetValue(Vehicle
.GetModelPropertyType(x =&gt; x.Colour)
.Alias, item.Colour);
vehicle
.SetValue(Vehicle
.GetModelPropertyType(x =&gt; x.Converter)
.Alias, cleanedConverterUsername);
vehicle
.SetValue(Vehicle
.GetModelPropertyType(x =&gt; x.Doors)
.Alias, item.Doors);
vehicle
.SetValue(Vehicle
.GetModelPropertyType(x =&gt; x.ElectricBelt)
.Alias, item.ElectricBelt);
vehicle
.SetValue(Vehicle
.GetModelPropertyType(x =&gt; x.Fuel)
.Alias, item.Fuel);
vehicle
.SetValue(Vehicle
.GetModelPropertyType(x =&gt; x.Make)
.Alias, item.Make);
vehicle
.SetValue(Vehicle
.GetModelPropertyType(x =&gt; x.Mileage)
.Alias, item.Mileage);
vehicle
.SetValue(Vehicle.GetModelPropertyType(x =&gt; x.Model)
.Alias, item.Model);
vehicle.SetValue(Vehicle
.GetModelPropertyType(x =&gt; x.AdditionalInformation)
.Alias, item.Additional);
vehicle
.SetValue(Vehicle
.GetModelPropertyType(x =&gt; x.Price)
.Alias, item.Price);
vehicle
.SetValue(Vehicle
.GetModelPropertyType(x =&gt; x.Seats)
.Alias, item.Seats);
vehicle
.SetValue(Vehicle
.GetModelPropertyType(x =&gt; x.PublishedDate)
.Alias, DateTime.Now);
var result = service.SaveAndPublish(vehicle);
}
}
}
_logger.Debug(this.GetType(), $&quot;file {filename} loaded into database&quot;);
payload = JsonConvert.SerializeObject(validateResult);
}
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(payload);
return response;
}

When I check the logs under App_Data it seems to suggest the items are being published.

{
&quot;@t&quot;:&quot;2023-03-30T12:39:46.2787407Z&quot;,
&quot;@mt&quot;:&quot;Document {ContentName} (id={ContentId}) has been published.&quot;,
&quot;ContentName&quot;:&quot;Vehicle123&quot;,
&quot;ContentId&quot;:0,
&quot;SourceContext&quot;:&quot;Umbraco.Core.Services.Implement.ContentService&quot;,
&quot;ProcessId&quot;:10848,&quot;ProcessName&quot;:&quot;iisexpress&quot;,
&quot;ThreadId&quot;:5,&quot;AppDomainId&quot;:2,
&quot;AppDomainAppId&quot;:&quot;LMW3SVC2ROOT&quot;,
&quot;MachineName&quot;:&quot;AT1149&quot;,
&quot;Log4NetLevel&quot;:&quot;INFO &quot;,
&quot;HttpRequestNumber&quot;:3,
&quot;HttpRequestId&quot;:&quot;f61e2d8f-71ac-48a9-87ce-e4ed98354c58&quot;
}

There are no errors and can't see any thing obvious when stepping through the code. Does anyone have any suggestions please?

Another strange behaviour I have just noticed with line

var result = service.SaveAndPublish(vehicle);

Will give the content an ID. I have let the code run and "create" the content and the first result had an ID of 48863. Although I am unable to see this in the DB or Umbraco.

I have then closed and restarted the project and run the same code using the same CSV. This time I was given an ID of 48873. Incremented by the exact record length of the last upload. So it appears that a record of the ID's is kept somewhere although I can't find. (This could be a red herring on the original issue however)

The import and entire project is being built in a separate project from the original v7 solution so there should be no references to the old v7 database.

答案1

得分: 1

我看来,你没有“提交”你的范围中所做的更改,这可能是你看到事物被创建的原因 - 它们很可能被回滚了。

所以,如果你在foreach后面添加类似 scope.Complete() 这样的东西,也许就可以解决问题?

链接

英文:

As far as I can see, you're not "committing" the changes made in your scope, which might be why you're seeing things being created - they are likely getting rolled back again.

So if you add something like scope.Complete() right after the foreach, it might do the trick?

https://our.umbraco.com/apidocs/v8/csharp/api/Umbraco.Core.Scoping.IScope.html#Umbraco_Core_Scoping_IScope_Events

huangapple
  • 本文由 发表于 2023年3月31日 18:52:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/75897698.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定