cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
Anonymous
Not applicable

Update Web Resource containing XML

Hi,

 

Within my model driven app (solution), I want to update an XML WebResource i.e. update the XML.

 

How can I do this using JavaScript and WebAPI.

 

Thanks

 

- Rory

19 REPLIES 19
DianaBirkelbach
Super User
Super User

Hi @Anonymous 

 

In case you must create a WebResource you would need 2 Steps:

1. Create record

Xrm.WebApi.createRecord("webresource", {content: window.btoa("<root/>"), displayname: "dummy", languagecode: 1031, name: "orb_dummy1.xml",  webresourcetype: 4})
.then(console.log)
.catch(console.error)
//returns {id: "GUID", entityType: "webresource"}

 2. Add Webresource to Solution

var req = {
  ComponentId : {guid: "GUID"},
  ComponentType: 61,
  SolutionUniqueName: "YOURSOLUTIONNAME",
  AddRequiredComponents: false,
  IncludedComponentSettingsValues: null
};
req.getMetadata = function () {
   return {
       boundParameter: null,
       operationName: "AddSolutionComponent",
       operationType: 0,
       parameterTypes: {
              ComponentId: {"typeName": "Edm.Guid", structuralProperty: 1},
              SolutionUniqueName: {"typeName": "Edm.String", structuralProperty: 1},
              ComponentType: { structuralProperty: 1}, 
              AddRequiredComponents: {structuralProperty:1}
           }    
        };
    };
 
Xrm.WebApi.online.execute(req).then(console.log).catch(console.error);

 

In case you have the WebResource and just need to update, you can use a normal update request. You need the id of the WebResource.

Xrm.WebApi.updateRecord("webresource", "GUID",  {content: window.btoa("<XML_CONTENT/>")}).then(console.log).catch(console.error)

 

If you don't have the id of the webresource, you need to retrieve it first

Xrm.WebApi.retrieveMultipleRecords("webresource", `?$select=webresourceid&$filter=name eq '${encodeURIComponent("orb_dummy1.xml")}'`).then(console.log)

 

After the create or update is done, you need to publish:

var req = {
    ParameterXml : "<importexportxml><webresources><webresource>${GUID}</webresource></webresources></importexportxml>"
};
req.getMetadata = function () {
    return {
       boundParameter: null,
       operationName: "PublishXml",
       operationType: 0,
       parameterTypes: {
              ParameterXml: {"typeName": "Edm.String", structuralProperty: 1}
           }    
        };
    };
 Xrm.WebApi.online.execute(req).then(console.log).catch(console.error);

You can publish more resources at once.

 

Best regards,

Diana

v-xida-msft
Community Support
Community Support

Hi @Anonymous ,

Do you want to update your web source using JavaScript instead of changing manually?

 

Based on the needs that you mentioned, I agree with @DianaBirkelbach 's thought almost. The Xrm.WebApi could achieve your needs:

Xrm.WebApi.updateRecord(entityLogicalName, id, data).then(successCallback, errorCallback);

Please check the following article:

https://docs.microsoft.com/en-us/powerapps/developer/model-driven-apps/clientapi/reference/xrm-webapi/updaterecord

 

Actually, when you uploading a file into the WebResources tab in your solution, it essentially would create a record for this uploaded file in webresource Entity (System Entity).

 

Best regards,

Community Support Team _ Kris Dai
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

@v-xida-msft 

When writing the webresource content, we need to pass the content in base64, that's why I've also provided how to set the "data" in the Xrm.WebApi.updateRecord.

As far as I know, the webResource must be also published, so I've included that too. Is that not needed in order to work with it afterwards?

 

The rest it's only about how to create or retrieve a webresource.

 

Best regards,

Diana

rajyraman
MVP

@Anonymous- What is the underlying intent in updating Webresource directly? Even though webresource is an entity can retrieved and updated just like any other entity records, it is a bit special as well as it can be packaged up into a solution, included in dependency tracking and needs to be published for the changes to come through.

 

Also in terms of ALM, your source control should be the source of truth, so by updating a webresource directly there might be mismatches between what is in source control and what is in the environment.

 

Is your use case some sort of configuration that you are storing, that is used in other areas?

Anonymous
Not applicable

Firstly - thank you everybody for your generous feedback.

 

Just to clarify, I am using the XML Web Resource as a settings file in my solution. The idea was for users to make setting updates (e.g. change visibility for a control on a form) using a html page and then save those settings changes back to the Web Resource XML file.

 

I can then apply those settings in my solution (based on the contents of the XML file)

@Anonymous- You are better off using a custom configuration entity and allow users to make changes to this custom config entity records, rather than using a webresource for this purpose. If this config is only needed just before the solution is exported, you don't need to package it up along with solution. Another advantage of this approach is the user's making change to the xml, doesn't need any other permission other than ability to edit/add xml to the custom config entity.

 

There is now a native file type, so you could use this along with File Field Manager in model-driven app. Generally, I use JSON/XML on a text field in a custom config/settings entity for these kind of configs.

 

Are you planning to move the WebResource file across into the target along with the solution? Is it needed in the target for something? If so, you can also use environment variables. It is preview though - so I would still stick with custom config entity and move this across as reference data, if you do need it in the target, as I would be very cautious in giving solution level permission for this, especially if they are non-technical.

Hi @rajyraman , 

There are a few reasons I prefer the WebResources for Solution Configurations:

 - Webresources are faster, because they are cached. That's not the case with an entity. Configurations are used often, so I consider the performance for the end-user, not necessarily for the customizer.

- usually we configure a solution and need that configuration in dev, test and prod. A webresource can be transported with the solution; for data we need another transport.

- Solution config is kind of customizing, so I don't need to setup more rights. Can be an advantage or a disadvantage.

- I don't like the system exploding with a lot of configuration entities 

 

But there are some cases where an entity is better. Maybe in the cases where this configuration has also some data related to it.

 

Interesting approach with the new file attribute for a configuration. I didn't thought about that yet. Thanks. I would still need to check if the file-attributes are slower than a string/textarea attribute. Have you checked that already?

 

I'm also looking forward to the new Environment Variables passing to GA. This will solve another problem that we have: having a default configuration defined with our generic solution, which can be changed for each customer. 

 

I think choosing a WebResource or an entity is a question where the answer starts with "It depends..

 

Best regards,

Diana

@DianaBirkelbach Xrm.WebApi calls are cached after first request for x hours or until the record is updated. Granted they aren't directly within the user's browser but time wise there is very really zero difference.

 

Because Environment settings currently don't have a global get function you end up having to write code which goes

 

 

attempt to retrieve custom value

if null is returned retrieve default value.

 

which to me has a double hit if you are looking at total performance time.

 

I suspect the 2 issues here are:-

 

1) will the configuration change during a period of time - if yes use an entity

2) will you need to reset the configuration in a hurry - if yes use an entity

 

Regarding point 2 years ago I a customer had let a licence for an ISV solution but needed it reset in a hurry. I took one look at their instructions and for ever more my focus has been on custom entities as the steps would be

1) delete appropriate license record

2) wait as on the next request the license was automatically refreshed. 

 

As for the system ending up with millions of entities, Microsoft are clear the read-only entities don't count towards any entity limita (and for most users they would be readonly) and have you seen the number of configuration entities in field service? In my case it's 1 entity per product at most.

---
If this post has answered your question please consider it for "Accept as Solution" or if it has been helpful give it a "Thumbs Up".

Thank you @ben-thompson

Very interesting ideas, but still have some questions. Sorry for that.

- Cached Queries: So you mean there is an "In Memory" cache, for every query requested? Has something to do with ETag and Optimistic Concurrency? Until now I thought this happens inside SQL. If you have a link for me to read more about this, I would  appreciate.

- Environment Variables: I think we can retrieve both values at once. We can define a fetch with "linked-entity", link-type="outer", and retrieve both values at once. As you say, the queries are cached. I would go even further, and implement a cache inside the SessionStorage. Since the EnvironmentVariables are transported with the solution, is the best I can get, I think.

 

I think, given the history, the field service is not the best reference for a solution design 🙂 

 

Thank you guys ( @ben-thompson  and @rajyraman ) for your input and great idea exchange.

 

Best regards,

Diana

Helpful resources

Announcements
PA User Group

Welcome to the User Group Public Preview

Check out new user group experience and if you are a leader please create your group

MBAS Attendee Badge

Claim Your Badge & Digital Swag!

Check out how to claim yours today!

secondImage

Are Your Ready?

Test your skills now with the Cloud Skill Challenge.

secondImage

Demo Extravaganza is Back!

We are excited to announce that Demo Extravaganza for 2021 has started!

Users online (85,552)