Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Gilles 25 posts 107 karma points
    Jul 17, 2020 @ 08:38
    Gilles
    0

    Save URL using IContentServer

    Hello,

    I'm working on a form which will allow a local businesses to register their contact data on our site.

    I'm using a SurfaceController and I'm saving the data using an IContentService. This works just fine for simple text properties. But I also allow them to inform their website. The document type has a URL Picker for the Website and it poses some problems.

    First here is the code:

    private void SaveRegisterBusinessRequestToUmbraco(RegisterBusinessViewModel business)
            {
    //do some other stuff
    var title = business.BusinessName + " (" + DateTime.Now.ToUniversalTime().ToString("yyyy-MM-dd HH:mm") + ")";
            var newNode = _contentService.Create(title, listRootNode.Id, BusinessContactCard.ModelTypeAlias);
            newNode.SetValue(BusinessContactCard.GetModelPropertyType(x => x.BusinessName).Alias, business.BusinessName);
            newNode.SetValue(BusinessContactCard.GetModelPropertyType(x => x.PhoneNumber).Alias, business.PhoneNumber);
            newNode.SetValue(BusinessContactCard.GetModelPropertyType(x => x.MobilePhoneNumber).Alias, business.MobilePhoneNumber);
            newNode.SetValue(BusinessContactCard.GetModelPropertyType(x => x.FaxNumber).Alias, business.Fax);
            newNode.SetValue(BusinessContactCard.GetModelPropertyType(x => x.Website).Alias, business.Website);
    
        if (_contentService.Save(newNode).Success)
        {
            //do some stuff
        }
    }
    

    I have an exception when business.Website is not empty on the _contentService.Save line:

    Unexpected character encountered while parsing value: w. Path '', line 0, position 0

    Here is the stack trace:

        [JsonReaderException: Unexpected character encountered while parsing value: w. Path '', line 0, position 0.]
       Newtonsoft.Json.JsonTextReader.ParseValue() in /_/Src/Newtonsoft.Json/JsonTextReader.cs:1706
       Newtonsoft.Json.JsonTextReader.Read() in /_/Src/Newtonsoft.Json/JsonTextReader.cs:419
       Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter) in /_/Src/Newtonsoft.Json/JsonReader.cs:1195
       Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) in /_/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs:196
       Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) in /_/Src/Newtonsoft.Json/JsonSerializer.cs:907
       Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings) in /_/Src/Newtonsoft.Json/JsonConvert.cs:828
       Newtonsoft.Json.JsonConvert.DeserializeObject(String value, JsonSerializerSettings settings) in /_/Src/Newtonsoft.Json/JsonConvert.cs:786
       Umbraco.Web.PropertyEditors.<GetReferences>d__7.MoveNext() in d:\a\1\s\src\Umbraco.Web\PropertyEditors\MultiUrlPickerValueEditor.cs:182
       Umbraco.Core.PropertyEditors.DataValueReferenceFactoryCollection.GetAllReferences(PropertyCollection properties, PropertyEditorCollection propertyEditors) in d:\a\1\s\src\Umbraco.Core\PropertyEditors\DataValueReferenceFactoryCollection.cs:33
       Umbraco.Core.Persistence.Repositories.Implement.ContentRepositoryBase`3.PersistRelations(TEntity entity) in d:\a\1\s\src\Umbraco.Core\Persistence\Repositories\Implement\ContentRepositoryBase.cs:829
       Umbraco.Core.Persistence.Repositories.Implement.DocumentRepository.PersistNewItem(IContent entity) in d:\a\1\s\src\Umbraco.Core\Persistence\Repositories\Implement\DocumentRepository.cs:503
       Umbraco.Core.Cache.DefaultRepositoryCachePolicy`2.Create(TEntity entity, Action`1 persistNew) in d:\a\1\s\src\Umbraco.Core\Cache\DefaultRepositoryCachePolicy.cs:96
       Umbraco.Core.Persistence.Repositories.Implement.RepositoryBase`2.Save(TEntity entity) in d:\a\1\s\src\Umbraco.Core\Persistence\Repositories\Implement\RepositoryBaseOfTIdTEntity.cs:138
       Umbraco.Core.Services.Implement.ContentService.Save(IContent content, Int32 userId, Boolean raiseEvents) in d:\a\1\s\src\Umbraco.Core\Services\Implement\ContentService.cs:791
       WeiswampachCms.Controllers.RegisterBusinessController.SaveRegisterBusinessRequestToUmbraco(RegisterBusinessViewModel business) in C:\Users\ragi\OneDrive\Development\WeiswampachCms-Umbraco8\WeiswampachCms-Umbraco8\Controllers\RegisterBusinessController.cs:94
       WeiswampachCms.Controllers.RegisterBusinessController.ContactFormSubmit(RegisterBusinessViewModel businessViewModel) in C:\Users\ragi\OneDrive\Development\WeiswampachCms-Umbraco8\WeiswampachCms-Umbraco8\Controllers\RegisterBusinessController.cs:59
       lambda_method(Closure , ControllerBase , Object[] ) +103
       System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +14
       System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +157
       System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
       System.Web.Mvc.Async.<>c.<BeginInvokeSynchronousActionMethod>b__9_0(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +22
       System.Web.Mvc.Async.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) +29
       System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
       System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32
       System.Web.Mvc.Async.<>c__DisplayClass11_0.<InvokeActionMethodFilterAsynchronouslyRecursive>b__0() +58
       System.Web.Mvc.Async.<>c__DisplayClass11_2.<InvokeActionMethodFilterAsynchronouslyRecursive>b__2() +228
       System.Web.Mvc.Async.<>c__DisplayClass11_2.<InvokeActionMethodFilterAsynchronouslyRecursive>b__2() +228
       System.Web.Mvc.Async.<>c__DisplayClass11_2.<InvokeActionMethodFilterAsynchronouslyRecursive>b__2() +228
       System.Web.Mvc.Async.<>c__DisplayClass11_2.<InvokeActionMethodFilterAsynchronouslyRecursive>b__2() +228
       System.Web.Mvc.Async.<>c__DisplayClass7_0.<BeginInvokeActionMethodWithFilters>b__1(IAsyncResult asyncResult) +10
       System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
       System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
       System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34
       System.Web.Mvc.Async.<>c__DisplayClass3_6.<BeginInvokeAction>b__4() +35
       System.Web.Mvc.Async.<>c__DisplayClass3_1.<BeginInvokeAction>b__1(IAsyncResult asyncResult) +100
       System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
       System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
       System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
       System.Web.Mvc.<>c.<BeginExecuteCore>b__152_1(IAsyncResult asyncResult, ExecuteCoreState innerState) +11
       System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
       System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
       System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +45
       System.Web.Mvc.<>c.<BeginExecute>b__151_2(IAsyncResult asyncResult, Controller controller) +13
       System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +22
       System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
       System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26
       System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
       System.Web.Mvc.<>c.<BeginProcessRequest>b__20_1(IAsyncResult asyncResult, ProcessRequestState innerState) +28
       System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29
       System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
       System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28
       System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
       System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +576
       System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +132
       System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +163
    

    I guess is it is because the value of an URL picker is saved in the DB in a JSON format, but what is the structure? Is there a simple way of doing this?

    Thanks

  • Steve Morgan 1345 posts 4452 karma points c-trib
    Jul 20, 2020 @ 11:26
    Steve Morgan
    100

    Hi,

    Here's a proof of concept that's loosely typed, can definitely be done better using the strongly typed models, but works.

    It's setting up JArray then the url picker object. I'm assuming you've used the Multi Url Picker??

    My test code just uses the homenode but hopefully you can see what I'm doing.

    Few things to note:

    1. Check the user enters a valid url? Append the protocol?
    2. You almost probably certainly shouldn't be storing web form entries to your content tree. You're opening up yourself to security issues or at the very least denial of service / spam issues. A custom table would be a much better solution here (probably) .

    But hope this is useful.

    var _contentService = Services.ContentService;
    
    
            var homeCsNode = _contentService.GetById(1106);
    
            // test getting the urlpicker content (useful to see what Umbraco set)
            var testJson = homeCsNode.GetValue<string>("urlPicker");
    
    
            var urlPickerNewValueList = new JArray();  // a list of url picker items
            var urlPickerNewValueObj = new JObject();  // the first (and only) item
    
    
            urlPickerNewValueObj.Add("name", "http://www.yahoo.co.uk");  // we add the name and url as the same value as that is what Umbraco seems to do
            urlPickerNewValueObj.Add("url", "http://www.yahoo.co.uk");  // you might need to check for the protocol and add it if omittted?
    
            urlPickerNewValueList.Add(urlPickerNewValueObj);
            // set the value in the Content Service
            homeCsNode.SetValue("urlPicker", JsonConvert.SerializeObject(urlPickerNewValueList));
            _contentService.SaveAndPublish(homeCsNode);
    
  • Gilles 25 posts 107 karma points
    Jul 22, 2020 @ 09:01
    Gilles
    0

    Hi Steve,

    Thanks for your answer. I actually figured it out myself shortly after posting. I did pretty much the same as you did. Just had to check in to Umbraco DB how Multi URL Picker Data is saved. After that it was a piece of cake :-)

    Regards

Please Sign in or register to post replies

Write your reply to:

Draft